我将现有的自定义插件转换为Swift语言:
(位于Plugins/CustomPluginInSwift.swift
下)
import Foundation
class CustomPluginInSwift : CDVPlugin {
func getSettings(command: CDVInvokedUrlCommand) {
println("CustomPluginInSwift :: getSettings is called")
var pluginResult = CDVPluginResult(status: CDVCommandStatus_OK)
commandDelegate.sendPluginResult(pluginResult, callbackId:command.callbackId)
}
}
我有两个问题:
CDVPlugin
未找到CustomPluginInSwift
:CDVPlugin类CustomPluginInSwift(pluginName:CustomPluginInSwift)不存在
我离开了config.xml
,但它没有按预期工作。
我的问题在哪里?
答案 0 :(得分:27)
如前所述,您必须添加包含
的bridging-header.h文件#import <Cordova/CDV.h>
此外,您还需要在XCode项目属性中添加桥接头路径 - > Build Build-&gt; Objective-C Bridging Header。例如:
your-app-name/plugins/com.plugin.example/bridging-header.h
此外,为了让Objective-C看到相同的插件类名,您需要将@objc映射添加到类声明中。它可以与swift类名本身相同,也可以是不同的名称。在这个例子中,“HWPCustomPluginInSwift”将是Objective-C(和Javascript)最终会看到的内容:
@objc(HWPCustomPluginInSwift) class CustomPluginInSwift : CDVPlugin {
然后config.xml文件中的功能节点应如下所示:
<feature name="CustomPluginInSwift">
<param name="ios-package" value="HWPCustomPluginInSwift" />
</feature>
答案 1 :(得分:10)
CDVPlugin
未找到
第一次创建swift文件时,Xcode会要求您生成
带有空内容的 <your app name>-Bridging-Header.h
标题:
//
// Use this file to import your target's public headers that you would like to expose to Swift.
//
在此标题中添加:
#import <Cordova/CDVPlugin.h>
之后清理您的项目。如果您没有此标题 - 请创建它。
CDVPlugin类CustomPluginInSwift(pluginName:CustomPluginInSwift)不存在
[第1步]
是的,因为Swift使用_TtC
( Type To Class )前缀和类索引以及以下模板:
_TtC8<AppName><index#><PluginName>
如何知道什么是正确的索引?
[第2步]
当您启动CustomPluginInSwift
类的实例时,例如:
var temp:CustomPluginInSwift = CustomPluginInSwift()
,Swift会将新的类名添加到<AppName>-Swift.h
标题中。问题是你在项目中看不到这个标题。
如何找到它?
~/Library/Developer/Xcode/DerivedData/<AppName>-hbgwavxfqvhwxzagxhgzjvsdrkjk
)cd ~/Library/Developer/Xcode/DerivedData/<AppName>-hbgwavxfqvhwxzagxhgzjvsdrkjk
cd Build/Intermediates/<App name>.build/Debug-iphoneos/<App name>.build/DerivedSources/
您可以在其中找到名为<App name>-Swift.h
的文件,其中包含以下内容:
/* ... */
SWIFT_CLASS("_TtC8Wanameet14CustomPluginInSwift")
@interface CustomPluginInSwift : CDVPlugin
- (void)getSettings:(CDVInvokedUrlCommand *)command;
- (instancetype)initWithWebView:(UIWebView *)theWebView OBJC_DESIGNATED_INITIALIZER;
- (instancetype)init OBJC_DESIGNATED_INITIALIZER;
@end
/* ... */
所以我们得到了正确的名字:_TtC8Wanameet14CustomPluginInSwift
[第3步]
现在,转到config.xml
并从:
<feature name="CustomPluginInSwift">
<param name="ios-package" value="CustomPluginInSwift" />
</feature>
为:
<feature name="MeeterCalendar">
<param name="ios-package" value="_TtC8Wanameet14CustomPluginInSwift" />
</feature>
多数,
希望能节省时间,
在cordova 3.5
+ xCode6.1
考虑项目中有Plugins
文件夹(由Cordova生成)。
我们使用以下内容创建新的swift文件MyPlugin.swift
:
@objc(HWPMyPlugin) class MyPlugin : CDVPlugin { // see @tsubik answer
/* ... */
}
我们解析javascript请求并立即返回答案的方法示例:
func someMethod(command: CDVInvokedUrlCommand){
println("MyPlugin :: someMethod is called")
let callbackId:String = command.callbackId
var obj:AnyObject = command.arguments[0] as AnyObject!
var eventStructure:AnyObject = obj["eventStructure"]
var eventId:String = eventStructure["_id"] as AnyObject! as String
println("MyPlugin :: someMethod :: _id: \(eventId) ")
self.commandDelegate.runInBackground({
// 'jw' is some class
var data:NSData = jw.toJson()
var str:String = jw.toJsonString(data)
var obj:JSONObject = jw.getJSONObjectFromNSData(data)
println("sampleList as String: \(str)")
var pluginResult:CDVPluginResult = CDVPluginResult(status: CDVCommandStatus_OK, messageAsDictionary: obj)
self.commandDelegate.sendPluginResult(pluginResult, callbackId:command.callbackId)
})
}
方法示例我们返回空的callabck并在一段时间后返回答案:
当您尝试通过异步方式在本机端获取某些数据时,我使用了很多此方法表单:
protocol AccountLoaderListenerItf {
func onAccountsDone(data:NSData)
}
@objc(HWPMyPlugin) class MyPlugin : CDVPlugin, AccountLoaderListenerItf {
var mCalendarAccountsCallbackContext:String?
func getCalendarAccounts( command: CDVInvokedUrlCommand ){
println("MyPlugin :: getCalendarAccounts is called")
self.mCalendarAccountsCallbackContext = command.callbackId
self.commandDelegate.runInBackground({
var all:AccountLoaderListenerItf = self
var accounts = MyAccounts(accLoader: all)
accounts.populateFromCalendars()
var pluginResult:CDVPluginResult = CDVPluginResult(status:CDVCommandStatus_NO_RESULT)
pluginResult.setKeepCallbackAsBool(true)
self.commandDelegate.sendPluginResult(pluginResult, callbackId:command.callbackId)
})
} // func
/* .... */
func onAccountsDone(data:NSData){
if self.mCalendarAccountsCallbackContext != nil {
var list:JSONArray = WmUtils.getJSONArrayFromNSData(data) // dummy data
var pluginResult:CDVPluginResult = CDVPluginResult(status: CDVCommandStatus_OK, messageAsArray: list)
pluginResult.setKeepCallbackAsBool(false)
self.commandDelegate.sendPluginResult(pluginResult, callbackId:self.mCalendarAccountsCallbackContext)
}
}
}