-
Notifications
You must be signed in to change notification settings - Fork 51
Architecture
###Basic Architecture
BlackHawk provide a framework working as a sub Xcode project. Everything is inside the BlackHawkViewController Class.
Inside BlackHawk there is a WKWebView with the same frame of BlackHawkViewController's view, and with some functions from WKScriptMessageHandler, WKUIDelegate and WKNavigationDelegate delegates. Because of Apple's strict policy on web view kernel, all the useful functions and the high performance are from WKWebView directly.
WITHOUT ANY PRIVATE APIs.
###How Dose Javascript Send Messages to Native Layer
We use userContentController(userContentController: WKUserContentController, didReceiveScriptMessage message: WKScriptMessage)
in WKScriptMessageHandler delegate to receive messages sent by javascript. Sendding messages in javascript is pretty easy in WKWebView:
// js code
window.webkit.messageHandlers.BlackHawk.postMessage('Hello BlackHawk!');
We had registed it before:
// swift code
let conf = WKWebViewConfiguration()
conf.userContentController.addScriptMessageHandler(self, name: "BlackHawk")
###How Dose BlackHawk Fire Up Some Code
As we all know Swift is a compiled language the same as Objective-C. But thanks to the Objective-C Runtime we has lots of powerful reflection functions.
We use window.webkit.messageHandlers.BlackHawk.postMessage
send a JavaScript Object with all information we need to native layer:
window.webkit.messageHandlers.BlackHawk.postMessage({className: 'Console', functionName: 'log', taskId: Queue.length - 1, data: string});
We get a NSDictionary on native layer, then we can get the class name and the function name.
####Get the Object
if let cls = NSClassFromString(NSBundle.mainBundle().objectForInfoDictionaryKey("CFBundleName")!.description + "." + className) as? BlackHawkPlugin.Type{
let obj = cls.init()
}
Thanks to the completely Object Oriented Swift and its namespace, we can reflect a object much more safe and flexible:
- Full class name is CFBundleName + ClassName in Swift
- The native plugin class must inherit from BlackHawkPlugin class
- We can call any functions in any plugin classes freely
####Fire the Function
BlackHawkPlugin inherit form NSObject, so we use performSelector()
to fire the function we need.
###How Dose Native Layer Send messages to Javascript Runtime
The WKWebView object wk
has been set to every plugin object's wk property, so we can fire some javascript code easily:
self.wk.evaluateJavaScript("alert(1);", completionHandler: nil)