Skip to content

Commit

Permalink
Rewrite XWVInvocation with Swift
Browse files Browse the repository at this point in the history
  • Loading branch information
Zhenyu Liang committed Jul 28, 2015
1 parent 1e81a80 commit 3d1e08a
Show file tree
Hide file tree
Showing 9 changed files with 418 additions and 484 deletions.
22 changes: 9 additions & 13 deletions XWebView.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@
AB023EBE1A8C8BC700580A2A /* XWebView.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = EE62683519FA323900EFC3F8 /* XWebView.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
AB2273E51AA6FDA700F9207A /* www in Resources */ = {isa = PBXBuildFile; fileRef = AB2273E41AA6FDA700F9207A /* www */; };
ABD3E8541A8CD08300F2BAB9 /* XWVInventoryTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABD3E8531A8CD08300F2BAB9 /* XWVInventoryTest.swift */; };
ABD3E85E1A8CD49F00F2BAB9 /* XWVInvocationTest.m in Sources */ = {isa = PBXBuildFile; fileRef = ABD3E85D1A8CD49F00F2BAB9 /* XWVInvocationTest.m */; };
ABD475E31A4129FC00F3BDEB /* XWVInvocation.h in Headers */ = {isa = PBXBuildFile; fileRef = EE62691D19FA52FC00EFC3F8 /* XWVInvocation.h */; settings = {ATTRIBUTES = (Public, ); }; };
ABF68ECD1A6B45FC0058267B /* XWebView.h in Headers */ = {isa = PBXBuildFile; fileRef = EE62691C19FA52FC00EFC3F8 /* XWebView.h */; settings = {ATTRIBUTES = (Public, ); }; };
EE0A1DD31A52775400C9E6D3 /* XWVChannel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE0A1DD21A52775400C9E6D3 /* XWVChannel.swift */; };
EE131CA71B5F900400A9E790 /* XWVUserScript.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE131CA61B5F900400A9E790 /* XWVUserScript.swift */; };
Expand All @@ -26,7 +24,7 @@
EE3379391AE2E298009124A4 /* XWVTestCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE3379381AE2E298009124A4 /* XWVTestCase.swift */; };
EE33793E1AE56875009124A4 /* XWVScriptObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE33793D1AE56875009124A4 /* XWVScriptObject.swift */; };
EE3379401AE57566009124A4 /* XWVScriptingTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE33793F1AE57566009124A4 /* XWVScriptingTest.swift */; };
EE62692419FA52FC00EFC3F8 /* XWVInvocation.m in Sources */ = {isa = PBXBuildFile; fileRef = EE62691E19FA52FC00EFC3F8 /* XWVInvocation.m */; };
EE5BA7BD1B67DC940095AAE7 /* XWVInvocationTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE5BA7BC1B67DC940095AAE7 /* XWVInvocationTest.swift */; };
EE62692619FA52FC00EFC3F8 /* XWebView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE62692019FA52FC00EFC3F8 /* XWebView.swift */; };
EE71648F1A716C9F00078FF9 /* XWVHttpConnection.h in Headers */ = {isa = PBXBuildFile; fileRef = EE71648B1A716C9F00078FF9 /* XWVHttpConnection.h */; };
EE7164901A716C9F00078FF9 /* XWVHttpConnection.m in Sources */ = {isa = PBXBuildFile; fileRef = EE71648C1A716C9F00078FF9 /* XWVHttpConnection.m */; };
Expand All @@ -36,6 +34,7 @@
EE92C65F1B5ACF81000FE1DA /* XWVMetaObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE92C65E1B5ACF81000FE1DA /* XWVMetaObject.swift */; };
EE92C6611B5AD7DB000FE1DA /* XWVMetaObjectTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE92C6601B5AD7DB000FE1DA /* XWVMetaObjectTest.swift */; };
EE92C6621B5AD86E000FE1DA /* XWVMetaObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE92C65E1B5ACF81000FE1DA /* XWVMetaObject.swift */; };
EEDF30601B6555B900A21659 /* XWVInvocation.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEDF305F1B6555B900A21659 /* XWVInvocation.swift */; };
EEE6F9A41AE02CF100A2EC89 /* XWVScripting.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEE6F9A31AE02CF100A2EC89 /* XWVScripting.swift */; };
EEE6F9A61AE02E8600A2EC89 /* XWVObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEE6F9A51AE02E8600A2EC89 /* XWVObject.swift */; };
EEE6F9A81AE02F5000A2EC89 /* XWVBindingObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEE6F9A71AE02F5000A2EC89 /* XWVBindingObject.swift */; };
Expand Down Expand Up @@ -72,7 +71,6 @@
AB023EA41A8C506600580A2A /* XWebViewTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XWebViewTests.swift; sourceTree = "<group>"; };
AB2273E41AA6FDA700F9207A /* www */ = {isa = PBXFileReference; lastKnownFileType = folder; path = www; sourceTree = "<group>"; };
ABD3E8531A8CD08300F2BAB9 /* XWVInventoryTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = XWVInventoryTest.swift; sourceTree = "<group>"; };
ABD3E85D1A8CD49F00F2BAB9 /* XWVInvocationTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XWVInvocationTest.m; sourceTree = "<group>"; };
EE0A1DD21A52775400C9E6D3 /* XWVChannel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = XWVChannel.swift; path = XWebView/XWVChannel.swift; sourceTree = "<group>"; };
EE131CA61B5F900400A9E790 /* XWVUserScript.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = XWVUserScript.swift; path = XWebView/XWVUserScript.swift; sourceTree = "<group>"; };
EE174E441A01FDDE00168D96 /* XWVInventory.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = XWVInventory.swift; path = XWebView/XWVInventory.swift; sourceTree = "<group>"; };
Expand All @@ -84,11 +82,10 @@
EE3379381AE2E298009124A4 /* XWVTestCase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = XWVTestCase.swift; sourceTree = "<group>"; };
EE33793D1AE56875009124A4 /* XWVScriptObject.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = XWVScriptObject.swift; path = XWebView/XWVScriptObject.swift; sourceTree = "<group>"; };
EE33793F1AE57566009124A4 /* XWVScriptingTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = XWVScriptingTest.swift; sourceTree = "<group>"; };
EE5BA7BC1B67DC940095AAE7 /* XWVInvocationTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = XWVInvocationTest.swift; sourceTree = "<group>"; };
EE62683519FA323900EFC3F8 /* XWebView.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = XWebView.framework; sourceTree = BUILT_PRODUCTS_DIR; };
EE62691319FA52D100EFC3F8 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = XWebView/Info.plist; sourceTree = "<group>"; };
EE62691C19FA52FC00EFC3F8 /* XWebView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = XWebView.h; path = XWebView/XWebView.h; sourceTree = "<group>"; };
EE62691D19FA52FC00EFC3F8 /* XWVInvocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = XWVInvocation.h; path = XWebView/XWVInvocation.h; sourceTree = "<group>"; };
EE62691E19FA52FC00EFC3F8 /* XWVInvocation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = XWVInvocation.m; path = XWebView/XWVInvocation.m; sourceTree = "<group>"; };
EE62692019FA52FC00EFC3F8 /* XWebView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = XWebView.swift; path = XWebView/XWebView.swift; sourceTree = "<group>"; };
EE71648B1A716C9F00078FF9 /* XWVHttpConnection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = XWVHttpConnection.h; path = XWebView/XWVHttpConnection.h; sourceTree = "<group>"; };
EE71648C1A716C9F00078FF9 /* XWVHttpConnection.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = XWVHttpConnection.m; path = XWebView/XWVHttpConnection.m; sourceTree = "<group>"; };
Expand All @@ -97,6 +94,7 @@
EE7886751A0D0CE30013A855 /* XWVLoader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = XWVLoader.swift; path = XWebView/XWVLoader.swift; sourceTree = "<group>"; };
EE92C65E1B5ACF81000FE1DA /* XWVMetaObject.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = XWVMetaObject.swift; path = XWebView/XWVMetaObject.swift; sourceTree = "<group>"; };
EE92C6601B5AD7DB000FE1DA /* XWVMetaObjectTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = XWVMetaObjectTest.swift; sourceTree = "<group>"; };
EEDF305F1B6555B900A21659 /* XWVInvocation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = XWVInvocation.swift; path = XWebView/XWVInvocation.swift; sourceTree = "<group>"; };
EEE6F9A31AE02CF100A2EC89 /* XWVScripting.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = XWVScripting.swift; path = XWebView/XWVScripting.swift; sourceTree = "<group>"; };
EEE6F9A51AE02E8600A2EC89 /* XWVObject.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = XWVObject.swift; path = XWebView/XWVObject.swift; sourceTree = "<group>"; };
EEE6F9A71AE02F5000A2EC89 /* XWVBindingObject.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = XWVBindingObject.swift; path = XWebView/XWVBindingObject.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -127,17 +125,17 @@
isa = PBXGroup;
children = (
AB2273E41AA6FDA700F9207A /* www */,
ABD3E85D1A8CD49F00F2BAB9 /* XWVInvocationTest.m */,
EE3379381AE2E298009124A4 /* XWVTestCase.swift */,
EE33793F1AE57566009124A4 /* XWVScriptingTest.swift */,
EE2F487C1AE4B8F40088AF67 /* ObjectPlugin.swift */,
EE5BA7BC1B67DC940095AAE7 /* XWVInvocationTest.swift */,
EE2F487E1AE4CD360088AF67 /* FunctionPlugin.swift */,
EE2F48801AE4CE690088AF67 /* ConstructorPlugin.swift */,
AB023EA41A8C506600580A2A /* XWebViewTests.swift */,
ABD3E8531A8CD08300F2BAB9 /* XWVInventoryTest.swift */,
EE30AAC31AD978DA006010A3 /* XWVLoaderTest.swift */,
AB023EA21A8C506600580A2A /* Supporting Files */,
EE92C6601B5AD7DB000FE1DA /* XWVMetaObjectTest.swift */,
AB023EA21A8C506600580A2A /* Supporting Files */,
);
path = XWebViewTests;
sourceTree = "<group>";
Expand Down Expand Up @@ -172,6 +170,7 @@
EE62683719FA323900EFC3F8 /* XWebView */ = {
isa = PBXGroup;
children = (
EEDF305F1B6555B900A21659 /* XWVInvocation.swift */,
EE131CA61B5F900400A9E790 /* XWVUserScript.swift */,
EE92C65E1B5ACF81000FE1DA /* XWVMetaObject.swift */,
EE71648B1A716C9F00078FF9 /* XWVHttpConnection.h */,
Expand All @@ -184,8 +183,6 @@
EE174E441A01FDDE00168D96 /* XWVInventory.swift */,
EE7886751A0D0CE30013A855 /* XWVLoader.swift */,
EE174E771A0361CB00168D96 /* xwebview.js */,
EE62691D19FA52FC00EFC3F8 /* XWVInvocation.h */,
EE62691E19FA52FC00EFC3F8 /* XWVInvocation.m */,
EEE6F9A31AE02CF100A2EC89 /* XWVScripting.swift */,
EEE6F9A51AE02E8600A2EC89 /* XWVObject.swift */,
EE33793D1AE56875009124A4 /* XWVScriptObject.swift */,
Expand All @@ -211,7 +208,6 @@
buildActionMask = 2147483647;
files = (
ABF68ECD1A6B45FC0058267B /* XWebView.h in Headers */,
ABD475E31A4129FC00F3BDEB /* XWVInvocation.h in Headers */,
EE7164911A716C9F00078FF9 /* XWVHttpServer.h in Headers */,
EE71648F1A716C9F00078FF9 /* XWVHttpConnection.h in Headers */,
);
Expand Down Expand Up @@ -317,7 +313,6 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
ABD3E85E1A8CD49F00F2BAB9 /* XWVInvocationTest.m in Sources */,
EEF27D551AE8F1F3004740CF /* XWVScripting.swift in Sources */,
EE3379391AE2E298009124A4 /* XWVTestCase.swift in Sources */,
ABD3E8541A8CD08300F2BAB9 /* XWVInventoryTest.swift in Sources */,
Expand All @@ -327,6 +322,7 @@
EE92C6621B5AD86E000FE1DA /* XWVMetaObject.swift in Sources */,
EE2F487F1AE4CD360088AF67 /* FunctionPlugin.swift in Sources */,
EE92C6611B5AD7DB000FE1DA /* XWVMetaObjectTest.swift in Sources */,
EE5BA7BD1B67DC940095AAE7 /* XWVInvocationTest.swift in Sources */,
EE2F487D1AE4B8F40088AF67 /* ObjectPlugin.swift in Sources */,
EE2F48811AE4CE690088AF67 /* ConstructorPlugin.swift in Sources */,
);
Expand All @@ -337,14 +333,14 @@
buildActionMask = 2147483647;
files = (
EEE6F9A41AE02CF100A2EC89 /* XWVScripting.swift in Sources */,
EEDF30601B6555B900A21659 /* XWVInvocation.swift in Sources */,
EE7886761A0D0CE30013A855 /* XWVLoader.swift in Sources */,
EE174E451A01FDDE00168D96 /* XWVInventory.swift in Sources */,
EEE6F9A81AE02F5000A2EC89 /* XWVBindingObject.swift in Sources */,
EE131CA71B5F900400A9E790 /* XWVUserScript.swift in Sources */,
EE7164921A716C9F00078FF9 /* XWVHttpServer.m in Sources */,
EE92C65F1B5ACF81000FE1DA /* XWVMetaObject.swift in Sources */,
EEE6F9A61AE02E8600A2EC89 /* XWVObject.swift in Sources */,
EE62692419FA52FC00EFC3F8 /* XWVInvocation.m in Sources */,
EE33793E1AE56875009124A4 /* XWVScriptObject.swift in Sources */,
EE0A1DD31A52775400C9E6D3 /* XWVChannel.swift in Sources */,
EE62692619FA52FC00EFC3F8 /* XWebView.swift in Sources */,
Expand Down
34 changes: 19 additions & 15 deletions XWebView/XWVBindingObject.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ class XWVBindingObject : XWVScriptObject {
self.object = object
objc_setAssociatedObject(object, key, self, UInt(OBJC_ASSOCIATION_ASSIGN))
startKVO()

// A trick for accessing static methods of the protocol
XWVScripting.self
}

init(namespace: String, channel: XWVChannel, arguments: [AnyObject]?) {
Expand All @@ -39,6 +42,7 @@ class XWVBindingObject : XWVScriptObject {
selector = sel
if arity == Int32(args.count) - 1 || arity < 0 {
promise = last(args) as? XWVScriptObject
args.removeLast()
}
default: break
}
Expand All @@ -47,7 +51,7 @@ class XWVBindingObject : XWVScriptObject {
if selector == "initByScriptWithArguments:" {
args = [args]
}
object = XWVInvocation.constructOnThread(channel.thread, `class`: channel.typeInfo.plugin, initializer: selector, arguments: args)
object = XWVInvocation(target: channel.typeInfo.plugin.alloc()).call(selector, withObjects: args)
objc_setAssociatedObject(object, key, self, UInt(OBJC_ASSOCIATION_ASSIGN))
startKVO()
syncProperties()
Expand All @@ -56,15 +60,15 @@ class XWVBindingObject : XWVScriptObject {
private func syncProperties() {
var script = ""
for (name, member) in filter(channel.typeInfo, { $1.isProperty }) {
let val = XWVInvocation.callOnThread(channel.thread, target: object, selector: member.getter!, arguments: nil)
let val: AnyObject! = XWVInvocation(target: object).call(member.getter!, withObjects: nil)
script += "\(namespace).$properties['\(name)'] = \(serialize(val));\n"
}
webView?.evaluateJavaScript(script, completionHandler: nil)
}

deinit {
if (object as? XWVScripting)?.finalizeForScript != nil {
XWVInvocation.callOnThread(channel.thread, target: object, selector: Selector("finalizeForScript"), arguments: nil)
XWVInvocation(target: object)[Selector("finalizeForScript")]()
}
objc_setAssociatedObject(object, key, nil, UInt(OBJC_ASSOCIATION_ASSIGN))
stopKVO()
Expand All @@ -79,10 +83,11 @@ class XWVBindingObject : XWVScriptObject {
}
if channel.queue != nil {
dispatch_async(channel.queue) {
XWVInvocation.call(object, selector: selector, arguments: args)
XWVInvocation(target: object).call(selector, withObjects: args)
}
} else {
XWVInvocation.asyncCallOnThread(channel.thread, target: object, selector: selector, arguments: args)
// FIXME: Add NSThread support back while migrate to Swift 2.0
XWVInvocation(target: object).call(selector, withObjects: args)
}
}
}
Expand All @@ -91,40 +96,39 @@ class XWVBindingObject : XWVScriptObject {
let val: AnyObject = wrapScriptObject(value)
if channel.queue != nil {
dispatch_async(channel.queue) {
XWVInvocation.call(object, selector: setter, arguments: [val])
XWVInvocation(target: object).call(setter, withObjects: [val])
}
} else {
XWVInvocation.asyncCallOnThread(channel.thread, target: object, selector: setter, arguments: [val])
// FIXME: Add NSThread support back while migrate to Swift 2.0
XWVInvocation(target: self.object)[name] = val
}
}
}

// override methods of XWVScriptObject
override func callMethod(name: String, withArguments arguments: [AnyObject]?, resultHandler: ((AnyObject!) -> Void)?) {
if let selector = channel.typeInfo[name]?.selector {
let result = XWVInvocation.call(object, selector: selector, arguments: arguments)
resultHandler?(result as? NSNumber ?? result.nonretainedObjectValue)
let result: AnyObject! = XWVInvocation(target: object).call(selector, withObjects: arguments)
resultHandler?(result)
} else {
super.callMethod(name, withArguments: arguments, resultHandler: resultHandler)
}
}
override func callMethod(name: String, withArguments arguments: [AnyObject]?) -> AnyObject! {
if let selector = channel.typeInfo[name]?.selector {
let result = XWVInvocation.call(object, selector: selector, arguments: arguments)
return result as? NSNumber ?? result.nonretainedObjectValue
return XWVInvocation(target: object).call(selector, withObjects: arguments)
}
return super.callMethod(name, withArguments: arguments)
}
override func value(forProperty name: String) -> AnyObject? {
if let getter = channel.typeInfo[name]?.getter {
let result = XWVInvocation.call(object, selector: getter, arguments: nil)
return result as? NSNumber ?? result.nonretainedObjectValue
return XWVInvocation(target: object).call(getter, withObjects: nil)
}
return super.value(forProperty: name)
}
override func setValue(value: AnyObject?, forProperty name: String) {
if let setter = channel.typeInfo[name]?.setter {
XWVInvocation.call(object, selector: setter, arguments: [value!])
XWVInvocation(target: object)[name] = value
} else {
assert(channel.typeInfo[name] == nil, "Property '\(name)' is readonly")
super.setValue(value, forProperty: name)
Expand All @@ -136,7 +140,7 @@ class XWVBindingObject : XWVScriptObject {
var prop = keyPath
if channel.typeInfo[prop] == nil {
if let scriptNameForKey = object.dynamicType.scriptNameForKey {
prop = scriptNameForKey((prop as NSString).UTF8String) ?? prop
prop = prop.withCString(scriptNameForKey) ?? prop
}
assert(channel.typeInfo[prop] != nil)
}
Expand Down

0 comments on commit 3d1e08a

Please sign in to comment.