Xcodeと仲良くなるためのいくつかの方法

この記事は [慶應義塾大学SFC村井&徳田研 Advent Calendar 2015](http://www.adventar.org/calendars/1053) の11日目の記事です。

---

こんにちは．みなさんiOSアプリ作ってますか？作ってますよね．
この記事では，iOSアプリを開発するために
避けては通れない
大活躍してくれるXcodeと仲良くなる方法を紹介します．

## 背景

先日[Swiftコンパイラのソースコード](https://github.com/apple/swift)が公開され，一部界隈ではお祭りの様を呈しています．
Appleは同時に[FoundationのSwift再実装](Foundation)や[Swift3.0への展望](https://github.com/apple/swift-evolution)など
野心的な計画を公表し，さらに[メーリングリスト](https://swift.org/community/#mailing-lists)といった議論の場を積極的に用意するなど，
Swiftが今後盛り上がっていくことは間違いないと言えるでしょう．

さて，ここで[Apple Developer内のSwiftのページ](https://developer.apple.com/swift/)を見てみましょう:
> Swift is a powerful and intuitive programming language for iOS, OS X, tvOS, and watchOS.

そう，**Swiftが盛り上がってiOSが盛り上がらないわけがない**のです！[^1]

実際，弊研究室でもこれからiOSアプリを作りたい，という人をちらほら見かけます．
Swiftがオープンソース化された今だからこそ，Xcode入門，というか**Xcodeに入門した後にするべきこと・覚えておいたほうがいいこと**を紹介します．

なお，ここでは各項目について深く掘り下げることはしません．それぞれここQiitaでも検索すれば詳しくて分かりやすい記事がたくさん出てくるはずなので，そちらを参照してください．

[^1]: OS X・tvOS・watchOSはなんとも言えないところがあるのでここでは割愛します

## Swiftを書こう

おそらく今からObjective-Cでアプリを作ろうという人はいないかと思いますが，当然新規プロジェクトはSwiftで始めましょう．
そして重要なのは，Swiftで書くことだけでなく，Swiftの文法を活用することです．

iOSアプリは今のところObjective-Cで開発されていた期間のほうが長いので，Objective-Cの情報がまだまだ多く出てきます．
しかしObjective-CとSwiftは，同じiOSアプリ開発に使われるといっても言語の性質や作法が異なります．

具体的には，Objective-Cは開発者にとって自由の利く言語である反面，開発者が気を配ってあげないと間違ったコードや危険なコードがかけてしまう言語です．一方Swiftの文法には，安全なコードを書くための様々な工夫が盛り込まれています．

中でも最も扱う機会が多いのが**`Optional`**でしょう．特にiOSアプリ開発からプログラミングに入った方などはなかなか馴染めないこともあるみたいですが，使いこなせないのは非常にもったいないので，ここで簡単にご紹介します．

たとえば，NSNotificationCenterを用いて以下のように通知を送るとします:

```
// let data: NSData = ...
NSNotificationCenter.defaultCenter().postNotificationName("UserDidUploadData", object: nil, userInfo: ["data": data])
```

あえて危険な受け取り方をするなら，以下のようになるでしょう:

```
NSNotificationCenter.defaultCenter().addObserverForName("UserDidUploadData", object: nil, queue: nil) { notification in
	let userInfo = notification.userInfo!
	let data = userInfo["data"] as! NSData
	print("The data is \(data.length) bytes")
}
```

Swiftで`Optional`を扱う際にでてくる`!`は，「何かが何かであることを仮定して話を進める」という意味です．
つまり上のコードは，`notification`に`userInfo`がセットされていることを仮定し，その`userInfo`が `"data"` というキーで何かを持っていることを仮定し，なおかつそれが`NSData`であることを仮定する，という意味です．

しかしながら，みなさんご存知の通り仮定は外れるものです．もし通知を飛ばす際にデータを付け忘れたりすると，プログラムが死に至ります．

最悪の事態を避けるために，Swiftらしく慎重に，一歩一歩確かめながら進んでいきましょう:

```
NSNotificationCenter.defaultCenter().addObserverForName("UserDidUploadData", object: nil, queue: nil) { notification in
	if let userInfo = notification.userInfo {
		if let data = userInfo["data"] as? NSData {
			print("The data is \(data.length) bytes")
		} else {
			print("userInfo has no data")
		}
	} else {
		print("notification has no userInfo")
	}
}
```

こうすることで，データが存在しない場合はアラートを出すなど，道を踏み外さずに進んでいくことができます．

しかし，`userInfo`があるかのチェックは一番上にあるのにエラーの出力は最後にあるなど，まだ分かりにくいですね．実はSwift2.0から追加された`guard`構文を使えば，以下のようにも書くことができます:

```
NSNotificationCenter.defaultCenter().addObserverForName("UserDidUploadData", object: nil, queue: nil) { notification in
	guard let userInfo = notification.userInfo else {
		print("notification has no userInfo")
		return
	}

	guard let data = userInfo["data"] as? NSData else {
		print("userInfo has no data")
		return
	}

	print("The data is \(data.length) bytes")
}
```

ちなみに`Optional`の正体は`Enum`なので，以下のように簡単に実装できます．興味を持たれた方はもっと調べてみてください．

```
enum Optional<T>: NilLiteralConvertible {
	case Some(T)
	case None

	init(value: T) {
		self = .Some(value)
	}

	init(nilLiteral: ()) {
		self = None
	}
}
```

せっかくSwiftというモダンな言語を使えるので，その利点を積極的に活用していきましょう．

## カラースキームを変更しよう
さて，ここからようやくXcodeの話です．

まずXcodeでコードを書き始める前に，Xcodeの**カラースキーム**（シンタックスハイライトの色付けの仕方）を変更しましょう．シンタックスハイライトは，文字列にすぎないソースコードから得られる情報の次元を増やすことのできる手段です．色付けのされ方に慣れれば，ソースコードを読むスピードが上がったり，自分の書いているコードが正しいかを確認しながらコーディングを進められるになったりするので，是非とも活用したいところです．

もちろんほとんどのエディターはシンタックスハイライトが可能ですが，Xcodeのシンタックスハイライトは静的解析の結果をもとに色づけしてくれるので，キーワードの種類ごとになかなか細かく設定できます．

にも関わらず，実はXcodeのデフォルトのカラースキームはイマイチです:

<img width="862" alt="Screen Shot 2015-12-12 at 1.53.40 AM.png" src="https://qiita-image-store.s3.amazonaws.com/0/28196/7b5afadc-ff75-0537-8b97-fd6691cef704.png">

ご覧の通り，**クラス・関数・定数・変数の色がほとんど一緒で，同一プロジェクト内で定義されているかかそうでないかで区別されています**．せっかくクラス・関数・定数・変数で区別できるのだから，それぞれに色づけをしたほうが分かりやすくはないでしょうか．

以下のようにクラス・関数・定数・変数でそれぞれ分けることで，定義を確認しなくてもキーワードの種類を一瞬で認識することができるようになります:
<img width="862" alt="Screenshot 2015-12-12 02.05.12.png" src="https://qiita-image-store.s3.amazonaws.com/0/28196/70072b51-144b-4a00-7c04-7bf688d6fecb.png">

もちろん何がどの色で，というのは好みの問題ですし，もしかしたらデフォルトのカラースキームのような分類が分かりやすい方もいるかもしれません．なんにせよ，早い段階で自分にとって最もわかりやすいものを用意しておくことをお勧めします．

## "Jump to Definition"を活用しよう
iOSの豊富なフレームワーク群を使っているうちに，このフレームワークは何ができるんだろう？とか，このクラスはどんなメソッドを持っているんだろう？といったことはよくあると思います．そんな時，リファレンスの次に役に立つのがこの機能です．

何ができるのかわからない/使い方を知りたいクラスやフレームワークがあったら，その上で右クリックし，"Jump to Definition"を選択してみましょう:

<img width="582" alt="Screenshot 2015-12-12 02.19.46.png" src="https://qiita-image-store.s3.amazonaws.com/0/28196/d2d12e33-31f9-97a2-1f89-7a74557bf209.png">

すると，下のような定義ファイルに飛ぶことができます:
<img width="707" alt="Screenshot 2015-12-12 02.22.31.png" src="https://qiita-image-store.s3.amazonaws.com/0/28196/a551aba5-83ac-8591-191f-0ea061fe42ea.png">

ここで，定義されている型やクラス，メソッドなどを一覧することができます．しかもご覧の通り，それぞれ大量のコメントが付記されており，引数の意味などは大体これを見るだけで把握できることが多いです．

そしてこの機能，なんとコンテキストメニューを開かなくても<key>⌘</key>キーを押しながらクリックすることで開けてしまいます．Appleが活用しろと囁く声が聞こえますね．

ちなみに，すべてを一覧する必要がない場合は<key>option</key>キーを押しながらクリックすると以下のような良い感じのポップアップが出てきます．ここに表示される説明文はリファレンスの情報から取得しているようなので，スクリーンショット内のスクロールバーからも察せられるように，半端ない情報量があります．

<img width="1280" alt="Screenshot 2015-12-12 02.25.43.png" src="https://qiita-image-store.s3.amazonaws.com/0/28196/672633c9-aa3b-3b87-32d3-5fe55180a49b.png">

これらの機能を活用してiOS SDKをマスターしていきましょう．

## まとめ

本当はあと4つほど項目があったのですが (lldb, Auto Layout, Instruments, Xcodeのgitは使うな, など)，思いの外長くなってしまったのと，Advent Calendar的にギリギリ滑り込みアウトになってしまったので，ここで終わりたいと思います．本当はこういったそれぞれを記事にして細かくシェアしていくべきだったのかもしれないですね．

さて，つよい人たちからはやれゴミだのカスだのvimでいいだのと蔑まれ，はじめての人たちからはよくわからないだの使いにくいだのと距離を置かれるXcodeですが，それでもAppleのエコシステムの中に置かれているという点でiOSアプリ開発に使われ続けていくことは間違いないでしょう．皆さんがXcodeと仲良くなって，iOSアプリ開発をエンジョイできるようになることを願っています．

---

ところで最近アイコンの変わった[AppCode](https://www.jetbrains.com/objc/)，めっちゃ便利そうですね．今度使ってみたいと思います．