【问题标题】:Implementing an Objective-C protocol in Swift在 Swift 中实现一个 Objective-C 协议
【发布时间】:2018-08-24 12:59:33
【问题描述】:

我有一个在 Objective-C 中定义的协议,例如:

@protocol MyProtocol <NSObject>
- (void)doStuffWithDictionary:(NSDictionary*)dict 
                    andString:(NSString*)str1
            andOptionalString:(NSString*)str2
             andOptionalArray:(NSArray*)arr
                     callback:(void (^)(id result))onSuccess;
@end

...我正在尝试在 Swift 中定义一个实现此协议的类,例如:

class MyImpl : Operation, MyProtocol {
    func doStuff(withDictionary dict: [AnyHashable : Any]!, 
                      andString str1: String!, 
              andOptionalString str2: String? = nil, 
                andOptionalArray arr: NSArray? = nil, 
                  callback onSuccess: ((Any?) -> Void)! {
        ...
    }
}

但是,我遇到了以下方面的构建错误:

Type 'MyImpl' does not conform to protocol 'MyProtocol'
note: candidate has non-matching type '([AnyHashable : Any]!, String!, String?, NSArray?, ((Any?) -> Void)!'
    func doStuff(withDictionary dict: [AnyHashable : Any]!, andString str1: String!, andOptionalString str2: String? = nil, andOptionalArray arr: NSArray? = nil, callback onSuccess: ((Any?) -> Void)!

它似乎对andOptionalArray arr: NSArray? = nil 参数感到不安。这里使用的正确语法是什么?

【问题讨论】:

  • 进入定义协议的头文件,在左上角的“Related Items”弹出框中选择“Generated Interface”。这将向您显示您必须实现的确切 Swift 方法签名。

标签: objective-c swift syntax protocols


【解决方案1】:

我将你的协议放在一个项目中,并在&lt;ProjectName&gt;-Bridging-Header.h 中导入,Auto Complete 建议使用以下语法:

public func doStuff(with dict: [AnyHashable : Any],
               andString str1: String,
       andOptionalString str2: String,
         andOptionalArray arr: [Any],
           callback onSuccess: @escaping (Any) -> Void) {
}

如果您希望将String[Any] 作为可选导入,您需要在Objective-C 中将它们标记为nullable

@protocol MyProtocol <NSObject>
- (void)doStuffWithDictionary:(NSDictionary*)dict
                    andString:(NSString*)str1
            andOptionalString:(nullable NSString*)str2
             andOptionalArray:(nullable NSArray*)arr
                     callback:(void (^)(id result))onSuccess;
@end

正如@MartinR 在 cmets 中建议的那样:

转到定义协议的头文件,然后从左上角的“相关项目”弹出窗口中选择“生成的接口”。这将向您显示您必须实现的确切 Swift 方法签名。

这也适用,并为不同版本的 Swift 提供不同的接口。

【讨论】:

  • 此解决方案有效。作为旁注,我试图在没有直接访问 XCode 的情况下对其进行调试。唯一可用的反馈来自 CI 系统,在每次(失败)尝试修复后几分钟。你为我节省了大量时间,谢谢!此外,对于可选/可为空,[Any]? = nil 适用于 NSArray* 参数。
猜你喜欢
  • 2015-01-01
  • 2017-03-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多