Guides

Hybrid Integration

Saucelive Weband Mobile integration

Implementing In-App Bridge Communication

A "Bridge" refers to the connection code used to enable communication between web content and native code, especially in hybrid apps or web apps that include native modules.

By using a bridge, code written in web technologies can access or manipulate native features of mobile devices such as the camera, GPS, or file system. This allows for the reuse of web-based code across platforms while delivering a native-like performance and user experience.


iOS Bridge Setup

Project Setup

STEP 1. Create a new project in Xcode.

STEP 2. Create a WKWebView instance.

Creating the Web Page

Create a simple web page (index.html) and add it to the project. Here's an example page:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>JS Bridge Example</title>
</head>
<body>

<button onclick="sendMessageToiOS('Hello from Web!')">Send Message to iOS</button>

<script>
    function sendMessageToiOS(message) {
        window.webkit.messageHandlers.bridge.postMessage(message);
    }
</script>

</body>
</html>

WKWebView Configuration

Configure WKWebView in ViewController.swift to load the web page and set up JavaScript communication.

import UIKit
import WebKit

class ViewController: UIViewController, WKScriptMessageHandler {
    
    @IBOutlet weak var webView: WKWebView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let contentController = WKUserContentController()
        contentController.add(self, name: "bridge")
        
        let config = WKWebViewConfiguration()
        config.userContentController = contentController
        
        webView.configuration.userContentController = contentController
        
        if let url = Bundle.main.url(forResource: "index", withExtension: "html") {
            webView.loadFileURL(url, allowingReadAccessTo: url.deletingLastPathComponent())
        }
    }
    
    func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
        if message.name == "bridge", let messageBody = message.body as? String {
            print("Received message from web: \(messageBody)")
            // Perform necessary actions here
        }
    }
}

Sending Messages from Web to iOS

Clicking the button on the web page invokes the JavaScript function sendMessageToiOS(), which sends a message to the iOS app. The iOS side receives the message in userContentController(_:didReceive:).

Sending Messages from iOS to Web

To call a JavaScript function in the web page from the iOS app, use theevaluateJavaScript(_:completionHandler:)method.

webView.evaluateJavaScript("alert('Hello from iOS!')", completionHandler: nil)
// Show PIP button when set to true
let name = "(function() { window.dispatchEvent(sauceflexPictureInPictureUse(true)); })();"
// Hide PIP button when set to false
let name = "(function() { window.dispatchEvent(sauceflexPictureInPictureUse(false)); })();"

webView?.evaluateJavaScript(name) { (Result, Error) in
	if let error = Error {
  	 print("evaluateJavaScript Error : \(error)")
  }
  print("evaluateJavaScript Result : \(Result ?? "success")")
}


Flutter Bridge Setup

This section explains how to enable communication between a Flutter app and web content using the webview_flutter package.

Adding Required Packages

Add the webview_flutter package to your project's pubspec.yaml file:

dependencies:
 flutter:
  sdk: flutter
 webview_flutter: ^3.0.0

Setting Up the WebView Widget

Use a WebView widget in Flutter to load the web page and set up JavaScript communication.

// code example
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';

class WebViewExample extends StatefulWidget {
 @override
 _WebViewExampleState createState() => _WebViewExampleState();
}

class _WebViewExampleState extends State<WebViewExample> {
 final _controller = Completer<WebViewController>();
 @override
 Widget build(BuildContext context) {
  return Scaffold(
   appBar: AppBar(
    title: Text('WebView Example'),
   ),
   body: WebView(
    initialUrl: 'https://yourwebsite.com',
    javascriptMode: JavascriptMode.unrestricted,
    onWebViewCreated: (WebViewController webViewController) {
     _controller.complete(webViewController);
    },
    javascriptChannels: <JavascriptChannel>{
     _createJavascriptChannel(),
    },
   ),
  );
 }
 JavascriptChannel _createJavascriptChannel() {
  return JavascriptChannel(
    name: 'FlutterBridge',
    onMessageReceived: (JavascriptMessage message) {
     print('Message received from web: ${message.message}');
    });
 }
}

Sending Messages from Web to Flutter

Example of basic communication between Flutter and web content:

