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.
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:
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 {}
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:
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:
var success: (_ identityId: String?, _ verificationId: String?) -> Void
var cancelled: () -> Void
3. Coordinator Pattern
The Coordinator bridges delegate callbacks to SwiftUI closures:
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
}
}
Basic Usage
Add the MetaMapDelegateObserver to your view hierarchy using a ZStack:
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
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
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:
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
| 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
- Single Observer Instance: Place the
MetaMapDelegateObserver once in your view hierarchy, typically at the top level
- ZStack Layout: Use a
ZStack to ensure the observer doesn’t affect your UI layout
- State Management: Store verification results in
@State or @StateObject for reactive UI updates
- Error Handling: Always implement both success and cancelled closures
Example with State Management
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