> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/GetMetaMap/metamap-ios-sdk/llms.txt
> Use this file to discover all available pages before exploring further.

# SwiftUI Integration

> Complete guide to integrating MetaMap SDK with SwiftUI using MetaMapDelegateObserver

## Overview

This guide shows you how to integrate the MetaMap SDK into your SwiftUI-based iOS application using the `MetaMapDelegateObserver` wrapper pattern.

## Prerequisites

* MetaMap SDK installed via CocoaPods
* iOS 13.0 or later
* Swift 5.7 or later
* SwiftUI framework

## Implementation

### Complete SwiftUI Example

Here's a complete implementation using the `MetaMapDelegateObserver` pattern:

```swift theme={null}
import SwiftUI
import MetaMapSDK
import UIKit

struct ContentView: View {
    var body: some View {
        VStack {
            ZStack {
//MARK: MetaMapDelegateObserver
                MetaMapDelegateObserver { identityId, verificationId in
                    print("\(identityId), \(verificationId)")
                } cancelled: {
                    print("cancelled")
                }
                HStack {
                    Button(action: {
                        MetaMap.shared.showMetaMapFlow(clientId: "YOUR_CLIENT_ID", flowId: "YOUR_FLOW_ID", metadata: ["key1": "value1", "key2": 123])
                    }) {
                        Text("press me")
                    }
                }
            }
        }
    }
}

struct MetaMapDelegateObserver: UIViewControllerRepresentable {
    let vc = MatiViewController()
    public func makeUIViewController(context: Context) -> MatiViewController {
        return vc
    }
    
    public func updateUIViewController(_ uiViewController: MatiViewController, context: Context) {}
    
    var success: (_ identityId: String?, _ verificationId: String?) -> Void
    var cancelled: () -> Void
    
    public func makeCoordinator() -> Coordinator {
        Coordinator(success: success, cancelled: cancelled)
    }
    
    public  class Coordinator: NSObject, MetaMapButtonResultDelegate {
        public  func verificationSuccess(identityId: String?, verificationID: String?) {
            success(identityId, verificationID)
        }
        
        public  func verificationCancelled() {
            cancelled()
        }
        
        var success: (_ identityId: String?, _ verificationId: String?) -> Void
        var cancelled: () -> Void
        
        init(success: @escaping (_ identityId: String?, _ verificationId: String?) -> Void, cancelled: @escaping () -> Void) {
            self.success = success
            self.cancelled = cancelled
            super.init()
            MetaMapButtonResult.shared.delegate = self
        }
    }
}

class MetaMapViewController: UIViewController {}
```

## Understanding MetaMapDelegateObserver

The `MetaMapDelegateObserver` is a custom `UIViewControllerRepresentable` wrapper that bridges UIKit's delegate pattern with SwiftUI's declarative approach.

### Key Components

#### 1. UIViewControllerRepresentable Implementation

The observer conforms to `UIViewControllerRepresentable` to integrate with SwiftUI:

```swift theme={null}
struct MetaMapDelegateObserver: UIViewControllerRepresentable {
    let vc = MatiViewController()
    
    public func makeUIViewController(context: Context) -> MatiViewController {
        return vc
    }
    
    public func updateUIViewController(_ uiViewController: MatiViewController, context: Context) {}
}
```

#### 2. Closure-Based Callbacks

Instead of implementing delegate methods, use closures for handling results:

```swift theme={null}
var success: (_ identityId: String?, _ verificationId: String?) -> Void
var cancelled: () -> Void
```

#### 3. Coordinator Pattern

The Coordinator bridges delegate callbacks to SwiftUI closures:

```swift theme={null}
public class Coordinator: NSObject, MetaMapButtonResultDelegate {
    public func verificationSuccess(identityId: String?, verificationID: String?) {
        success(identityId, verificationID)
    }
    
    public func verificationCancelled() {
        cancelled()
    }
    
    var success: (_ identityId: String?, _ verificationId: String?) -> Void
    var cancelled: () -> Void
    
    init(success: @escaping (_ identityId: String?, _ verificationId: String?) -> Void, 
         cancelled: @escaping () -> Void) {
        self.success = success
        self.cancelled = cancelled
        super.init()
        MetaMapButtonResult.shared.delegate = self
    }
}
```

