LiSA Social Commerce
Developers
Developers
  • Developers
  • Guides
    • Integration Guide
      • Web Integration
      • App Integration
        • Android
          • Communication
          • Storage
          • File Downloads
          • Theming
        • iOS
          • Communication
          • Storage
          • File Downloads
          • Theming
        • React Native
          • Communication
          • Storage
          • File Downloads
          • Theming
        • Picture in Picture
      • Entrypoints
        • Query Parameter (v1)
    • Player Communication
      • Message API Reference
        • App
          • App — Heartbeat
          • App — Message Acknowledge
          • App — Message Error
          • App — Listen
        • CTA
          • CTA — Link in Comments
          • CTA — Sponsor Badge
        • Cart — View Cart
        • Comments — Join
        • Media
          • Media — Complete
          • Media — Pause
          • Media — Progress
          • Media — Resume
        • Media Item
          • Media Item — Emoji
          • Media Item — Impression
        • Player
          • Player — Dismiss
          • Player — Native Picture-in-Picture (PiP)
          • Player — Pass Visual Viewport
          • Player — Request Visual Viewport
          • Player — UI Transition
        • Products
          • Products — Add to Cart
          • Products — Add to Wishlist
          • Products — Click
          • Products — Close Product List
          • Products — Emoji
          • Products — Emoji State Update
          • Products — Impression
          • Products — Open Product List
        • Stickers
          • Stickers — Activate
          • Stickers — Click
          • Stickers — Expire
          • Stickers — Impression
          • Stickers — Publish
          • Stickers — Unlock
          • Stickers — Unpublish
          • Stickers — Update
          • Stickers — Voucher Claim
        • Visitor — Pass User Context
        • Shared Legacy Message Properties
    • Products
      • Product Update Notification API
  • Widgets
    • Content Hub
    • Quick Start Guide
    • Appearance
      • Markup
      • Responsive design
    • Configuration options
      • Autoplay
      • Channel
      • Client
      • Data
      • Debug
      • Host node
      • Layout
      • Language
      • On
      • Player
      • Query string
      • Quick view
      • Sections
      • Store
      • Template
    • API reference
      • Library API reference
      • Player API reference
      • Quick View API reference
    • Customisations
      • Template
      • Bring your own template
      • Type definitions
    • Examples
    • Type definitions
      • Asset
      • Product
      • Other
    • Promo Widget
      • Quick Start Guide
      • Configuration options
        • Autoplay
        • Channel
        • Countdown (deprecated)
        • Enabled
        • Image modifier
        • Lead time
        • Live (deprecated)
        • Position
        • Replay (deprecated)
        • Show ID
        • URL
  • Media Player Introduction
    • Picture-in-Picture Mode
  • Analytics
  • REST API
    • Authentication
    • Rate limits
    • Response status and error codes
    • API Documentation
Powered by GitBook
On this page
  • Setting Up the WebView
  • Using the WebView in SwiftUI
  1. Guides
  2. Integration Guide
  3. App Integration

iOS

Documentation Update in Progress

We are currently revisiting and updating this section of our documentation to ensure it provides the most accurate and helpful information. Some content may be incomplete or outdated during this process.

Thank you for your patience! If you have any immediate questions, please don’t hesitate to contact our support team.


This guide shows how to embed a React.js web app in a WebView for iOS using SwiftUI. It also demonstrates how to enable messaging between the web app and the host app.

Setting Up the WebView

Use WKWebView to embed the LiSA Player in an iOS application:

import SwiftUI
import WebKit

struct WebView: UIViewRepresentable {
    // Define the specific UIView subclass we are representing
    typealias UIViewType = WKWebView

    let urlString: String