// code example
function sendMessageToFlutter(message) {
  if (window.FlutterBridge) {
    window.FlutterBridge.postMessage(message);
  }
}

Player Bridge Integration (Web → App communication)

iOS

)

After implementing the base guide, add platform-specific code as needed.

Player Bridge add

iOS

...
let contentController = WKUserContentController()
contentController.add(self, name: "sauceflexEnter")
contentController.add(self, name: "sauceflexBroadcastStatus")
contentController.add(self, name: "sauceflexMoveExit")
contentController.add(self, name: "sauceflexMoveLogin")
contentController.add(self, name: "sauceflexMoveProduct")
contentController.add(self, name: "sauceflexMoveBanner")
contentController.add(self, name: "sauceflexMoveCoupon")
contentController.add(self, name: "sauceflexMoveReward")
contentController.add(self, name: "sauceflexOnShare")
contentController.add(self, name: "sauceflexPictureInPicture")
contentController.add(self, name: "sauceflexWebviewReloading")
...

Add bridge functionality for communication

iOS

extension ViewController: WKScriptMessageHandler {
    func userContentController(_ userContentController: WKUserContentController,
                                    didReceive message: WKScriptMessage) {
        switch (message.name) {
            case "sauceflexEnter": // Callback when entering the broadcast - Automatically triggered when entering the page
                print("sauceflexEnter")
                break
                
            case "sauceflexBroadcastStatus": // Callback when broadcast status changes - Automatically triggered when broadcast status changes
                print("sauceflexBroadcastStatus")
                break
                
            case "sauceflexMoveExit": // Callback when exiting
                print("sauceflexMoveExit")
                break
 
            case "sauceflexMoveLogin": // 	Callback when logging in
                print("sauceflexMoveLogin")
                break
 
            case "sauceflexMoveProduct": // Callback when a product is clicked
                print("sauceflexMoveProduct")
                print(message.body)
                break
                
            case "sauceflexMoveBanner": // 	Callback when a banner is clicked
                print("sauceflexMoveBanner")
                print(message.body)
                break
                
            case "sauceflexMoveCoupon": // 	Callback when a coupon  is clicked
                print("sauceflexMoveCoupon")
                print(message.body)
                break
                
            case "sauceflexMoveReward": // 	Callback when reward is completed
                print("sauceflexMoveReward")
                print(message.body)
                break
 
            case "sauceflexOnShare": // Callback when the share button is clicked
                print("sauceflexOnShare")
                print(message.body)
                break
 
            case "sauceflexPictureInPicture": // Callback when the PIP toggle button is clicked (Elements above the player are automatically hidden in PIP mode)
                print("sauceflexPictureInPicture")
                break
 
            case "sauceflexWebviewReloading": // 	Callback when the WebView is reloaded
                print("sauceflexWebviewReloading")
                break

            default:
                print("message.name \\(message.name) not handled.")
        }
    }
}


Example of Player Bridge integration (Share)

iOS

extension ViewController: WKScriptMessageHandler {
    func userContentController(_ userContentController: WKUserContentController,
                               didReceive message: WKScriptMessage) {
        switch (message.name) {
        case "sauceflexOnShare":
            if let messageBody = message.body as? String,
               let messageData = messageBody.data(using: .utf8) {
                do {
                    if let parsedJSON = try JSONSerialization.jsonObject(with: messageData, options: []) as? [String: Any] {
                        var shareURL: URL?
                        
                        if let linkURLString = parsedJSON["linkUrl"] as? String {  // If using shortUrl, you can replace it with parsedJSON["shortUrl"]
                            shareURL = URL(string: linkURLString)
                        }
                        
                        if let url = shareURL {
                            let itemsToShare = [url]
                            let activityViewController = UIActivityViewController(activityItems: itemsToShare, applicationActivities: nil)
                            activityViewController.popoverPresentationController?.sourceView = self.view
                            self.present(activityViewController, animated: true, completion: nil)
                        } else {
                            print("	No shareable URL available.")
                        }
                    }
                } catch {
                    print("JSON pasing error: \(error)")
                }
            }
        default:
            print(message.name)
        }
    }
}