iTunes Uで学ぶSwift入門 ( Developing iOS 8 Apps with Swift Lecture 1 ~ 2 )

iTunes Uにて[Developing iOS 8 Apps with Swift](https://itunes.apple.com/us/course/developing-ios-8-apps-swift/id961180099)というStanford Universityの講義を発見したので、そちらを利用してswiftを学ぶことにしました。
xcodeの基本的な使い方から丁寧に説明されているのでオススメです。

※この記事はその備忘録です。あくまで備忘録なので、自分の中で残して置きたいと思ったものしか記載していません。

# 概要
Calculatorを実際に作りながら、swiftでアプリを作る方法を勉強していきます。
xcodeの使い方、MVCの考え方など基本的なところの説明もされているので、初心者でも勉強しやすい教材だと思います。
授業はもちろん英語で進みますが、字幕を使えばある程度理解できると思います。

# xcodeの便利な使い方

optionを押しながら変数や関数名をクリックすると、変数の型や関数の引数などの情報が参照できる.

# Auto Layout

Ctrl + Drag で2つのview間にconstraintsを設定できる.

* 黄色い線が今表示されているビューの位置
* 黄色い破線がconstraints(Auto-Layout)によって設定されるビューの位置
* 青い線が表示されているとき、今表示されている位置とconstraintsによって設定される位置が一致していることを示す→OKのサイン
* 赤い線がでるときはConstraints同士でコンフリクトするなどなんらかのエラーが出ている

### 黄色い破線が表示されているときの修正方法
document outlineの中の黄色い丸をクリック→修正する必要のあるところのリストが表示される.
修正したい項目の黄色い三角をクリック→修正方法を指定.

* Update Frame = 黄色い破線に合うようにビューを変更
* Update Constraints = 今表示されているビューになるようにConstraintを設定
* Reset to Suggested Contraints = 黄色い破線に合うようにConstraintを設定

Apply to all views in containerを選択しておくと全てのビューを一気に修正してくれる.


# 型について

swiftは型を推測してくれるので必ず書く必要はない.

```swift
var str = "string" // 自動的にString型になる
```

varは変更可能な変数、letは変更不可能な変数.
letを使うと絶対に変更されないことが保証されるので、コードを読むときに余計な心配が減る.(readable)

```swift
var varStr = "string"
varStr = "new string" // OK

let letStr = "string"
letStr = "new string" // NG 
```

optional(?マーク)のついている変数が取りうる値は nil(not set) or something.
optionalをoptionalで無くしたいときは"!"でunwrapする.

```swift
let digit = sender.currentTitle  // currentTitleはString? → digitもString?になる
let digit = sender.currentTitle! // unwrapしたのでdigitはString
```

もしunwrapしたときに変数がnilだったら、アプリはクラッシュする.
このことをうまく利用して、アプリをクラッシュさせることでリリース前にバグを発見することができる.

```swift
var tmp: String? = nil // optionalな変数にnilを代入
let str = tmp! // クラッシュ
```

!マークはoptionalだが、常に自動でunwrapしてくれるという意味の記号.
!マークだが依然としてoptinal型であることに注意.
optional型なのでもちろんnilを代入することができる

```swift
var display: UILabel?
let text = display!.text! // 毎回unwrapは面倒

var display2: UILabel!
let text = display2.text!  // 自動でunwrapしてくれる
display2 = nil // OK
```

# 特殊文字

Edit>Special Charactersから√などの特殊文字を入力することができる.
(日本版だと、Edit>Emoji & Symbol)

# Array, Dictionary

Array, Dictionaryは以下のように簡略化して書くことができる.

```swift
var array = Array<String>()
var array = [String]()

var dic = Dictionary<String, Double>()
var dic = [String:Double]()
```

# 代入時、呼び出し時に処理を追加したいとき

Calculatorでは、displayに表示されている文字列を数字として受け取りたい.
また、逆に数字をセットしたときにdisplayとなるUILabelのテキストを更新してほしい.
そういうときに以下の方法が使える.

```swift
var displayValue: Double {
    get {
        return NSNumberFormatter().numberFromString(display.text!)!.doubleValue
    }
    set {
        display.text = "\(newValue)" // newValueは代入された値
    }
}
```

# 関数を引数として渡すとき

馬鹿正直に書くと以下のようなコードになるとき、stackに入っている数字の確認や、計算後の更新作業など共通な部分がたくさんある.

```swift
switch operation {
case "×":
    if stack.count > 2 {
        result = stack.removeLast() * stack.removeLast()
        updateDisplay(result)
    }
case "÷":
    if stack.count > 2 {
        result = stack.removeLast() / stack.removeLast()
        updateDisplay(result)
    }
case "+":
    if stack.count > 2 {
        result = stack.removeLast() + stack.removeLast()
        updateDisplay(result)
    }
case "−":
    if stack.count > 2 {
        result = stack.removeLast() - stack.removeLast()
        updateDisplay(result)
    }
}

```

このとき、以下のような関数を使って処理を共通化することを考える.

```swift
func performOperation(operation: (Double, Double) -> Double){
    if stack.count > 2 {
        result = operation(stack.removeLast(), stack.removeLast())
    }
}
```
performOperationは"Doubleの引数2つからDoubleを返す関数"を引数にとる関数.
これを使うと以下のように書ける.
multiplyという"2つのDoubleからDoubleを返す関数"を引数として渡していることがわかる.

```swift
func someFunction {
    switch operation {
    case "×": performOperation(multiply)
    case "÷": ...
    case "+": ...
    case "−": ...
    }
}

func multiply (op1: Double, op2: Double) -> Double {
    return op1 * op2
}
```

この方法を使うときは他の場所でいちいち関数を宣言しなくても、その場で作成して渡すこともできる.
これをClosureと呼ぶ.

```swift
func someFunction {
    switch operation {
    case "×": performOperation({ (op1: Double, op2: Double) -> Double in // 引数の宣言
        return op1 * op2 // 関数の中身
        })
    ...
    }
}
```

ここからはswiftの機能を利用して、この関数をよりシンプルにしていく.
はじめに、performOperationは"(Double, Double) -> Double"という関数を引数にとることがわかっているので、op1/2についているDoubleと返り値のDoubleは削除することができる.
また、Double型の値を返すことがわかっているので、returnも削除することができる

```swift
performOperation({ (op1, op2) in op1 * op2 })
```

次にswiftでは\$マークを利用して引数に名前をつけることなく利用することができる.
これを利用すると、引数を削除することができる.$マークを利用するときは0から始まることに注意.
また、関数が最後の引数のとき、関数を( )の外に出すことができる.

```swift
performOperation({ $0 * $1 })
performOperation(){ $0 * $1 } // 関数を( ) の外に出す
performOperation{ $0 * $1 }   // ( )内に引数が無いので( )を削除
```

このようにすると最終的にswitch文の中は以下のようになる.

```swift
switch operation {
case "×": performOperation{ $0 * $1 }
case "÷": performOperation{ $1 / $0 }
case "+": performOperation{ $0 + $1 }
case "−": performOperation{ $1 - $0 }
}
```