article
article copied to clipboard
使用swift 扩展weex module
Swift In Weex
参考之前 Swift和Objective-C 混编的文档
Weex iOS SDK 是使用 Objective-C,结合部分C实现的,
引入 Swift,需要混编,直接进入正题
一个例子
SDK集成 参考
使用 Swift 进行 module 扩展
因为 module 暴露 method 是通过Objective-C宏来做的,调用的时候是通过反射,所以Swift扩展 module 通过extension Objective-C的类,以下操作,可以直接在weex 的iOS playground 中进行
-
新建
WXSwiftTestModule.h/m和WXSwiftTestModule.swift文件, 在新建Swift文件的时候会提示选择
Create Bridging Header, 因为我们要在 Swift 中访问Objective-C的一些类,正是通过这个 header暴露 OC 的类给 Swift,header 格式为yourTarget-Bridging-Header.h,我这里创建完header文件名称为:WeexDemo-Bridging-Header.h -
WXSwiftTestModule.h/m中实现-
WXSwiftTestModule.h 中
#import <Foundation/Foundation.h> #import <WeexSDK/WeexSDK.h> @interface WXSwiftTestModule : NSObject <WXModuleProtocol> @end -
WXSwiftTestModule.m 中
WeexDemo-Swift.h 这个文件需要编译一下才可以搜索到,具体的路径
weex/ios/playground/DerivedData/WeexDemo/Build/Intermediates/WeexDemo.build/Debug-iphonesimulator/WeexDemo.build/DerivedSources/WeexDemo-Swift.h路径具体需要根据自己工程而定
#import "WXSwiftTestModule.h" #import "WeexDemo-Swift.h" // Swift类和方法 被 `Objective-C` 识别需要导入 @implementation WXSwiftTestModule #pragma clang diagnostic push //关闭unknow selector的warrning #pragma clang diagnostic ignored "-Wundeclared-selector" WX_EXPORT_METHOD(@selector(printSome:callback:)) //Swift 中定义的方法,XCode 转换成的最终的方法名称,在`WeexDemo-Swift.h`里面查看 #pragma clang diagnostic pop @end
-
-
Swift 中实现 扩展 OC 的类
WXSwiftTestModule,增加了一个方法,这个方法就是我们要暴露出来,在 js 中可以调到的-
WXSwiftTestModule.swift
import Foundation public extension WXSwiftTestModule { public func printSome(someThing:String, callback:WXModuleCallback) { print(someThing) callback(someThing) } }WXSwiftTestModule和WXModuleCallback因为是 OC 的,需要在WeexDemo-Bridging-Header中暴露 -
WeexDemo-Bridging-Header.h中
// // Use this file to import your target's public headers that you would like to expose to Swift. // #import "WXSwiftTestModule.h" #import "WeexSDK.h"至此这个使用 Swift 开发的简单的 module 已经完成
module 使用
-
注册 module
[WXSDKEngine registerModule:@"swifter" withClass:[WXSwiftTestModule class]]; -
we 文件中使用
<template> <text>Swift Module</text> </template> <script> require('weex-components'); module.exports = { data: { }, ready: function() { var swifter = require('@weex-module/swifter'); swifter.printSome("https://www.taobao.com",function(param){ nativeLog(param); }); } }; </script> -
完整根据这个代码来的,运行后发现找不到这个方法,提示:
[fg0,128,0; <Weex>[debug]WXJSCoreBridge.m:135, Calling native... instance:1, tasks:( { args = ( "https://www.taobao.com", 2 ); method = printSome; module = swifter; } ), callback:-1 [;
@Bijiabo 这个提示是 JS调用native的一个日志,可以参考一下这个例子 swiftExample
@acton393 sorry,复制错了内容,提示是这样的:
2016-12-08 23:29:07.413 learnProject [60197:2137501] [fg255,0,0; <Weex>[error]WXMonitor.m:190, Module:swifter, method:printSome doesn't exist [;
如果非http请求的图片资源而是项目中内部的图片资源,ios是如何读取的
@lenvonsam 可以参考WXURLRewriteProtocol 这个协议,有默认实现
请问那个 WeexDemo-Swift 是源自哪里的?
@15130886370 文档中有链接
按照文档所说的,
- 添加WXSwiftTestModule.h/.m文件,并在Bridging-Header.h中import WXSwiftTestModule.h
- 在WXSwiftTestModule.m中添加WX_EXPORT_METHOD(@selector(method:))方法,并import project-swift.h
- 创建swift file,通过extension的方式扩充method方法 但是仍然提示找不到注册的module的方法 method:method for module: module doesn't exist, maybe it has not been registered [;
@XImoon you have to import the XCode generated header files. Something like "#import "ProjectName-Swift.h" Also in this file you can find the generated method names for the WX_EXPORT_METHOD. it's located somewhere under "~/Library/Developer/XCode/DerivedData/......./DerivedData/ProjectName-Swift.h" It will be generated after you hit build.
@xeha-gmbh I think you misunderstand me. It's not me but the compiler can not find the method. I'm confused somewhere I lost or did mistake, so that the complier can't excute even relate the method I write. Finally, I completed it using OC, which call a swift method to finish the action. But I still really wonder know what's wrong with me as the article says.
@XImoon 和你遇到同样的问题,通过swift的extension方式提示找不到方式,完全使用OC代码实现是ok的,不知道哪个步骤不对
找到坑了,现在用的是swift 4.0,默认去掉了自动增加的 @objc,swift代码改成这样就没问题了
public extension WXEventModule {
@objc public func openURL(_ url:String) {
var newUrl:String = url;
if url.hasPrefix("//") {
newUrl = String.init(format: "http://%@", url);
}else if !url.hasPrefix("http") {
//relative path
newUrl = (URL.init(string: url, relativeTo: weexInstance.scriptURL)!.absoluteString)
}
let controller:URLViewController = URLViewController()
controller.url = URL.init(string: newUrl)
weexInstance.viewController.navigationController?.pushViewController(controller, animated:true)
}
}
@zhongdom 这个问题我后来直接用oc代码实现,然后调用swift的方法……非常感谢解惑,我以为这个坑就这么掉下去爬不出来了
请问有没有swift weex component相关的代码 成员方法报 is not function 已经通过WX_EXPORT_METHOD暴露出去 oc写法是成功的
@XImoon @thecorsair 我也是遇到这个问题,我是 OC/Swift 新手,经验不太足,花了一整天测试,最后找到一个办法。
一开始试了上面提到的 @objc 办法,但在我这里并不生效,我尝试了不带任何参数的函数签名,通过 WX_EXPORT_METHOD 暴露,是完全正常的,所以就定位问题到 “函数签名” 上了。
Weex Vue Code:
webView.open(url, callback)
*-Swift.h 头文件里的签名形式
- (void)open:(NSString * _Nonnull)url :(SWIFT_NOESCAPE void (^ _Nonnull)(id _Nullable))callback;
.swift 文件里的 extension 扩展实现(特别注意参数前面的 _ )
public func open(_ url: String, _ callback: WXModuleCallback)
.m 文件里的暴露(你的函数是几个参数,就几个冒号)
WX_EXPORT_METHOD(@selector(open::))
应该写对了函数签名,这个问题就可以解决,但我就没有花更多时间去深挖了,目前能让项目进行下去就 OK。
希望对大家有帮助。
更新一个在swift4下面的解决方法 在方法前加入'@objc(printSome::)',与.m的selector方法名一样 @objc(printSome::) func printSome(_ someThing:String, _ callback:WXModuleCallback) { print(someThing) callback(someThing) }
试了你的方法完美解决,谢谢