iOS

Seamless OZZOBiT integration for iOS applications

Integrate OZZOBiT into your iOS application using WKWebView. This guide covers Swift and SwiftUI implementations for embedding the OZZOBiT widget in native iOS apps.

Prerequisites

  • iOS 13.0+ with WKWebView support
  • A valid OZZOBiT API key from the Partner Dashboard
  • App Transport Security configured (HTTPS required)

Installation

Add Dependency

Podfileruby
# Podfile
platform :ios, '13.0'

target 'YourApp' do
  use_frameworks!
  pod 'OZZOBiTSDK', :git => 'https://github.com/OZZOBiT/OZZOBiT-ios-sdk.git'
end
texttext
// In Xcode: File → Add Packages...
// Enter URL: https://github.com/OZZOBiT/OZZOBiT-ios-sdk.git
// Select version and add to target

Configure App Transport Security

Info.plistxml
<!-- Info.plist -->
<key>NSAppTransportSecurity</key>
<dict>
  <key>NSAllowsArbitraryLoads</key>
  <false/>
  <key>NSExceptionDomains</key>
  <dict>
    <key>OZZOBiT.com/global</key>
    <dict>
      <key>NSIncludesSubdomains</key>
      <true/>
      <key>NSExceptionAllowsInsecureHTTPLoads</key>
      <false/>
      <key>NSExceptionMinimumTLSVersion</key>
      <string>TLSv1.2</string>
      <key>NSExceptionRequiresForwardSecrecy</key>
      <true/>
    </dict>
  </dict>
</dict>

Implement WKWebView Controller

OZZOBiTViewController.swiftswift
// OZZOBiTViewController.swift
import UIKit
import WebKit

class OZZOBiTViewController: UIViewController {

    private var webView: WKWebView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        setupWebView()
        loadOZZOBiTWidget()
    }
    
    private func setupWebView() {
        let config = WKWebViewConfiguration()
        config.allowsInlineMediaPlayback = true
        
        // Enable JavaScript
        let preferences = WKPreferences()
        preferences.javaScriptEnabled = true
        config.preferences = preferences
        
        // Create WebView
        webView = WKWebView(frame: view.bounds, configuration: config)
        webView.navigationDelegate = self
        webView.uiDelegate = self
        webView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        
        // Add to view hierarchy
        view.addSubview(webView)
    }
    
    private func loadOZZOBiTWidget() {
        var components = URLComponents(string: "https://OZZOBiT.com/global")!
        
        let queryItems = [
            URLQueryItem(name: "apiKey", value: "YOUR_PUBLIC_API_KEY"),
            URLQueryItem(name: "productsAvailed", value: "BUY"),
            URLQueryItem(name: "network", value: "ethereum"),
            URLQueryItem(name: "defaultCryptoCurrency", value: "ETH"),
            URLQueryItem(name: "defaultFiatCurrency", value: "USD"),
            URLQueryItem(name: "themeColor", value: "#1461db"),
            URLQueryItem(name: "redirectURL", value: "your-app-scheme://callback"),
        ]
        components.queryItems = queryItems
        
        guard let url = components.url else { return }
        let request = URLRequest(url: url)
        webView.load(request)
    }
}

// MARK: - WKNavigationDelegate
extension OZZOBiTViewController: WKNavigationDelegate {
    
    func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction) async -> WKNavigationActionPolicy {
        guard let url = navigationAction.request.url else {
            return .allow
        }
        
        // Handle callback / redirect URLs
        if url.scheme == "your-app-scheme" || url.absoluteString.contains("callback") {
            handleCallback(url)
            return .cancel
        }
        
        return .allow
    }
    
    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        // Widget loaded - hide loading indicator if any
    }
    
    func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
        print("Navigation failed: \(error.localizedDescription)")
    }
}

// MARK: - WKUIDelegate
extension OZZOBiTViewController: WKUIDelegate {
    
    func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
        // Handle links that want to open in a new window
        if navigationAction.targetFrame == nil {
            webView.load(navigationAction.request)
        }
        return nil
    }
}

// MARK: - Callback Handling
extension OZZOBiTViewController {
    
    private func handleCallback(_ url: URL) {
        let components = URLComponents(url: url, resolvingAgainstBaseURL: false)
        let status = components?.queryItems?.first(where: { $0.name == "status" })?.value
        let orderId = components?.queryItems?.first(where: { $0.name == "orderId" })?.value
        
        DispatchQueue.main.async {
            switch status {
            case "SUCCESS":
                self.handleSuccess(orderId ?? "")
            case "FAILURE":
                self.handleFailure(orderId ?? "")
            default:
                break
            }
            
            self.dismiss(animated: true)
        }
    }
    
    private func handleSuccess(_ orderId: String) {
        print("Order successful: \(orderId)")
        NotificationCenter.default.post(
            name: Notification.Name("OZZOBiTOrderSuccess"),
            object: nil,
            userInfo: ["orderId": orderId]
        )
    }
    
    private func handleFailure(_ orderId: String) {
        print("Order failed: \(orderId)")
    }
}

SwiftUI Implementation

OZZOBiTView.swiftswift
// OZZOBiTView.swift
import SwiftUI
import WebKit

struct OZZOBiTView: UIViewRepresentable {
    
    let apiKey: String
    let walletAddress: String
    let network: String
    let cryptoCurrency: String
    
    func makeUIView(context: Context) -> WKWebView {
        let config = WKWebViewConfiguration()
        config.preferences.javaScriptEnabled = true
        
        let webView = WKWebView(frame: .zero, configuration: config)
        webView.navigationDelegate = context.coordinator
        
        return webView
    }
    
    func updateUIView(_ uiView: WKWebView, context: Context) {
        var components = URLComponents(string: "https://OZZOBiT.com/global")!
        components.queryItems = [
            URLQueryItem(name: "apiKey", value: apiKey),
            URLQueryItem(name: "productsAvailed", value: "BUY"),
            URLQueryItem(name: "network", value: network),
            URLQueryItem(name: "defaultCryptoCurrency", value: cryptoCurrency),
            URLQueryItem(name: "walletAddress", value: walletAddress),
        ]
        
        if let url = components.url {
            uiView.load(URLRequest(url: url))
        }
    }
    
    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }
    
    class Coordinator: NSObject, WKNavigationDelegate {
        var parent: OZZOBiTView
        
        init(_ parent: OZZOBiTView) {
            self.parent = parent
        }
        
        func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction) async -> WKNavigationActionPolicy {
            return .allow
        }
    }
}

// Usage in SwiftUI:
struct ContentView: View {
    @State private var showOZZOBiT = false
    
    var body: some View {
        VStack {
            Button("Buy Crypto") {
                showOZZOBiT = true
            }
            .buttonStyle(.borderedProminent)
        }
        .fullScreenCover(isPresented: $showOZZOBiT) {
            OZZOBiTView(
                apiKey: "YOUR_PUBLIC_API_KEY",
                walletAddress: "0x742d35Cc6634C0532925a3b844Bc9e7595f8bD21",
                network: "ethereum",
                cryptoCurrency: "ETH"
            )
            .ignoresSafeArea()
        }
    }
}
ℹ️
Tips
  • Use .sheet or .fullScreenCover in SwiftUI for modal presentation
  • Register a custom URL scheme in your project settings for deep linking callbacks
  • Test on both simulator and real devices as WebView behavior can differ