> ## Documentation Index
> Fetch the complete documentation index at: https://docs.frankieone.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Native Integration

> Learn how to integrate FrankieOne's Web SDK into native mobile apps via WebView. This approach lets you run your OneSDK web implementation within a native WebView container, combining web and native functionality.

<Callout icon="bell" color="#FFCA16" iconType="regular">
  ##### Prerequisites

  * You have installed OneSDK in your web app
  * Android/iOS development experience
  * Your Native App has Camera, Microphone, and Location permissions
  * Your Web App is live
</Callout>

## Implementation Steps

<Steps>
  <Step title="Setup Web WebAppInterface">
    First, ensure your web app is properly configured with OneSDK:

    ```html theme={null}
    <!-- Add our SDK to your web app -->
    <script>
        // Initialize OneSDK
        const oneSdk = await OneSDK({
    			session: {
    				token: YOUR_TOKEN
    			},
    			// Additional configuration options
        });

    		// rest of your OneSDK Implementation
    </script>
    ```
  </Step>

  <Step title="Implement in Native">
    <Tabs>
      <Tab value="android" title="Android" default>
        #### Permissions Setup

        First, add required permissions to your `AndroidManifest.xml`:

        ```xml theme={null}
        <?xml version="1.0" encoding="utf-8"?>
        <manifest xmlns:android="http://schemas.android.com/apk/res/android">
            <!-- Camera permissions -->
            <uses-permission android:name="android.permission.CAMERA" />
            <uses-feature android:name="android.hardware.camera" />
            
            <!-- Microphone permissions -->
            <uses-permission android:name="android.permission.RECORD_AUDIO" />
            
            <!-- Location permissions -->
            <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
            <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
        </manifest>
        ```

        #### WebView Implementation

        Add WebView support with device access permissions:

        ```kotlin theme={null}
        class WebViewActivity : AppCompatActivity() {
            private lateinit var webView: WebView
            private val PERMISSION_REQUEST_CODE = 1234

            override fun onCreate(savedInstanceState: Bundle?) {
                super.onCreate(savedInstanceState)
                setContentView(R.layout.activity_webview)

                // Request permissions
                requestPermissions()

                webView = findViewById(R.id.webView)
                
                // Enable JavaScript
                webView.settings.apply {
                    javaScriptEnabled = true
                    domStorageEnabled = true
                    allowFileAccess = true
                    allowContentAccess = true
                    mediaPlaybackRequiresUserGesture = false  // Allow media autoplay
                }

                // Configure WebChromeClient for handling permissions
                webView.webChromeClient = object : WebChromeClient() {
                    // Camera permission request
                    override fun onPermissionRequest(request: PermissionRequest) {
                        runOnUiThread {
                            request.grant(request.resources)
                        }
                    }

                    // Geolocation permission request
                    override fun onGeolocationPermissionsShowPrompt(
                        origin: String,
                        callback: GeolocationPermissions.Callback
                    ) {
                        callback.invoke(origin, true, false)
                    }
                }

                // Load your web app
                webView.loadUrl("https://your-webapp-url.com")
            }

            private fun requestPermissions() {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                    requestPermissions(
                        arrayOf(
                            Manifest.permission.CAMERA,
                            Manifest.permission.RECORD_AUDIO,
                            Manifest.permission.ACCESS_FINE_LOCATION
                        ),
                        PERMISSION_REQUEST_CODE
                    )
                }
            }

            override fun onRequestPermissionsResult(
                requestCode: Int,
                permissions: Array<String>,
                grantResults: IntArray
            ) {
                super.onRequestPermissionsResult(requestCode, permissions, grantResults)
                when (requestCode) {
                    PERMISSION_REQUEST_CODE -> {
                        if (grantResults.isNotEmpty() && 
                            grantResults.all { it == PackageManager.PERMISSION_GRANTED }) {
                            // All permissions granted, proceed with WebView setup
                        } else {
                            // Handle permission denial
                        }
                    }
                }
            }
        }
        ```
      </Tab>

      <Tab value="ios" title="iOS">
        #### Permissions Setup

        First, add required permissions to your `Info.plist`:

        ```xml theme={null}
        <?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>
            <!-- Camera permissions -->
            <key>NSCameraUsageDescription</key>
            <string>We need access to your camera for [YOUR REASON]</string>
            
            <!-- Microphone permissions -->
            <key>NSMicrophoneUsageDescription</key>
            <string>We need access to your microphone for [YOUR REASON]</string>
            
            <!-- Location permissions -->
            <key>NSLocationWhenInUseUsageDescription</key>
            <string>We need access to your location for [YOUR REASON]</string>
            <key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
            <string>We need access to your location for [YOUR REASON]</string>
        </dict>
        </plist>
        ```

        #### WebView Implementation

        Implement WebView with device access permissions:

        ```swift theme={null}
        import WebKit
        import AVFoundation
        import CoreLocation

        class WebViewController: UIViewController, WKNavigationDelegate, CLLocationManagerDelegate {
            var webView: WKWebView!
            private let locationManager = CLLocationManager()
            
            override func viewDidLoad() {
                super.viewDidLoad()
                
                // Configure WebView
                let configuration = WKWebViewConfiguration()
                configuration.allowsInlineMediaPlayback = true
                
                // Configure camera and microphone access
                configuration.mediaTypesRequiringUserActionForPlayback = []
                
                // Add script for location access
                let contentController = configuration.userContentController
                contentController.add(self, name: "locationHandler")
                
                webView = WKWebView(frame: view.bounds, configuration: configuration)
                webView.navigationDelegate = self
                webView.configuration.allowsInlineMediaPlayback = true
                
                // Set up location manager
                locationManager.delegate = self
                locationManager.desiredAccuracy = kCLLocationAccuracyBest
                
                view.addSubview(webView)
                
                // Request permissions
                requestPermissions()
                
                // Load your web app
                if let url = URL(string: "https://your-webapp-url.com") {
                    let request = URLRequest(url: url)
                    webView.load(request)
                }
            }
            
            private func requestPermissions() {
                // Request camera and microphone permissions
                AVCaptureDevice.requestAccess(for: .video) { granted in
                    if granted {
                        // Camera permission granted
                    }
                }
                
                AVCaptureDevice.requestAccess(for: .audio) { granted in
                    if granted {
                        // Microphone permission granted
                    }
                }
                
                // Request location permission
                locationManager.requestWhenInUseAuthorization()
            }
            
            // Handle location updates
            func locationManager(_ manager: CLLocationManager, 
                               didUpdateLocations locations: [CLLocation]) {
                guard let location = locations.last else { return }
                let script = "updateLocation(\(location.coordinate.latitude), \(location.coordinate.longitude))"
                webView.evaluateJavaScript(script, completionHandler: nil)
            }
        }

        // Extend for WKScriptMessageHandler to handle location requests
        extension WebViewController: WKScriptMessageHandler {
            func userContentController(_ userContentController: WKUserContentController,
                                     didReceive message: WKScriptMessage) {
                if message.name == "locationHandler" {
                    locationManager.startUpdatingLocation()
                }
            }
        }
        ```
      </Tab>
    </Tabs>
  </Step>
</Steps>

## Establishing Communication Between Native and Web Layers

<Tabs>
  <Tab value="android" title="Android" default>
    To enable communication from web to native:

    ```kotlin theme={null}
    class WebAppInterface(private val context: Context) {
        @JavascriptInterface
        fun onEvent(data: String) {
            // Handle events from web app
        }
    }

    // Add the interface to WebView
    webView.addJavascriptInterface(WebAppInterface(this), "Android")
    ```
  </Tab>

  <Tab value="ios" title="iOS">
    Enable web-to-native communication in iOS:

    ```swift theme={null}
    // Configure message handler
    configuration.userContentController.add(self, name: "iOSNative")

    // Handle messages
    extension WebViewController: WKScriptMessageHandler {
        func userContentController(_ userContentController: WKUserContentController,
                                 didReceive message: WKScriptMessage) {
            if message.name == "iOSNative" {
                // Handle message from web app
            }
        }
    }
    ```
  </Tab>
</Tabs>