    func makeUIView(context: Context) -> WKWebView {
        // Configuration
        let webViewConfiguration = WKWebViewConfiguration()
        // Allow video playback inline
        webViewConfiguration.allowsInlineMediaPlayback = true
        // Allow PiP for video
        webViewConfiguration.allowsPictureInPictureMediaPlayback = true
        // Allow JS to enter fullscreen
        webViewConfiguration.preferences.isElementFullscreenEnabled = true

        // Allow media to play without user gesture (use with caution, respect user settings)
        webViewConfiguration.mediaTypesRequiringUserActionForPlayback = []

        // JavaScript Injection
        let scriptSource = """
        window._lscLocalThemeOptions = { playerDismissCtaState: "enabled" };
        """
        let userScript = WKUserScript(source: scriptSource, injectionTime: .atDocumentEnd, forMainFrameOnly: true)

        let contentController = WKUserContentController()
        contentController.addUserScript(userScript)

        // Register the message handler with the coordinator
        contentController.add(context.coordinator, name: "MessageFromLiSA")
        webViewConfiguration.userContentController = contentController

        // Create WKWebView
        // Use .zero frame; SwiftUI will manage the actual frame size
        let webView = WKWebView(frame: .zero, configuration: webViewConfiguration)

        // Only include this setting in Debug builds
        #if DEBUG
        if #available(iOS 16.4, *) {
            // Explicitly allow inspection for Debug builds on iOS 16.4+
            // Log confirmation
            print("Setting webView.isInspectable = true")
            // Set on the webView instance
            webView.isInspectable = true
        }
        #endif

        // Set background colors (optional, black might hide loading issues initially)
        // Consider using .clear or removing these if the webpage has its own background
        webView.backgroundColor = .black
        webView.scrollView.backgroundColor = .black

        // Can help if you want SwiftUI background to show through
        webView.isOpaque = false

        webView.scrollView.contentInsetAdjustmentBehavior = .never

        // Set Delegates
        webView.navigationDelegate = context.coordinator
        // Needed for things like JavaScript alerts or window opening
        webView.uiDelegate = context.coordinator

        // Store reference in Coordinator
        // Keep a reference if coordinator needs to access webView later
        context.coordinator.webView = webView

        // Initial Load
        // Load the initial URL directly in makeUIView
        if let url = URL(string: urlString) {
            let request = URLRequest(url: url)
            webView.load(request)
        }

        // Return the WKWebView directly
        return webView
    }

    func updateUIView(_ webView: WKWebView, context: Context) {
        // The `uiView` parameter *is* the WKWebView because we set UIViewType
        // Check if the urlString prop has changed and reload if necessary
        if let currentURL = webView.url?.absoluteString, currentURL == urlString {
           // URL hasn't changed, do nothing
           return
        }
        
        // URL string has changed, load the new one
        if let url = URL(string: urlString) {
            let request = URLRequest(url: url)
            webView.load(request)
        }
    }

    func makeCoordinator() -> Coordinator {
        // Pass the WebView struct itself if needed
        Coordinator(self)
    }

    // Coordinator
    // Handles callbacks from the WKWebView
    class Coordinator: NSObject, WKScriptMessageHandler, WKNavigationDelegate, WKUIDelegate {
        // Reference back to the SwiftUI view
        var parent: WebView
        // Weak reference maybe better if lifecycle allows?
        var webView: WKWebView?

        init(_ parent: WebView) {
            self.parent = parent
        }

        // WKScriptMessageHandler
        func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
            if message.name == "MessageFromLiSA" {
                // Handle message from JavaScript
                print("Received message from LiSA: \(message.body)")
                // You could trigger actions in your SwiftUI view here if needed,
                // e.g., using @State variables passed down or Combine publishers.
            }
        }

        // WKNavigationDelegate (Example Methods)
        func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
            print("WebView did finish loading")
            // You could update SwiftUI state here, e.g., hide a loading indicator
        }

        func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
            print("WebView failed navigation: \(error.localizedDescription)")
            // Handle loading errors
        }

        func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) {
            print("WebView failed provisional navigation: \(error.localizedDescription)")
             // Handle initial loading errors (e.g., server not found)
        }

        // WKUIDelegate (Optional - Add methods as needed)
        // Example: Handle JavaScript window.open()
        func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
            // If the request is a main frame navigation, open in Safari/default browser
            if navigationAction.targetFrame == nil {
                webView.load(navigationAction.request)
            }
            // Prevents opening a new webview window within the app
            return nil
        }
    }
}

Using the WebView in SwiftUI

Here’s how to use the WebView component:

struct ContentView: View {
    // Example URL - Replace with your actual URL
    private let urlString: String = "https://{clientId}.loveslisa.tech/s/{showId}"

    var body: some View {
        // Use edgesIgnoringSafeArea for older iOS/better compatibility
        WebView(urlString: urlString)
            .edgesIgnoringSafeArea(.all)
    }
}
PreviousThemingNextCommunication

Last updated 1 month ago