Hybrid Integration
Saucelive Web
and 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
WKWebView
ConfigurationConfigure 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)
}
}
}
Updated 13 days ago