Objective-CからSwiftへの書き換え作業, enum, NS_OPTION, ビットフィールド

Swiftが登場して以来、 Objective-cenumをSwiftに書き直すといった作業は少なくない。 そんなenumをSwiftでかくとどうなるだろうか。

それを一度まとめてみようと思う。

基本系

Objective-c

enum Sample {
     SampleA = 1, SampleB, SampleC
};

Swift

enum Sample : Int {
    case a = 1
    case b 
    case c
}

NS_ENUMで定義された列挙型

Objective-c

typedef NS_ENUM (NSInteger, SampleType) {
    SampleTypeObjc,
    SampleTypeSwift,
    SampleTypeJava,
    SampleTypeKotlin,
};

Swift

enum SampleType : Int {
    case objc
    case swift
    case java
    case kotlin
}

これが大体の仕事場でObjective-Cファイルでよく見られるコードだと思う。 今まで散々Swiftに書き直してきたよ。

NS_OPTIONで定義された列挙型

Objective-c

typedef NS_OPTIONS(NSUInteger, SampleType) {
    SampleTypeObjc  = 1 << 0,
    SampleTypeSwift  = 1 << 1,
    CategoryJava = 1 << 2,
    CategoryKotlin = 1 << 3,
};

Swift

struct SampleType : OptionSet {
    let rawValue: Int

    static let objc = SampleType(rawValue: 1 << 0)
    static let swift = SampleType(rawValue: 1 << 1)
    static let categoryJava = SampleType(rawValue: 1 << 2)
    static let categoryKotlin = SampleType(rawValue: 1 << 3)
}

let singleOption = SampleType.objc
let multipleOptions: SampleType = [.objc, .swift]
if multipleOptions.contains(.swift) {
    print("multipleOptions has swift")
}

マクロ定義

マクロ

#define pi = 3.14
let Pi = 3.14

CまたはObjCで定義された、定数値を表す単純なマクロは、 Swiftではグローバルな定数として表現される。

共用体とビットフィールド

実務で全然見かけないが共用体の定義

objc

typedef union IntChars {
    int swift;
    unsigned char list[4];
};

swift

struct IntChars {
    var swift: Int = 0
    var list = [UInt8](repeating: 0, count: 4)
}

objc

typedef union IntChars {
    int swift;
    unsigned char list[4];
};

struct WNumber {
    unsigned int flag:1;
    unsigned int pad:7;
    IntChars data;
};

swift

struct IntChars {
    var swift: Int = 0
    var list = [UInt8](repeating: 0, count: 4)
}
struct WNumber {
    var: unsigned int flag?
    var: unsigned int pad?
    var data = IntChars()
}

このあたりを網羅しておけばenumのSwiftへの書き換えで いちいち考える必要がなくなると思います。