To use our SDK with Swift , you only need to add the name of message handler as NativeIOS
when using the WKWebView
. This handler allows our server to communicate with WebViews in Swift. See the example below:
import Foundation
import WebKit
import SwiftUI
struct WebViewContainer: UIViewRepresentable {
let sdkMobileServer = "https://sdk-mobile.cert.zerohash.com/v1/"
let zeroHashAppsURL = "https://web-sdk.cert.zerohash.com/"
var token: String = "<JWT_TOKEN_HERE>"
var url : URL = URL(string: "\(sdkMobileServer)?achDepositsJWT=\(token)&cryptoBuyJWT=\(token)&cryptoSellJWT=\(token)&cryptoWithdrawalsJWT=\(token)&fiatWithdrawalsJWT=\(token)&userOnboardingJWT=\(token)&zeroHashAppsURL=\(zeroHashAppsURL)")!
class Coordinator: NSObject, WKNavigationDelegate, WKScriptMessageHandler {
var webView: WKWebView?
var token: String
init(token: String) {
self.token = token
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
self.webView = webView
}
// Handle messages from the WebView
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
guard let jsonString = message.body as? String else {
print("Unexpected message type:", type(of: message.body))
return
}
do {
guard let jsonObject = try JSONSerialization.jsonObject(with: Data(jsonString.utf8), options: []) as? [String: Any] else {
print("Failed to convert JSON string to a JSON object")
return
}
guard let messageType = jsonObject["type"] as? String else {
print("Missing 'type' key in JSON object")
return
}
print("Message type:", messageType)
if messageType == "SDK_MOBILE_READY" {
print("SDK Mobile ready:", messageType)
self.sendMessageToWebView("OPEN_MODAL")
}
// Handle other message types here
// Your code here...
} catch {
print("Error parsing JSON:", error.localizedDescription)
}
}
func sendMessageToWebView(_ event: String) {
let script = "window.postMessage({type: '\(event)', payload: { appIdentifier: 'crypto-buy'}});"
print("Sending message to WebView:", event)
// print("Sending message to WebView:", script)
webView?.evaluateJavaScript(script, completionHandler: { (result, error) in
if let error = error {
print("Error sending message to WebView:", error.localizedDescription)
}
})
}
// Implement this method to handle navigation requests
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
if let url = navigationAction.request.url {
// Check if the URL is an external link
if navigationAction.navigationType == .linkActivated {
// Optionally open external links in the default browser
UIApplication.shared.open(url, options: [:], completionHandler: nil)
decisionHandler(.cancel) // Cancel the request so the URL doesn't load in the webView
} else {
decisionHandler(.allow) // Allow the request to load within the webView
}
} else {
decisionHandler(.allow) // Allow the request to load within the webView
}
}
}
func makeCoordinator() -> Coordinator {
return Coordinator(onClose: onClose, jwt: jwt, module: module)
}
func makeUIView(context: Context) -> WKWebView {
let coordinator = makeCoordinator()
let userContentController = WKUserContentController()
// Add a script message handler for the 'NativeIOS' message name
// IMPORTANT: do not change the message name 'NativeIOS' as it is used by the SDK to communicate with the native app
userContentController.add(coordinator, name: "NativeIOS")
let configuration = WKWebViewConfiguration()
configuration.userContentController = userContentController
// IMPORTANT: This line is required so that the Onboarding document collection works properly.
configuration.allowsInlineMediaPlayback = true
let _wkwebview = WKWebView(frame: .zero, configuration: configuration)
_wkwebview.navigationDelegate = coordinator
_wkwebview.load(URLRequest(url: url))
return _wkwebview
}
}