2019/01/22

Swift4.0→4.2でEnumEnumerableが不要になった

iOS12.0 対応で Xcode 10 にして Swift 4.2 対応した。
基本的にAll Fix Issuesでポチポチやれば良いが、
Enumのcountが取れずテーブルビューが表示されなくなった。
これまではEnumを自前で実装する必要があったので、
EnumEnumerableを使っていたが、Swift4.2の新機能CaseIterableでいけることに気付いた。

対象

– EnumEnumerable

使ってたやつ

EnumEnumerable

protocol EnumEnumerable {
    associatedtype Case = Self
}

extension EnumEnumerable where Case: Hashable {
    private static var iterator: AnyIterator<Case> {
        var n = 0
        return AnyIterator {
            defer { n += 1 }

            let next = withUnsafePointer(to: &n) {
                UnsafeRawPointer($0).assumingMemoryBound(to: Case.self).pointee
            }
            return next.hashValue == n ? next : nil
        }
    }

    static func enumerate() -> EnumeratedSequence<AnySequence<Case>> {
        return AnySequence(self.iterator).enumerated()
    }

    static var cases: [Case] {
        return Array(self.iterator)
    }

    static var count: Int {
        return self.cases.count
    }
}

CaseIterable

リファレンス: https://developer.apple.com/documentation/swift/caseiterable

Swift 4.2 では enum の件数が自前で実装しなくてもとれるようになった。

enum Element: CaseIterable { case hoge, piyo, fuga, hogehoge }

Element.allCases         // returns some Collection whose Iterator.Element is Element
Element.allCases.count   // returns 4
Array(Element.allCases)  // returns [hoge, piyo, fuga, hogehoge]

結論

  • EnumEnumerable削除
  • “EnumEnumerable” → “CaseIterable”にReplace
  • 一度ビルドしてエラーの箇所を.count→.allCases.countに修正

.countをReplaceで一気にやれればいいけど、Enum以外も引っかかってしまうのでそこはちょっと面倒でした。