iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 28
0
Mobile Development

30 天從 Swift 學會 Objective-C系列 第 28

[28] 30 天從 Swift 學會 Objective-C:Swift friendly 的 API Swift name

在 Objective-C 與 Swift 的命名有明顯的區別,雖然 Swift interface 可以將 Objective-C 的 API 以一定程度的方式改寫為 Swift 命名方式。

Photo by @jontyson on Unsplash

可以改寫的部分

Objective-C 的 Foundation/Foundtion.h 提供了 NS_SWIFT_NAME 作為改寫 API 的關鍵字:

// Objective-C
NS_SWIFT_NAME(Sandwich.Preferences)
@interface SandwichPreferences : NSObject

@property BOOL includesCrust NS_SWIFT_NAME(isCrusty);

@end

@interface Sandwich : NSObject
@end

範例來自 Apple Developer Documentation [註 1]

其相對應的 Swift interface 則是

一些限制

Swift interface 並不是萬能的,在提供方便的 NS_SWIFT_NAME 的同時,有幾個要避免的事情:

  1. Namespace 的使用只有 1 個,如Sandwich.Preferences.Detail 是不能使用的
// Objective-C
NS_SWIFT_NAME(Sandwich.Preferences.Detail) // 'swift_name' attribute has invalid identifier for base name
@interface SandwichPreferencesDetail : NSObject
@end

正確使用的方式是 NS_SWIFT_NAME(SandwichPreferences.Detail)

  1. 參數的順序是不可以更改的。

[進階] NS_REFINED_FOR_SWIFT 隱藏 API

之前說到在 public header 的實作是會自動出現在 Swift interface 的,但是當我們想要透過改寫 API 的順序或是不想讓 Swift client 使用不方便的 API (如: ObjcBool 與 Swift.Bool),我們可以使用 NS_REFINED_FOR_SWIFT 的關鍵字來處理。

// Objective-C
@interface Color : NSObject
 
- (void)getRed:(nullable CGFloat *)red
         green:(nullable CGFloat *)green
          blue:(nullable CGFloat *)blue
         alpha:(nullable CGFloat *)alpha NS_REFINED_FOR_SWIFT;
 
@end

範例來自 Apple Developer Documentation [註 2]

// Swift
extension Color {
    var rgba: (red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat) {
        var r: CGFloat = 0.0
        var g: CGFloat = 0.0
        var b: CGFloat = 0.0
        var a: CGFloat = 0.0
        __getRed(red: &r, green: &g, blue: &b, alpha: &a)
        return (red: r, green: g, blue: b, alpha: a)
    }
}

請注意的是 __getRed 是不存在於 Swift interface 的。

註記

  1. Renaming Objective-C APIs for Swift - Apple Developer Documentation
  2. Improving Objective-C API Declarations for Swift - Apple Developer Documentation

簡單測驗

  1. Swift 官方有所謂的 API 編寫規範,請問在哪裡可以找到?
  2. [進階] Swift interface 透過哪些機制將 Objective-C API 自動轉譯為 Swift API

上一篇
[27] 30 天從 Swift 學會 Objective-C:Swift friendly 的 Unavailable 與 convenience init
下一篇
[29] 30 天從 Swift 學會 Objective-C:Swift friendly 的 進階 C 語言部分與 modulemap
系列文
30 天從 Swift 學會 Objective-C30

尚未有邦友留言

立即登入留言