diff --git a/Build/Products/Debug-iphonesimulator/libdsbridge.a b/Build/Products/Debug-iphonesimulator/libdsbridge.a index 88184e3..75a3916 100644 Binary files a/Build/Products/Debug-iphonesimulator/libdsbridge.a and b/Build/Products/Debug-iphonesimulator/libdsbridge.a differ diff --git a/README.md b/README.md index 083a713..417c621 100644 --- a/README.md +++ b/README.md @@ -142,10 +142,29 @@ In order to be compatible with IOS , we make the following convention on Object 2. For asynchronous API. -**` (void) handler:(id) arg :(void (^)( id result,BOOL complete))completionHandler)`** + **` (void) handler:(id) arg :(void (^)( id result,BOOL complete))completionHandler)`** -> Attention: API name can't start with "init", because it is reserved in OC class. -> + > Attention: API name can't start with "init", because it is reserved in OC class. + +## Using in Swift + +In Swift, you should declare APIs as follows: + +``` +//MUST USE "_" to ignore the first argument name explicitly。 +@objc func testSyn( _ arg:String) -> String { + return String(format:"%@[Swift sync call:%@]", arg, "test") +} + +@objc func testAsyn( _ arg:String, handler: (String, Bool)->Void) { + handler(String(format:"%@[Swift async call:%@]", arg, "test"), true) +} +``` + +Two points you should keep in mind: + +- Must add "@objc" to Swift API. +- Must use "_" to ignore the first argument name explicitly ## Namespace diff --git a/dsbridge.xcodeproj/project.pbxproj b/dsbridge.xcodeproj/project.pbxproj index 4524643..70ff8b2 100644 --- a/dsbridge.xcodeproj/project.pbxproj +++ b/dsbridge.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 8142EA1E214212E700BEE5C0 /* JsApiTestSwift.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8142EA1D214212E700BEE5C0 /* JsApiTestSwift.swift */; }; 815612EB2020304600C4F5CD /* InternalApis.m in Sources */ = {isa = PBXBuildFile; fileRef = 815612EA2020304600C4F5CD /* InternalApis.m */; }; 815612EE202041B000C4F5CD /* DSCallInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 815612ED202041B000C4F5CD /* DSCallInfo.m */; }; 815612F12022E42D00C4F5CD /* JsEchoApi.m in Sources */ = {isa = PBXBuildFile; fileRef = 815612F02022E42D00C4F5CD /* JsEchoApi.m */; }; @@ -55,6 +56,8 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 8142EA1C214212E600BEE5C0 /* dsbridgedemo-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "dsbridgedemo-Bridging-Header.h"; sourceTree = ""; }; + 8142EA1D214212E700BEE5C0 /* JsApiTestSwift.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JsApiTestSwift.swift; sourceTree = ""; }; 815612E92020304600C4F5CD /* InternalApis.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InternalApis.h; sourceTree = ""; }; 815612EA2020304600C4F5CD /* InternalApis.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = InternalApis.m; sourceTree = ""; }; 815612EC202041B000C4F5CD /* DSCallInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DSCallInfo.h; sourceTree = ""; }; @@ -163,6 +166,8 @@ 818F0BCF1E1A820B00679925 /* test.html */, 815612EF2022E42D00C4F5CD /* JsEchoApi.h */, 815612F02022E42D00C4F5CD /* JsEchoApi.m */, + 8142EA1D214212E700BEE5C0 /* JsApiTestSwift.swift */, + 8142EA1C214212E600BEE5C0 /* dsbridgedemo-Bridging-Header.h */, ); path = dsbridgedemo; sourceTree = ""; @@ -236,6 +241,7 @@ 818F0B9D1E18C0AA00679925 = { CreatedOnToolsVersion = 8.2.1; DevelopmentTeam = XTLLEQZMD7; + LastSwiftMigration = 0940; ProvisioningStyle = Automatic; }; }; @@ -297,6 +303,7 @@ 818F0BA51E18C0AA00679925 /* AppDelegate.m in Sources */, 815612F12022E42D00C4F5CD /* JsEchoApi.m in Sources */, 818F0BA21E18C0AA00679925 /* main.m in Sources */, + 8142EA1E214212E700BEE5C0 /* JsApiTestSwift.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -447,12 +454,17 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + DEFINES_MODULE = YES; DEVELOPMENT_TEAM = XTLLEQZMD7; INFOPLIST_FILE = dsbridgedemo/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = wendu.dsbridgedemo.xx; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "dsbridgedemo/dsbridgedemo-Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 3.0; }; name = Debug; }; @@ -460,12 +472,16 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + DEFINES_MODULE = YES; DEVELOPMENT_TEAM = XTLLEQZMD7; INFOPLIST_FILE = dsbridgedemo/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = wendu.dsbridgedemo.xx; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "dsbridgedemo/dsbridgedemo-Bridging-Header.h"; + SWIFT_VERSION = 3.0; }; name = Release; }; diff --git a/dsbridge.xcodeproj/xcuserdata/du.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/dsbridge.xcodeproj/xcuserdata/du.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist index 2da46da..bf198cb 100644 --- a/dsbridge.xcodeproj/xcuserdata/du.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +++ b/dsbridge.xcodeproj/xcuserdata/du.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -218,7 +218,7 @@ ignoreCount = "0" continueAfterRunningActions = "No" filePath = "dsbridge/DWKWebView.m" - timestampString = "557920558.736751" + timestampString = "557979526.664736" startingColumnNumber = "9223372036854775807" endingColumnNumber = "9223372036854775807" startingLineNumber = "256" @@ -234,7 +234,7 @@ ignoreCount = "0" continueAfterRunningActions = "No" filePath = "dsbridge/DWKWebView.m" - timestampString = "557920558.736854" + timestampString = "557979526.66483" startingColumnNumber = "9223372036854775807" endingColumnNumber = "9223372036854775807" startingLineNumber = "251" @@ -250,7 +250,7 @@ ignoreCount = "0" continueAfterRunningActions = "No" filePath = "dsbridge/DWKWebView.m" - timestampString = "557920558.736935" + timestampString = "557979526.664907" startingColumnNumber = "9223372036854775807" endingColumnNumber = "9223372036854775807" startingLineNumber = "250" @@ -266,7 +266,7 @@ ignoreCount = "0" continueAfterRunningActions = "No" filePath = "dsbridge/DWKWebView.m" - timestampString = "557920558.737004" + timestampString = "557979526.664975" startingColumnNumber = "9223372036854775807" endingColumnNumber = "9223372036854775807" startingLineNumber = "259" @@ -282,7 +282,7 @@ ignoreCount = "0" continueAfterRunningActions = "No" filePath = "dsbridge/DWKWebView.m" - timestampString = "557920558.737074" + timestampString = "557979526.665044" startingColumnNumber = "9223372036854775807" endingColumnNumber = "9223372036854775807" startingLineNumber = "248" @@ -298,7 +298,7 @@ ignoreCount = "0" continueAfterRunningActions = "No" filePath = "dsbridge/DWKWebView.m" - timestampString = "557920558.737144" + timestampString = "557979526.665114" startingColumnNumber = "9223372036854775807" endingColumnNumber = "9223372036854775807" startingLineNumber = "267" @@ -314,7 +314,7 @@ ignoreCount = "0" continueAfterRunningActions = "No" filePath = "dsbridge/DWKWebView.m" - timestampString = "557920558.737913" + timestampString = "557979526.665176" startingColumnNumber = "9223372036854775807" endingColumnNumber = "9223372036854775807" startingLineNumber = "264" @@ -323,5 +323,21 @@ landmarkType = "7"> + + + + diff --git a/dsbridgedemo/JsApiTestSwift.swift b/dsbridgedemo/JsApiTestSwift.swift new file mode 100644 index 0000000..f3c301e --- /dev/null +++ b/dsbridgedemo/JsApiTestSwift.swift @@ -0,0 +1,22 @@ +// +// JsApiTestSwift.swift +// dsbridgedemo +// +// Created by du on 2018/9/7. +// Copyright © 2018年 杜文. All rights reserved. +// + +import Foundation + +class JsApiTestSwift: NSObject { + + //MUST use "_" to ignore the first argument name explicitly。 + @objc func testSyn( _ arg:String) -> String { + return String(format:"%@[Swift sync call:%@]", arg, "test") + } + + @objc func testAsyn( _ arg:String, handler: (String, Bool)->Void) { + handler(String(format:"%@[Swift async call:%@]", arg, "test"), true) + } + +} diff --git a/dsbridgedemo/ViewController.m b/dsbridgedemo/ViewController.m index d2155f2..4b8f12b 100644 --- a/dsbridgedemo/ViewController.m +++ b/dsbridgedemo/ViewController.m @@ -9,6 +9,7 @@ #import "ViewController.h" #import #import "JsEchoApi.h" +#import "dsbridgedemo-Swift.h" @interface ViewController () @end @@ -22,10 +23,13 @@ - (void)viewDidLoad { // register api object without namespace [dwebview addJavascriptObject:[[JsApiTest alloc] init] namespace:nil]; + // register api object without namespace + [dwebview addJavascriptObject:[[ JsApiTestSwift alloc] init] namespace:@"swift"]; + // register api object with namespace "echo" [dwebview addJavascriptObject:[[JsEchoApi alloc] init] namespace:@"echo"]; - // open debug mode + // open debug mode, Release mode should disable this. [dwebview setDebugMode:true]; [dwebview customJavascriptDialogLabelTitles:@{@"alertTitle":@"Notification",@"alertBtn":@"OK"}]; diff --git a/dsbridgedemo/dsbridgedemo-Bridging-Header.h b/dsbridgedemo/dsbridgedemo-Bridging-Header.h new file mode 100644 index 0000000..1b2cb5d --- /dev/null +++ b/dsbridgedemo/dsbridgedemo-Bridging-Header.h @@ -0,0 +1,4 @@ +// +// Use this file to import your target's public headers that you would like to expose to Swift. +// + diff --git a/dsbridgedemo/test.html b/dsbridgedemo/test.html index f4afe1e..d2533f8 100644 --- a/dsbridgedemo/test.html +++ b/dsbridgedemo/test.html @@ -32,6 +32,8 @@
Synchronous call
Asynchronous call
+
Syn call (swift)
+
Async call(swift)
Sync call without argument
Async call without argument
echo.syn
@@ -58,6 +60,15 @@ }) } +function callSynSwift() { + alert(dsBridge.call("swift.testSyn", "hello")) +} + +function callAsynSwift() { + dsBridge.call("swift.testAsyn","hello", function (v) { + alert(v) + }) +} function callAsyn_() { for (var i = 0; i < 2000; i++) { diff --git a/readme-chs.md b/readme-chs.md index e0f6a4d..eedd674 100644 --- a/readme-chs.md +++ b/readme-chs.md @@ -114,7 +114,7 @@ pod "dsBridge" **`(id) handler:(id) msg`** - 参数可以是任何类型, 但是返回值类型不能为 **void**. + 参数可以是任何类型, 但是返回值类型不能为 **void。** **如果不需要参数,也必须声明**,声明后不适用就行。 2. 异步 API. @@ -125,6 +125,26 @@ pod "dsBridge" +## 在Swift中使用 + +在 Swift中,你应该按照如下方式声明APIs: + +``` +//必须给第一个参数前添加下划线"_"来显式忽略参数名。 +@objc func testSyn( _ arg:String) -> String { + return String(format:"%@[Swift sync call:%@]", arg, "test") +} + +@objc func testAsyn( _ arg:String, handler: (String, Bool)->Void) { + handler(String(format:"%@[Swift async call:%@]", arg, "test"), true) +} +``` + +有两点必须注意: + +- 必须给Swift API添加 "@objc" 标注。 +- 必须给第一个参数前添加下划线"_"来显式忽略参数名 + ## 命名空间 命名空间可以帮助你更好的管理API,这在API数量多的时候非常实用,比如在混合应用中。DSBridge (>= v3.0.0) 支持你通过命名空间将API分类管理,并且命名空间支持多级的,不同级之间只需用'.' 分隔即可。