***
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
|