SwiftのEnumと計算型プロパティを組み合わせて便利に使うTips


最近、案件でEnumの便利な使い方を学んだのでシェアします。

計算型プロパティとEnumを組み合わせると
toString()関数とか作らなくとも、シンプルに欲しい値を取得できます。

例:Enumから文字列を取得する

Enum内でSelfを使うと、Enumが参照された際の自分自身を指すことができるので、
Switch文すら不要な場合があります。

enum SNSType: Int {

  case Facebook
  case Twitter
  case Google

  // シンプル
  var name: String {
      if self == Google {
          return "\(self)+"
      }
      return "\(self)"
  }

  // この例だとtoString関数は冗長。プロパティごとに全く出力するテキストが違うならOK
  func toString() -> String {
      switch self {
      case Facebook:
          return "Facebook"
      case Twitter:
          return "Twitter"
      case Google:
          return "Google+"
      }
  }
}

print(SNSType.Google.name) // "Google+"

例:UIImage (SNSのアイコン画像)を参照する

色々取得できます。

enum SNSType: Int {

    case Facebook
    case Twitter
    case Google

    var name: String {

        if self == Google {
            return "\(self)+"
        }
        return "\(self)"
    }

    var iconImage: UIImage {
        return UIImage(named: iconName)!
    }

    // 外から欲しいのはiconImageなので、icon名を出力する処理はprivateで隠蔽化してやる
    private var iconName: String {
        return "ic-" + name.lowercaseString + ".png"
    }
}

結果:

<余談>値型のEnumについて想うこと

SwiftはEnumの値の型をStringにできます。
が、
本来Enumは定数であることを意識すると基本Int型がいいと思います。

<追記>
※コメントに書いていただきましたが、String型で使用したほうが便利なケースも多々あるそうです。 ケースバイケースですね。すみません..

例えば、下記のようなEnumを作った場合、
nameプロパティなど与えなくても、そのままSNS名が取得できるので一見便利そうですが、

enum SNSType2: String {
    case Facebook = "Facebook"
    case Twitter = "Twitter"
    case Google = "Google+"
}

例えばtag番号やタップしたセルなどから、
初期化したいとき、使い勝手が悪いです。

print(SNSType(rawValue: tag)!) // Facebook
print(SNSType2(rawValue: "Facebook")!) // Facebook

上記例の場合、初期化の結果は同じですが、
SNStype2は初期化の際、typoしてしまうとクラッシュします。
あと初期化の値に、"Facebook"と書けるなら

SNSType2.Facebook.rawValue

と定義すれば良いですが、毎回どのプロパティを定義すれば良いか分かるわけでもないのでやはり不便です。

ですので、値型のEnumは基本Int型で良いと思います。