# iOS Implementation source: https://developer.mastercard.com/mastercard-checkout-solutions/tutorial/scof_passkey_mobile_integration/ios/index.md The mobile app must launch the **Authentication UI URL** using an iOS **SFSafariViewController** when the consumer initiates checkout within their iOS device. The following representation shows the consumer's passkey authentication during checkout on merchant's mobile app in their iOS device. ![SFSafari_View_Controller session](https://static.developer.mastercard.com/content/mastercard-checkout-solutions/documentation/images/iOS3.jpg "SFSafariViewController session") *Face ID® and the Apple-owned graphic symbols depicted in the UX screen are trademarks of Apple Inc.* *SFSafariViewController does not share cookies across apps or with the Safari browser on the device.As a result, consumers currently need to create a new Mastercard Passkey in each participating mobile application.A solution to eliminate the need for recreating the passkey is planned for a future release.* Follow the sequence outlined in [Create Passkey](https://developer.mastercard.com/mastercard-checkout-solutions/documentation/token-authentication/secure-card-on-file/by-mastercard/authentication-with-passkey/create-passkey/index.md) on the Mastercard Checkout Solutions documentation. After receiving the **Authentication URL** from Mastercard Checkout Solutions, ensure that your mobile app launches this URL within an iOS **SFSafariViewController**. Mastercard recommends that customers refer to the official iOS documentation for guidance on implementing SFSafariViewController launches, as well as configuring callbacks and handling closure. ![SFSafariViewController Mermaid Diagram](https://static.developer.mastercard.com/content/mastercard-checkout-solutions/documentation/images/mermaid_iOS.png "SFSafariViewController session Mermaid") ## Step 1: Configure Universal Link {#step-1-configure-universal-link} Although you can use custom URL schemes, Apple strongly recommends using **Universal Links** because they provide stronger security. For more information, see the Apple guide [Defining a custom URL scheme for your app](https://developer.apple.com/documentation/xcode/defining-a-custom-url-scheme-for-your-app). To configure Universal Links: 1. **Create a domain association** by following the steps in the Apple documentation. This involves uploading a file to the root of your domain, which Apple uses to verify the link between your app and the website. 2. **Complete the Universal Links setup** by following the Apple guide, [Supporting associated domains](https://developer.apple.com/documentation/xcode/supporting-associated-domains) for modifying your app code to support Universal Links, including where and how to implement the necessary changes. ## Step 2: Create and Launch SFSafariViewController {#step-2-create-and-launch-sfsafariviewcontroller} A **SafariViewController** is a `UIViewController` that loads web pages in a sandboxed environment and allows for customizable presentation. For more details, refer to the Apple reference for [ASFSafariViewController](https://developer.apple.com/documentation/safariservices/sfsafariviewcontroller). Below is a basic code snippet to create and present a Safari View Controller: * Swift ```Swift func openSafariViewController(url: URL) { // Create a Safari View Controller with the provided URL let safariVC = SFSafariViewController(url: url) // Set the delegate if you need to detect when the view controller is closed safariVC.delegate = self // Present the Safari View Controller self.present(safariVC, animated: true) } ``` ## Step 3: Redirection to App / Callback {#step-3-redirection-to-app--callback} To return from a webpage loaded in a **Safari View Controller** , a special navigation called a **Universal Link** (configured in Step 1) is required. This allows the URL to be passed back to the native application via the `AppDelegate`. The `AppDelegate` code was already configured in Step 1 to handle the Universal Link. It should resemble the following snippet: * Swift ```Swift func application( _ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([any UIUserActivityRestoring]?) -> Void ) -> Bool { guard userActivity.activityType == NSUserActivityTypeBrowsingWeb, let incomingURL = userActivity.webpageURL else { return false } MCAuthentication.shared().responseFromSafariVC(incomingURL) return true } ``` The response URL is now sent and validated, allowing the flow to proceed. * Swift ```Swift @objc func responseFromSafariVC(_ incomingUrl: URL) { guard incomingUrl.absoluteString.starts(with: "[MyCallbackUrl]") else { // Not our callback return } self.dismiss(animated: true) // TODO: Validate & sanitize incomingUrl // TODO: Process incomingUrl and continue the flow } ``` ## Step 4: {#step-4} A **Safari View Controller** can be closed by the user at any point during the process. In such cases, you need to determine how to proceed, as the transaction or workflow on the webpage may have completed. To detect when the user closes the Safari View Controller, implement the appropriate **delegate protocol**. * Swift ```Swift extension MCAuthentication: SFSafariViewControllerDelegate { func safariViewControllerDidFinish(_ controller: SFSafariViewController) { // TODO: Clean up and verify the process status } } ```