## Using MetaMapDelegateObserver

### Basic Usage

Add the `MetaMapDelegateObserver` to your view hierarchy using a `ZStack`:

```swift theme={null}
struct ContentView: View {
    var body: some View {
        VStack {
            ZStack {
                MetaMapDelegateObserver { identityId, verificationId in
                    // Handle success
                    print("Success: \(identityId ?? "N/A")")
                } cancelled: {
                    // Handle cancellation
                    print("Cancelled")
                }
                
                Button("Start Verification") {
                    MetaMap.shared.showMetaMapFlow(
                        clientId: "YOUR_CLIENT_ID",
                        flowId: "YOUR_FLOW_ID",
                        metadata: ["key1": "value1"]
                    )
                }
            }
        }
    }
}
```

### Handling Results

The observer provides two closure parameters:

#### Success Closure

```swift theme={null}
MetaMapDelegateObserver { identityId, verificationId in
    // Called when verification succeeds
    if let identityId = identityId {
        print("Identity ID: \(identityId)")
    }
    if let verificationId = verificationId {
        print("Verification ID: \(verificationId)")
    }
} cancelled: {
    // ...
}
```

#### Cancelled Closure

```swift theme={null}
MetaMapDelegateObserver { identityId, verificationId in
    // ...
} cancelled: {
    // Called when user cancels verification
    print("User cancelled the verification")
}
```

## Launching Verification Flow

Call `showMetaMapFlow` from any button or action in your SwiftUI view:

```swift theme={null}
Button(action: {
    MetaMap.shared.showMetaMapFlow(
        clientId: "YOUR_CLIENT_ID",
        flowId: "YOUR_FLOW_ID",
        metadata: ["key1": "value1", "key2": 123]
    )
}) {
    Text("Start Verification")
        .padding()
        .background(Color.blue)
        .foregroundColor(.white)
        .cornerRadius(8)
}
```

## Parameters

### showMetaMapFlow Parameters

| Parameter  | Type       | Required | Description                                   |
| ---------- | ---------- | -------- | --------------------------------------------- |
| `clientId` | String     | Yes      | Your MetaMap client ID                        |
| `flowId`   | String     | Yes      | The verification flow ID                      |
| `metadata` | Dictionary | No       | Additional metadata and customization options |

## Best Practices

1. **Single Observer Instance**: Place the `MetaMapDelegateObserver` once in your view hierarchy, typically at the top level
2. **ZStack Layout**: Use a `ZStack` to ensure the observer doesn't affect your UI layout
3. **State Management**: Store verification results in `@State` or `@StateObject` for reactive UI updates
4. **Error Handling**: Always implement both success and cancelled closures

## Example with State Management

```swift theme={null}
struct ContentView: View {
    @State private var identityId: String?
    @State private var showingResult = false
    
    var body: some View {
        VStack {
            ZStack {
                MetaMapDelegateObserver { identityId, verificationId in
                    self.identityId = identityId
                    self.showingResult = true
                } cancelled: {
                    print("Verification cancelled")
                }
                
                Button("Start Verification") {
                    MetaMap.shared.showMetaMapFlow(
                        clientId: "YOUR_CLIENT_ID",
                        flowId: "YOUR_FLOW_ID",
                        metadata: [:]
                    )
                }
            }
        }
        .alert("Verification Complete", isPresented: $showingResult) {
            Button("OK") { }
        } message: {
            Text("Identity ID: \(identityId ?? "Unknown")")
        }
    }
}
```

## Next Steps

* Learn about [UI Customization](/ui/customization) options
* Explore [UIKit Integration](/ui/uikit-integration)
* See [Objective-C Integration](/ui/objective-c-integration)
