Skip to content
JohnLui edited this page Aug 30, 2015 · 1 revision

###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:

  1. Full class name is CFBundleName + ClassName in Swift
  2. The native plugin class must inherit from BlackHawkPlugin class
  3. 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)
Clone this wiki locally