# Using Webviews with the Web SDK on iOS
source: https://developer.mastercard.com/open-finance-us/documentation/connect/integrating/sdk/webviews/ios-webviews/index.md

This page outlines steps to load your WebApp via the Data Connect WebSDK in your iOS Mobile App inside a WebView. It also explains how to seamlessly transition control to your mobile app using a Safari View Controller for the FI's OAuth Login (if the FI banking app is not installed on the user's device), or redirecting to the FI app (if the FI app is present on the user's device).

This documentation also includes Universal Link and deep link configuration, as well as details on customizing the WebViewClient and secure container (SFSafariViewController) for enhanced control and handling of web interactions.

These are the steps which occur when launching:

1. Launch your web app (integrated with the Data Connect WebSDK) URL address in a secure web container inside your mobile app.

2. Select an option or link which will open the Data Connect experience in a WebView (this option should have the `redirectUrl` code integrated already).

3. After successful FI OAuth account addition, control returns to your app.

Tip: See also the [Secure Web Containers on iOS](https://developer.mastercard.com/open-finance-us/documentation/connect/integrating/sdk/ios/websdk-ios/index.md) page for more information on loading your URL inside a secure container (SFSafariViewController) and closing the secure container when complete.

Secure containers are mandatory in some situations (for example, Chase does not allow their consent URL to be launched from within insecure webviews).

The following scenarios need to be handled:

* Scenario 1: FI's app is installed - the FI's app will launch and the OAuth session will occur in the FI's app.

* Scenario 2: FI's app is not installed - the FI OAuth login page will open in an SFSafariViewController.

Note: In order to support App to App authentication make sure you pass a suitable `redirectUrl` parameter via the Data Connect Web SDK. See [Data Connect Web SDK App to App support](https://developer.mastercard.com/open-finance-us/documentation/connect/integrating/sdk/web-sdk/sdk/index.md#app-to-app-support).

## iOS project setup {#ios-project-setup}

Make sure you have set up the following in your XCode project:

* Under your Project target, select the **Signing and Capabilities** section:

  * Under this section click on **+Capability** to add a new capability, and select **Associated Domains** . Add your domain here. Under the **Signing** section, make sure you have set the development team correctly (or leave the team value as **None**).

  * This will create entitlement file `YourProject.entitlements`:

```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>com.apple.developer.associated-domains</key>
  <array>
    <string>applinks:*.example.com</string>
  </array>
</dict>
</plist>
```

For further details on app to app setup see [here](https://developer.mastercard.com/open-finance-us/documentation/connect/integrating/sdk/ios/ios-sdk/index.md#app-to-app-support).

## WebView Initialization {#webview-initialization}

In your view controller, create a `WKWebView` (named `webView `in the following example) to load your domain URL integrated with WebSDK in it.

Then, add setup steps for the `WKWebView` in the `viewDidAppear` function within which `WKPreferences`, `WKWebViewConfiguration` and delegates (`uiDelegate` and `navigationDelegate`) are added to the view controller.

```swift
import UIKit
import WebKit
import SafariServices
import Foundation

class ViewController: UIViewController, SFSafariViewControllerDelegate {
  var webView: WKWebView!

override func viewDidAppear(_ animated: Bool) {
  setupWebView()
  loadUrlInWebView()
}

// Add this function if not added already in basic XCode project installation steps.
func setupWebView() {
  let preferences = WKPreferences()
  preferences.javaScriptCanOpenWindowsAutomatically = true

  let configuration = WKWebViewConfiguration()
  configuration.preferences = preferences

  webView = WKWebView(frame: view.bounds, configuration: configuration)
  webView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
  webView.uiDelegate = self
  webView.navigationDelegate = self

  view.addSubview(webView)
}
```

## Loading your Web URL inside the WebView {#loading-your-web-url-inside-the-webview}

Call the `loadUrlInWebView()` function to load your domain URL in the webView.

```swift
func loadUrlInWebView(){
  if let url = URL(string: "https://example.com") {
    // Load domain URL where connect web sdk is already embeded
    let urlRequest = URLRequest(url: url)
    webView.load(urlRequest)
  }

}
```

## Handling OAuth Login URL and App to App {#handling-oauth-login-url-and-app-to-app}

Add WKUIDelegate extension and mentioned code in it which listens FI OAuth Event in Data Connect and open Secure Container or FI App.

Add SafariVIewController delegate to listen to manual closing of secure container.

```swift
func closeChildWebViewOrPopUp(){
  if(self.presentedViewController != nil){
    self.dismiss(animated: true)
  }
}

}

extension WKWebContainerViewController: SFSafariViewControllerDelegate {
  public func safariViewControllerDidFinish(_ controller: SFSafariViewController) {
    controller.dismiss(animated: true, completion: nil)
    self.closeChildWebViewOrPopUp()
  }
}

extension ViewController: WKUIDelegate {
func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
  var popupWebView = WKWebView(frame: view.bounds, configuration: configuration)
  popupWebView!.autoresizingMask = [.flexibleWidth, .flexibleHeight]
  popupWebView!.navigationDelegate = self
  popupWebView!.uiDelegate = self
  popupWebView?.isHidden = true

  if let url = navigationAction.request.url {
    OpenUniversalLink.inAnyNativeWay(url: url) { success in
      // Creation of OpenUniversalLink class is in Step no. 3
      if !success {
        let sfSafariViewController:SFSafariViewController = SFSafariViewController(url:url)
        sfSafariViewController.delegate = self
        self.present(sfSafariViewController, animated: true, completion: nil)
      }
    }         
  }
  return popupWebView!
}
```

Add the following code in SceneDelegate class for control to close already opened secure container.

```swift
// Scene delegate functions to Close Secure Container / Webview Pop Up

class SceneDelegate: UIResponder, UIWindowSceneDelegate {

  func scene(_ scene: UIScene, continue userActivity: NSUserActivity){
    self.closeSecureContainerPopUp(url: userActivity.webpageURL)
  }

  func closeSecureContainerPopUp(url:URL?) {
    var viewController:ViewController = ViewController()

    if ((self.window?.rootViewController?.children.count)! > 0) {
      viewController = self.window?.rootViewController?.children.last as! ViewController
    }
    else if (self.window?.rootViewController is ViewController) {
      viewController = self.window?.rootViewController as! ViewController
    }

    DispatchQueue.main.asyncAfter(deadline: .now() + 0.005) {
      viewController.closeChildWebViewOrPopUp()
    }
  }
}
```

Create a new OpenUniversalLink class using the following code. This will open the FI app using the universal link if the app is present on the device.

```swift
// Sample Open link class
import Foundation
import UIKit
import SafariServices
public class OpenUniversalLink {
  typealias completionHandler = (_ success:Bool) -> Void
  static func inAnyNativeWay(url: URL, dontPreferEmbeddedBrowser: Bool = false,completion: @escaping completionHandler) { // OPEN AS UNIVERSAL LINK IF EXISTS else : EMBEDDED or EXTERNAL
    if #available(iOS 10.0, *) {
      // Try to open with owner universal link app
      UIApplication.shared.open(url, options: [UIApplication.OpenExternalURLOptionsKey.universalLinksOnly : true]) { (success) in
        if !success {
          completion(false)
        }
      }
    } else {
      completion(false)
    }
  }
}
```

