*** title: iOS slug: integration/mobile/native-ios subtitle: Seamless Transak integration for iOS applications ----------------------------------------------------------- The Transak iOS integration allows you to embed a fully functional interface directly into your native iOS application using Webview. Update your `Info.plist` to include camera permission (required for KYC verification): ```xml NSCameraUsageDescription Permission required for Camera Access. ``` Configure your View Controller to load the Transak widget URL using your preferred implementation: ```swift title="SwiftUI" import SwiftUI import WebKit struct WebView: UIViewRepresentable { let url: URL func makeUIView(context: Context) -> WKWebView { let webview = WKWebView() return webview } func updateUIView(_ uiView: WKWebView, context: Context) { let request = URLRequest(url: url) uiView.load(request) } } struct ContentView: View { var body: some View { WebView(url: URL(string: "https://global-stg.transak.com?apiKey=&sessionId=")!) .edgesIgnoringSafeArea(.all) .padding(10) } } ``` ```swift title="UIKit" import UIKit import WebKit class WebViewController: UIViewController, WKUIDelegate, WKNavigationDelegate { @IBOutlet weak var webView: WKWebView! override func loadView() { let webConfiguration = WKWebViewConfiguration() webView = WKWebView(frame: .zero, configuration: webConfiguration) webView.uiDelegate = self webView.navigationDelegate = self view = webView } override func viewDidLoad() { super.viewDidLoad() let myURL = URL(string: "https://global-stg.transak.com?apiKey=&sessionId=") let myRequest = URLRequest(url: myURL!) webView.load(myRequest) } func webView(_ webView: WKWebView, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) { if let serverTrust = challenge.protectionSpace.serverTrust { completionHandler(.useCredential, URLCredential(trust: serverTrust)) } } } ``` Call the [Create Widget URL](/api/public/create-widget-url) to generate a Widget URL by securely passing the [widget parameters](/customization/query-parameters). The response returns a `widgetUrl` that should be used to load Transak in iOS Webview.
A `widgetUrl` is valid for 5 minutes and can only be used once. A new `widgetUrl` must be generated for every user flow.
**Example Request:** ```bash curl --request POST \ --url https://api-gateway-stg.transak.com/api/v2/auth/session \ --header 'access-token: YOUR_ACCESS_TOKEN' \ --header 'content-type: application/json' \ --data '{ "widgetParams": { "apiKey": "YOUR_API_KEY", "referrerDomain": "yourdomain.com" } }' ```
## Use cases Use the table below to choose the right approach for redirects, order data, and WebView events.
Feature Approach
How to redirect users back to your app after a transaction [Deeplink](#deeplinking)
How to get order data (e.g. status, order ID, amount) [Deeplink](#deeplinking), [Events](#events)
Listen to WebView events (order created, widget close, etc.) [Events](#events)
### Deeplink Transak supports deeplinking through the use of the `redirectURL` query parameter to enable seamless navigation after the purchase/sell process is completed. Add the URL scheme to your `Info.plist` to handle the deeplink ```xml CFBundleURLTypes CFBundleURLSchemes myapp ``` Listen for the deeplink and parse the returned parameters in your App When Transak redirects back, it includes additional query parameters appended to deeplink URL mentioned [here](/customization/query-parameters#redirecturl-1). ```swift @main struct SampleApp: App { @State private var deepLinkPath: URL? var body: some Scene { WindowGroup { ContentView() NavigationView { if let deepLinkPath = deepLinkPath { // handle deeplink query parameters } else { ContentView() } } .onOpenURL { url in if url.scheme == "myapp" { deepLinkPath = url } } } } } ``` Call the [Create Widget URL](/api/public/create-widget-url) to generate a Widget URL by securely passing the [widget parameters](/customization/query-parameters) along with the `redirectURL` parameter. The response returns a `widgetUrl` that should be used to load Transak in iOS Webview.
A `widgetUrl` is valid for 5 minutes and can only be used once. A new `widgetUrl` must be generated for every user flow.
**Example Request:** ```bash curl --request POST \ --url https://api-gateway-stg.transak.com/api/v2/auth/session \ --header 'access-token: YOUR_ACCESS_TOKEN' \ --header 'content-type: application/json' \ --data '{ "widgetParams": { "apiKey": "YOUR_API_KEY", "referrerDomain": "yourdomain.com", "redirectURL": "myapp://transak-redirect" } }' ```
### Events Transak allows listening of in-widget events (like order creation, completion, and widget close) through native event handlers in iOS WebViews. Add a script message handler to your WebView using the handler name IosWebview to listen for all frontend events. ```swift struct WebView: UIViewRepresentable { let url: URL func makeCoordinator() -> WebViewCoordinator { return WebViewCoordinator(self) } func makeUIView(context: Context) -> WKWebView { let contentController = WKUserContentController() contentController.add(context.coordinator, name: "IosWebview") let config = WKWebViewConfiguration() config.userContentController = contentController let webView = WKWebView(frame: .zero, configuration: config) webView.navigationDelegate = context.coordinator webView.load(URLRequest(url: url)) return webView } func updateUIView(_ webView: WKWebView, context: Context) {} class WebViewCoordinator: NSObject, WKNavigationDelegate, WKScriptMessageHandler { var parent: WebView init(_ parent: WebView) { self.parent = parent } func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) { if message.name == "IosWebview", let body = message.body as? String { print(body) } } } } ``` #### Supported Events
Event Name Description
TRANSAK_WIDGET_INITIALISED Widget initialised with query params
TRANSAK_WIDGET_OPEN Widget fully loaded
TRANSAK_ORDER_CREATED Order created by user
TRANSAK_ORDER_SUCCESSFUL Order is successful
TRANSAK_ORDER_CANCELLED Order is cancelled
TRANSAK_ORDER_FAILED Order is failed
TRANSAK_WIDGET_CLOSE Widget is about to close