diff --git a/caravel/Caravel.swift b/caravel/Caravel.swift index a51f752..d63e920 100644 --- a/caravel/Caravel.swift +++ b/caravel/Caravel.swift @@ -161,6 +161,8 @@ public class Caravel { internal func dispatch(busName: String, eventName: String, eventData: AnyObject?) { if busName != self.name { + // Different buses can use the same web view so same proxy + // If not a potential receiver, ignore event return } diff --git a/caravel/internal/proxies/WKScriptMessageHandlerProxy.swift b/caravel/internal/proxies/WKScriptMessageHandlerProxy.swift index 3f50e8a..5b9329c 100644 --- a/caravel/internal/proxies/WKScriptMessageHandlerProxy.swift +++ b/caravel/internal/proxies/WKScriptMessageHandlerProxy.swift @@ -6,23 +6,23 @@ import WebKit Sets up a custom script message handler for the provided configuration */ internal class WKScriptMessageHandlerProxy: NSObject, WKScriptMessageHandler { - private static let subscriberLock = NSObject() - + private let subscriberLock = NSObject() + /** All the subscribers. */ private lazy var subscribers: [IWKWebViewObserver] = [] - + init(configuration: WKWebViewConfiguration) { super.init() - + configuration.userContentController.addScriptMessageHandler(self, name: "caravel") } - + private func lockSubscribers(@noescape action: () -> Void) { - synchronized(WKScriptMessageHandlerProxy.subscriberLock, action: action) + synchronized(subscriberLock, action: action) } - + private func iterateOverDelegates(callback: (IWKWebViewObserver) -> Void) { self.lockSubscribers { for e in self.subscribers { @@ -30,7 +30,7 @@ internal class WKScriptMessageHandlerProxy: NSObject, WKScriptMessageHandler { } } } - + func subscribe(subscriber: IWKWebViewObserver) { lockSubscribers { for s in self.subscribers { @@ -38,11 +38,11 @@ internal class WKScriptMessageHandlerProxy: NSObject, WKScriptMessageHandler { return } } - + self.subscribers.append(subscriber) } } - + func unsubscribe(subscriber: IWKWebViewObserver) { lockSubscribers { var i = 0 @@ -55,19 +55,23 @@ internal class WKScriptMessageHandlerProxy: NSObject, WKScriptMessageHandler { } } } - + func hasSubscribers() -> Bool { return self.subscribers.count > 0 } - + + func willBeDeleted(config: WKWebViewConfiguration) { + config.userContentController.removeScriptMessageHandlerForName("caravel") + } + func userContentController(userContentController: WKUserContentController, didReceiveScriptMessage message: WKScriptMessage) { let body = message.body as! Dictionary let busName = body["busName"] as! String let eventName = body["eventName"] as! String let eventData = body["eventData"] - - iterateOverDelegates {e in - background {e.onMessage(busName, eventName: eventName, eventData: eventData)} + + iterateOverDelegates { e in + background { e.onMessage(busName, eventName: eventName, eventData: eventData) } } } } \ No newline at end of file diff --git a/caravel/internal/proxies/WKWebViewMediator.swift b/caravel/internal/proxies/WKWebViewMediator.swift index 3f3e43a..ba6bac5 100644 --- a/caravel/internal/proxies/WKWebViewMediator.swift +++ b/caravel/internal/proxies/WKWebViewMediator.swift @@ -7,51 +7,47 @@ import WebKit */ internal class WKScriptMessageHandlerProxyMediator { private static let creationLock = NSObject() - + /** Indexed by WKWebViewConfiguration's hash */ private static var proxies: [Int: WKScriptMessageHandlerProxy] = [:] - + private static func lockProxies(@noescape action: () -> Void) { synchronized(creationLock, action: action) } - + static func subscribe(configuration: WKWebViewConfiguration, observer: IWKWebViewObserver) { - let action: Void -> Bool = { - for (k, v) in proxies { - if k == configuration.hash { - v.subscribe(observer) - return true - } - } - return false - } - - if !action() { + let key = configuration.hash + + if let p = proxies[key] { + p.subscribe(observer) + } else { lockProxies { - if action() { - return - } else { - let p = WKScriptMessageHandlerProxy(configuration: configuration) + if let p = proxies[key] { p.subscribe(observer) - proxies[configuration.hash] = p + } else { + let proxy = WKScriptMessageHandlerProxy(configuration: configuration) + proxy.subscribe(observer) + proxies[key] = proxy } } } } - + static func unsubscribe(configuration: WKWebViewConfiguration, observer: IWKWebViewObserver) { - for (k, v) in proxies { - if k == configuration.hash { - v.unsubscribe(observer) - - if !v.hasSubscribers() { - lockProxies { - proxies.removeValueForKey(configuration.hash) + let key = configuration.hash + + if let p = proxies[key] { + p.unsubscribe(observer) + + if !p.hasSubscribers() { + lockProxies { + if !p.hasSubscribers() { + p.willBeDeleted(configuration) + proxies.removeValueForKey(key) } } - return } } }