如何在 Objective-C 代码中使用导入的 Swift 协议和 类?
How to use imported Swift protocols and classes in Objective-C code?
我有一个连接 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))
}
}
我已经将自动生成的桥接 header 文件导入到 Objective-C .m
文件中,我想在以下位置使用 Plugin
接口:
#import "My_App_Name-Swift.h"
桥接 header 肯定工作正常,因为其他桥接 Swift 代码正在工作。
我还在 Objective-C .h
header 文件中转发声明了该协议:
@protocol Plugin;
现在,在 Objective-C .m
文件中,我有一个 NSMutableDictionary,_plugins
的值是 类 定义的 objects在 Swift 中实现 Plugin
协议。我想遍历每个 objects 并调用协议中定义的 onDevicePackageReceived(np: NetworkPackage)
函数,我计划通过确认 objects 到 Plugin
协议来实现实现了该功能。
for (Plugin* plugin in [_plugins allValues]) {
[plugin onDevicePackageReceived:np];
}
但它一直抛出错误 Use of undeclared identifier 'Plugin'
。
我检查了自动生成的 header 文件,它似乎已正确桥接:
SWIFT_PROTOCOL("_TtP16KDE_Connect_Test6Plugin_")
@protocol Plugin
- (BOOL)onDevicePackageReceivedWithNp:(NetworkPackage * _Nonnull)np SWIFT_WARN_UNUSED_RESULT;
@end
为了进一步参考,字典 plugins
曾经在 Swift 中声明,其中相同的 for 循环在 Swift 中工作得很好:
for plugin in plugins.values {
(plugin as! Plugin).onDevicePackageReceived(np: np)
}
所以基本上,plugins
现在已经移动到 Objective-C,我正在尝试在 Object-C 中复制这个精确的 for 循环,唯一的区别是协议Plugin
和实现它的所有 类 都在 Swift 中声明,因此需要将它们正确导入到 Objective-C.
此语法对于 ObjC 中的协议不正确:
for (Plugin* plugin in [_plugins allValues]) {
没有指向协议存在的指针。 ObjC 没有像 Swift 这样的存在类型(即包含符合协议的类型的框)。
我相信你的意思是:
for (id<Plugin> plugin in [_plugins allValues]) {
这是“符合插件的任意 ObjC 对象 (id
)。”
有关 ObjC 协议语法的详细信息,请参阅 Objective-C 编程中的 Working with Protocols。
请参阅 Swift 编程语言中的 Protocols as Types,了解有关 Swift 协议存在性(与协议本身不同)的详细信息。
如果您不想编写 objc 代码,另一种选择是为您的 objc swift 创建扩展 class。
例如,如果它被称为 LegacyPluginHolder
,添加新文件 LegacyPluginHolder+Extensions.swift
并创建扩展名:
extension LegacyPluginHolder {
@objc func notifyAllPlugins(package: NetworkPackage) {
// Your swift code moves here
}
}
在 LegacyPluginHolder.m
中,您可以像这样使用扩展程序:
[self notifyAllPluginsWithPackage:np]
我有一个连接 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))
}
}
我已经将自动生成的桥接 header 文件导入到 Objective-C .m
文件中,我想在以下位置使用 Plugin
接口:
#import "My_App_Name-Swift.h"
桥接 header 肯定工作正常,因为其他桥接 Swift 代码正在工作。
我还在 Objective-C .h
header 文件中转发声明了该协议:
@protocol Plugin;
现在,在 Objective-C .m
文件中,我有一个 NSMutableDictionary,_plugins
的值是 类 定义的 objects在 Swift 中实现 Plugin
协议。我想遍历每个 objects 并调用协议中定义的 onDevicePackageReceived(np: NetworkPackage)
函数,我计划通过确认 objects 到 Plugin
协议来实现实现了该功能。
for (Plugin* plugin in [_plugins allValues]) {
[plugin onDevicePackageReceived:np];
}
但它一直抛出错误 Use of undeclared identifier 'Plugin'
。
我检查了自动生成的 header 文件,它似乎已正确桥接:
SWIFT_PROTOCOL("_TtP16KDE_Connect_Test6Plugin_")
@protocol Plugin
- (BOOL)onDevicePackageReceivedWithNp:(NetworkPackage * _Nonnull)np SWIFT_WARN_UNUSED_RESULT;
@end
为了进一步参考,字典 plugins
曾经在 Swift 中声明,其中相同的 for 循环在 Swift 中工作得很好:
for plugin in plugins.values {
(plugin as! Plugin).onDevicePackageReceived(np: np)
}
所以基本上,plugins
现在已经移动到 Objective-C,我正在尝试在 Object-C 中复制这个精确的 for 循环,唯一的区别是协议Plugin
和实现它的所有 类 都在 Swift 中声明,因此需要将它们正确导入到 Objective-C.
此语法对于 ObjC 中的协议不正确:
for (Plugin* plugin in [_plugins allValues]) {
没有指向协议存在的指针。 ObjC 没有像 Swift 这样的存在类型(即包含符合协议的类型的框)。
我相信你的意思是:
for (id<Plugin> plugin in [_plugins allValues]) {
这是“符合插件的任意 ObjC 对象 (id
)。”
有关 ObjC 协议语法的详细信息,请参阅 Objective-C 编程中的 Working with Protocols。
请参阅 Swift 编程语言中的 Protocols as Types,了解有关 Swift 协议存在性(与协议本身不同)的详细信息。
如果您不想编写 objc 代码,另一种选择是为您的 objc swift 创建扩展 class。
例如,如果它被称为 LegacyPluginHolder
,添加新文件 LegacyPluginHolder+Extensions.swift
并创建扩展名:
extension LegacyPluginHolder {
@objc func notifyAllPlugins(package: NetworkPackage) {
// Your swift code moves here
}
}
在 LegacyPluginHolder.m
中,您可以像这样使用扩展程序:
[self notifyAllPluginsWithPackage:np]