[英]Swift expose the protocol to objc in protocol oriented programming
我有這個運行良好的代碼:
public protocol PermissionProvider {
static func authorizationStatus(for mediaType: AVMediaType) -> AVAuthorizationStatus
}
extension AVCaptureDevice: PermissionProvider {}
現在我需要將協議暴露給 Objc 運行時:
@objc // added this attribute
public protocol PermissionProvider {
static func authorizationStatus(for mediaType: AVMediaType) -> AVAuthorizationStatus
}
extension AVCaptureDevice: PermissionProvider {}
但我收到一條錯誤消息:
AVFoundation.AVCaptureDevice:4:21: error: Objective-C method 'authorizationStatusForMediaType:' provided by method 'authorizationStatus(for:)' does not match the requirement's selector ('authorizationStatusFor:')
open class func authorizationStatus(for mediaType: AVMediaType) -> AVAuthorizationStatus
從錯誤消息來看,它似乎與 objc 和 swift 之間的一些命名約定有關。 我想知道如何修復編譯錯誤?
我引入這個協議的原因是,我需要對這個“權限提供者”進行單元測試和注入。 而我需要將其暴露給 objc 的原因是,一些調用者仍在 ObjC 中
編輯:
我創建了一個空項目,然后用上面的代碼創建了一個新文件,並得到了錯誤
在協議方法上添加 @objc 屬性以指定要暴露給 Objective-C 的不同方法名稱,在這種情況下,將其與AVCaptureDevice
的相關方法( authorizationStatusForMediaType:
:)匹配:
@objc // added this attribute
public protocol PermissionProvider {
@objc(authorizationStatusForMediaType:) static func authorizationStatus(for mediaType: AVMediaType) -> AVAuthorizationStatus
}
extension AVCaptureDevice: PermissionProvider {}
當 Objective-C 方法映射到 Swift 時,與相應參數類型匹配的參數描述會被刪減(參見SE-0005 'Better Translation of Objective-C APIs into Swift' ),但是當 Swift 映射到 Objective-C 時相應的“去修剪”不會發生。
例如,如果在 Objective-C 中我們定義了:
- (NappingStatus)nappingStatusForKoala:(Koala *)koala;
- (NappingStatus)nappingStatusForEchidna:(Koala *)koala;
當映射到 Swift 中時,這些將變為:
func nappingStatus(for: Koala) -> NappingStatus
func nappingStatus(forEchidna: Koala) -> NappingStatus
請注意,在第一種方法中, Koala
已從參數名稱中刪除,因為它與它所描述的參數類型匹配,但在第二種方法中, Echidna
沒有被刪除,因為它與參數的類型不匹配。描述(考拉)。
當從 Swift 映射到 Objective-C 時,這種修剪的逆轉不會發生。 例如,如果在 Swift 中我們定義了
func nappingStatus(for: Koala) -> NappingStatus
當映射到 Objective-C 時,它將變為:
- (NappingStatus)nappingStatusFor:(Koala *)koala;
因此,對於您的情況,Objective-C 中的 AVCaptureDevice 方法是:
+ (AVAuthorizationStatus)authorizationStatusForMediaType:(AVMediaType)mediaType;
在 Swift 中被映射到(注意 MediaType 被修剪):
class func authorizationStatus(for mediaType: AVMediaType) -> AVAuthorizationStatus
但是您的協議方法,在 Swift 中是:
static func authorizationStatus(for mediaType: AVMediaType) -> AVAuthorizationStatus
當映射到 Objective-C 時將是(注意 MediaType 不是 `de-pruned'):
+ (AVAuthorizationStatus)authorizationStatusFor:(AVMediaType)mediaType;
這與 AVCaptureDevice 中的 Objective-C 方法不匹配,因此我們只需通過 @objc 屬性提供正確的 Objective-C 方法名稱:
@objc(authorizationStatusForMediaType:) static func authorizationStatus(for mediaType: AVMediaType) -> AVAuthorizationStatus
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.