Takahiro Octopress Blog

-1から始める情弱プログラミング

Swift2.0で追加された新機能を見てみよう!

| Comments

今更だけど見てみたいSwift2.0で追加された新機能

さて、本日は表題通り、今更なんだけど…Swift2.0で追加された新機能について見ていきたいと思います。
Swift2.0では下記3つの新機能が追加されました。

  • guard statement
  • do-catch, try, defer
  • Protocol Extension

これらの使いどころやメリットなど見ていきたいと思います。

guard statementについて

まずはguard statementについて見ていきます。

用途について

条件分岐(if 〜 else 〜)で利用します。
例えば、Open Weather Map APIでのリクエストでは

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Alamofire.request(.GET, "http://api.openweathermap.org/data/2.5/weather?APPID=<あなた自身のAPPID>",
  parameters:["q":location]).responseJSON { (response) -> Void in
      if response.result.isSuccess {
          guard let value = response.result.value else {
              // 値の取得に失敗した場合
              return
          }
          guard let weatherArray:AnyObject? = value["weather"] else {
              // 値の取得に失敗した場合
              return
          }
          guard let weather = weatherArray?[0] else {
              // 値の取得に失敗した場合
              return
          }
          guard let description = weather["description"] as? String else {
              // 値の取得に失敗した場合
              return
          }

          print(description)
      }
}

のように書くことができます。
以前であれば、下記のようにこれでもかってくらいネストしていたのですが、可読性が向上します。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Alamofire.request(.GET, "http://api.openweathermap.org/data/2.5/weather?APPID=<あなた自身のAPPID>",
  parameters:["q":location]).responseJSON { (response) -> Void in
      if response.result.isSuccess {
          if let value = response.result.value {
              if let weatherArray = value["weather"] {
                  if let weather = weatherArray?[0] {
                      if let description = weather["description"] as? String {
                          print(description)
                      }
                  }
              }
          }
      }
}

do-catch, try, deferについて

続いて、do-catch, try, deferについて見ていきます。

用途について

基本的には、例外処理を実行したい場合に使います。
想定外の例外が発生した場合にアプリが落ちないようにしないことはもちろんのこと、
想定した例外処理が発生した場合にもそれ相応の処理を実施することがあるので、
そういったときに使います。

まずは、呼び出し元を書きます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// エラー種別の設定
enum MyError: ErrorType {
  case NilError
  case StringError
}

// サンプルメソッド
func sampleMethod(param: String?) throws -> String {
  defer {
      print("メソッドが呼ばれました!")
  }

  if param == nil {
      throw MyError.NilError
  } else if param == "Error" {
      throw MyError.StringError
  }

  return param
}

throwで例外を投げる際にエラー種別を渡す必要があるため、エラー種別を設定します。
deferは例外発生の有無に関わらず、 必ず実行する処理内容 を書きます。

続いて、呼び出し先を書きます。

1
2
3
4
5
6
7
8
9
10
do {
  let result = try self.sampleThrowMethod("Error")
  print(result)
} catch MyError.NilError {
  print("nilがパラメータとして渡されました")
} catch MyError.StringError {
  print("Error文字列がパラメータとして渡されました")
} catch {
  print("想定外のErrorが発生しました")
}

do-catchは例外発生別にその後の処理を分けるために利用します。
try!で強制実行する場合はdo-catchは不要ですが、
アプリがダウンしては元も子もないのでオススメしません。

Protocol Extension

最後にProtocol Extensionです。

用途について

筆者のイメージではObjective-Cで言うところの カテゴリ の用途に近いのかなと思っています。
Objective-Cのカテゴリと異なるのは指定した既存クラスにメソッドを追加するのではなく、
プロトコル にメソッドを追加するので拡張性や柔軟性が高いようです。

1
2
3
4
5
6
7
8
9
10
// MyProtocol.swift
protocol MyProtocol {
  func pico()
}

extension MyProtocol {
  func pico() {
      print("プロトコルメソッドを追加しました")
  }
}

定義したメソッドを下記のように呼び出せます。

1
2
3
4
5
6
7
8
// ViewController.swift
class ViewController: UIViewController, MyProtocol {
  override func viewDidLoad() {
      super.viewDidLoad()

      self.pico()
  }
}

まとめ

さて如何でしたでしょうか?
今更ですが、Swift2.0の新機能について見てきました。
個人的にはguard statementはかなり利用したいなと思っています。
ネストが多発しがちなSwiftでは活躍の場面が目に浮かびます。
do-catchは待ち望んだ機能ですし、逆に今までなかったのが信じられないくらいですよね?
より安定したSwift製アプリを作成することができると想像するとワクワクしますね。

といったところで本日はここまで。

Comments