Core bridge setup and view controller integration for embedding Capacitor web applications in iOS apps.
Main view controller class that iOS developers subclass or use directly to integrate Capacitor web applications.
/**
* Main view controller for Capacitor applications that manages webview lifecycle and bridge initialization
*/
open class CAPBridgeViewController: UIViewController {
// MARK: - Configuration
/**
* Override to provide custom instance configuration
* @returns InstanceDescriptor for configuring the Capacitor instance
*/
open func instanceDescriptor() -> InstanceDescriptor
/**
* Override to customize WKWebView configuration before initialization
* @param instanceConfiguration The instance configuration
* @returns Configured WKWebViewConfiguration
*/
open func webViewConfiguration(for instanceConfiguration: InstanceConfiguration) -> WKWebViewConfiguration
/**
* Called after Capacitor bridge has finished loading and is ready
* Override to perform post-initialization setup
*/
open func capacitorDidLoad()
// MARK: - Properties
/** Reference to the active bridge instance */
public var bridge: CAPBridgeProtocol? { get }
/** Reference to the managed WKWebView */
public var webView: WKWebView? { get }
/** Controls status bar visibility */
public var isStatusBarVisible: Bool { get set }
/** Controls status bar appearance style */
public var statusBarStyle: UIStatusBarStyle { get set }
/** Array of supported device orientations */
public var supportedOrientations: [Int] { get set }
}Usage Examples:
import UIKit
import Capacitor
// Basic implementation
class MyViewController: CAPBridgeViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Bridge automatically initializes with default configuration
}
}
// Custom configuration
class CustomViewController: CAPBridgeViewController {
override func instanceDescriptor() -> InstanceDescriptor {
let descriptor = InstanceDescriptor()
descriptor.appLocation = Bundle.main.url(forResource: "dist", withExtension: nil)!
descriptor.appStartPath = "index.html"
descriptor.backgroundColor = UIColor.systemBackground
descriptor.scrollingEnabled = false
return descriptor
}
override func capacitorDidLoad() {
super.capacitorDidLoad()
// Bridge is ready, can register plugins or perform setup
bridge?.registerPluginType(MyCustomPlugin.self)
}
}
// Status bar customization
class CustomStatusBarController: CAPBridgeViewController {
override func viewDidLoad() {
super.viewDidLoad()
isStatusBarVisible = false
statusBarStyle = .lightContent
supportedOrientations = [UIInterfaceOrientation.portrait.rawValue]
}
}Core bridge implementation that handles JavaScript-to-native communication and plugin management.
/**
* Core bridge implementation for JavaScript-native communication
*/
open class CapacitorBridge: NSObject, CAPBridgeProtocol {
// MARK: - Properties
/** Reference to the managed WKWebView */
public var webView: WKWebView? { get }
/** Runtime configuration for the bridge */
public var config: InstanceConfiguration { get }
/** Notification routing handler */
public var notificationRouter: NotificationRouter { get }
/** True if running in iOS Simulator */
public var isSimEnvironment: Bool { get }
/** True if running in development mode */
public var isDevEnvironment: Bool { get }
// MARK: - Plugin Management
/**
* Get plugin instance by name
* @param name Plugin identifier string
* @returns Plugin instance or nil if not found
*/
public func plugin(withName name: String) -> CAPPlugin?
/**
* Register a plugin type for automatic instantiation
* @param pluginType Plugin class conforming to CAPBridgedPlugin
*/
public func registerPluginType(_ pluginType: CAPPlugin.Type)
// MARK: - JavaScript Execution
/**
* Execute JavaScript code in the webview
* @param js JavaScript code string to execute
*/
public func eval(js: String)
/**
* Execute JavaScript with plugin context
* @param js JavaScript code to execute
* @param plugin Plugin instance for context
*/
public func evalWithPlugin(js: String, plugin: CAPPlugin)
// MARK: - Call Management
/**
* Save a plugin call for later retrieval
* @param call Plugin call to save
*/
public func saveCall(_ call: CAPPluginCall)
/**
* Release a saved plugin call
* @param call Plugin call to release
*/
public func releaseCall(_ call: CAPPluginCall)
/**
* Get saved call by ID
* @param callbackId Callback identifier
* @returns Saved plugin call or nil
*/
public func getSavedCall(_ callbackId: String) -> CAPPluginCall?
// MARK: - UI Utilities
/**
* Show native alert dialog
* @param title Alert title
* @param message Alert message
* @param buttonTitle Button text
*/
public func showAlertWith(title: String, message: String, buttonTitle: String)
/**
* Present view controller modally
* @param viewController View controller to present
* @param animated Whether to animate presentation
* @param completion Completion handler
*/
public func presentViewController(_ viewController: UIViewController, animated: Bool, completion: (() -> Void)?)
/**
* Dismiss presented view controller
* @param animated Whether to animate dismissal
* @param completion Completion handler
*/
public func dismissViewController(animated: Bool, completion: (() -> Void)?)
}Usage Examples:
// Direct bridge usage (advanced)
let bridge = CapacitorBridge()
bridge.registerPluginType(MyPlugin.self)
// Execute JavaScript
bridge.eval(js: "console.log('Hello from native!')")
// Get plugin instance
if let plugin = bridge.plugin(withName: "MyPlugin") as? MyPlugin {
plugin.doSomething()
}
// Show alert
bridge.showAlertWith(
title: "Error",
message: "Something went wrong",
buttonTitle: "OK"
)Protocol defining the bridge contract for plugins to interact with the bridge system.
/**
* Bridge protocol defining standard interface for plugins
*/
@objc public protocol CAPBridgeProtocol {
// MARK: - Environment Access
/** Reference to the webview */
var webView: WKWebView? { get }
/** Bridge configuration */
var config: InstanceConfiguration { get }
/** Notification router */
var notificationRouter: NotificationRouter { get }
// MARK: - Plugin Management
/**
* Get plugin by name
* @param name Plugin identifier
* @returns Plugin instance or nil
*/
func plugin(withName name: String) -> CAPPlugin?
/**
* Register plugin type
* @param pluginType Plugin class to register
*/
func registerPluginType(_ pluginType: CAPPlugin.Type)
// MARK: - JavaScript Execution
/**
* Execute JavaScript in webview
* @param js JavaScript code to execute
*/
func eval(js: String)
// MARK: - Call Management
/**
* Save call for later use
* @param call Plugin call to save
*/
func saveCall(_ call: CAPPluginCall)
/**
* Release saved call
* @param call Plugin call to release
*/
func releaseCall(_ call: CAPPluginCall)
// MARK: - UI Utilities
/**
* Show alert dialog
* @param title Alert title
* @param message Alert message
* @param buttonTitle Button text
*/
func showAlertWith(title: String, message: String, buttonTitle: String)
}Usage in Plugins:
class MyPlugin: CAPPlugin {
@objc func myMethod(_ call: CAPPluginCall) {
// Access bridge through protocol
bridge?.eval(js: "console.log('Plugin method called')")
// Get other plugins
if let otherPlugin = bridge?.plugin(withName: "OtherPlugin") {
// Interact with other plugin
}
// Show alert
bridge?.showAlertWith(
title: "Info",
message: "Method executed",
buttonTitle: "OK"
)
call.resolve()
}
}