Files
duooomi-ble-sdk/wrappers/ios/Sources/DuooomiBleWrapper/DuooomiBleRuntime.swift
2026-04-08 17:04:29 +08:00

116 lines
3.5 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import Foundation
import UIKit
/// Brownfield
public enum DuooomiBleRuntimeError: Error, LocalizedError {
case hostManagerUnavailable
case reactNativeViewUnavailable
public var errorDescription: String? {
switch self {
case .hostManagerUnavailable:
return "Unable to locate ReactNativeHostManager. Make sure the brownfield framework is linked correctly."
case .reactNativeViewUnavailable:
return "Unable to create ReactNativeView automatically. Pass createReactNativeView when starting the runtime."
}
}
}
/// 宿 RN JS
public final class DuooomiBleRuntime {
/// 宿
public static let shared = DuooomiBleRuntime()
private weak var mountedView: UIView?
private weak var containerView: UIView?
private init() {}
/// Brownfield
///
/// - Parameters:
/// - containerView: React Native 宿
/// - initializeHost: 宿
/// - createReactNativeView: RN View
/// - Throws: `DuooomiBleRuntimeError`
public func start(
in containerView: UIView,
initializeHost: (() -> Void)? = nil,
createReactNativeView: (() -> UIView)? = nil
) throws {
if mountedView != nil {
return
}
if let initializeHost {
initializeHost()
} else {
try autoInitializeHostManager()
}
let reactNativeView = createReactNativeView?() ?? try autoCreateReactNativeView()
reactNativeView.isHidden = true
reactNativeView.isUserInteractionEnabled = false
reactNativeView.frame = CGRect(x: 0, y: 0, width: 1, height: 1)
reactNativeView.accessibilityElementsHidden = true
containerView.addSubview(reactNativeView)
self.containerView = containerView
self.mountedView = reactNativeView
DuooomiBleManager.shared.start()
}
/// RN
public func stop() {
DuooomiBleManager.shared.stop()
mountedView?.removeFromSuperview()
mountedView = nil
containerView = nil
}
private func autoInitializeHostManager() throws {
let possibleClassNames = [
"ReactNativeHostManager",
"DuooomiBleSDK.ReactNativeHostManager",
]
for className in possibleClassNames {
guard let managerClass = NSClassFromString(className) as? NSObject.Type else {
continue
}
let sharedSelector = NSSelectorFromString("shared")
let initializeSelector = NSSelectorFromString("initialize")
let managerObject = (managerClass as AnyObject).perform(sharedSelector)?.takeUnretainedValue() as? NSObject
if let managerObject, managerObject.responds(to: initializeSelector) {
managerObject.perform(initializeSelector)
return
}
}
throw DuooomiBleRuntimeError.hostManagerUnavailable
}
private func autoCreateReactNativeView() throws -> UIView {
let possibleClassNames = [
"ReactNativeView",
"DuooomiBleSDK.ReactNativeView",
]
for className in possibleClassNames {
guard let viewClass = NSClassFromString(className) as? NSObject.Type else {
continue
}
if let view = viewClass.init() as? UIView {
return view
}
}
throw DuooomiBleRuntimeError.reactNativeViewUnavailable
}
}