如何在Objective-C代码中使用导入的Swift协议和类?



我有一个项目,桥Swift和Objective-C两种方式,和:

我在Swift文件中定义了一个@objc协议:

@objc protocol Plugin {
@objc func onDevicePackageReceived(np: NetworkPackage) -> Bool
}

所有实现此协议的类也在Swift中定义,例如:

@objc class Ping : NSObject, Plugin {

@objc func onDevicePackageReceived(np: NetworkPackage) -> Bool {
if (np._Type == PACKAGE_TYPE_PING) {
connectedDevicesViewModel.showPingAlert()
return true
}
return false
}

@objc func sendPing(deviceId: String) -> Void {
let np: NetworkPackage = NetworkPackage(type: PACKAGE_TYPE_PING)
let device: Device = backgroundService._devices[deviceId] as! Device
device.send(np, tag: Int(PACKAGE_TAG_PING))
}
}

我已经将自动生成的桥接头文件导入到我想使用Plugin接口的Objective-C.m文件中:

#import "My_App_Name-Swift.h"

桥接头肯定工作得很好,因为其他桥接的Swift代码都在工作。

我还在Objective-C.h头文件中转发声明了协议:

@protocol Plugin;

现在,在Objective-C.m文件中,我有一个NSMutableDictionary,_plugins的值是那些在Swift中定义的实现Plugin协议的类的对象。我想遍历每个对象并调用协议中定义的onDevicePackageReceived(np: NetworkPackage)函数,我计划通过确认对象到实现了该函数的Plugin协议来实现这一点。

for (Plugin* plugin in [_plugins allValues]) {
[plugin onDevicePackageReceived:np];
}

但是它一直抛出错误Use of undeclared identifier 'Plugin'

我检查了自动生成的头文件,它似乎正确地桥接了它:

SWIFT_PROTOCOL("_TtP16KDE_Connect_Test6Plugin_")
@protocol Plugin
- (BOOL)onDevicePackageReceivedWithNp:(NetworkPackage * _Nonnull)np        SWIFT_WARN_UNUSED_RESULT;
@end

作为进一步的参考,字典plugins过去是在Swift中声明的,在Swift中相同的For循环工作得很好:

for plugin in plugins.values {
(plugin as! Plugin).onDevicePackageReceived(np: np)
}

所以本质上,plugins现在已经被移动到Objective-C,我试图复制这个精确的for循环在Object-C中,唯一的区别是协议Plugin和所有实现它的类都是在Swift中声明的,所以他们需要被正确导入到Objective-C。

这个语法对于ObjC:

中的协议是不正确的
for (Plugin* plugin in [_plugins allValues]) {

没有指向协议存在的指针。ObjC不像Swift那样具有存在类型(即包含符合协议的类型的框)。

我相信你的意思是:

for (id<Plugin> plugin in [_plugins allValues]) {

这是一个符合Plugin.">

的任意ObjC对象(id

)。有关ObjC协议语法的详细信息,请参见Objective-C编程中的使用协议。

关于Swift协议存在性的详细信息,请参见《Swift编程语言》中的协议类型(Protocols as Types)。

如果你不想写objc代码,另一个选择是为你的objc类创建快速扩展。
例如LegacyPluginHolder,添加新文件LegacyPluginHolder+Extensions.swift并创建扩展名:

extension LegacyPluginHolder {
@objc func notifyAllPlugins(package: NetworkPackage) {
// Your swift code moves here
}
}

LegacyPluginHolder.m中,你可以使用这样的扩展:

[self notifyAllPluginsWithPackage:np]

相关内容

  • 没有找到相关文章

最新更新