Swift基本的な書き方

#Data Type
- Escape sequence
 - \n , \\\, \r, \t, \", \', \u{nn}, \u{nnn} , \u{nnnnnnnn}など特殊文字は\\をつける
- 宣言
 - var
 - let(修正不可)
- TYPE SAFE
 - 変数のデータ・タイプを識別して違うタイプを保存できない
- タイプ識別
 - Type Annotation ``` var userCount:Int = 10 ```
 - Type Inference  ``` var signalStrength = 2,231 ```
- Tuple

```swift
// Index
let myTuple = (10, 432.123, "This is String")
var myString = myTuple.2
println(myString) // This is String

// Tupleから値を選択して使い別の変数に入れる
// ただし、index1のFloatを無視したい場合
var (myInt, _, myString) = myTuple

// Tupleにnameをつけたい場合
let myTuple = (count:10, length:432.433, message:"This is string")
println(myTuple.message) // This is String
```

 - optional：値がないもしくはnilができるのはoptional typeのみ
 
```swift
var index:Int?
index = 3　// index!が呼ばれないと値についてwrappedできないのでこの状態だとindexはnil

if index != nil {
 //値がある
} else {
 //値がない
}

```
 - optional binding

```swift
if let constantName = optionalName {}
if var variableName = optionalName {}
```

# 演算子と表現式
- 論理演算(logical operator)

```swift
( true || false) // どちらかがtrueだったらtrue
( true && false) // 両方がtrueだったらtrue
( true ^ false) // 一方のみがtrueだったらtrue
```

- 範囲演算

```swift
5...8 // 5,6,7,8
5..<8 //5,6,7
```

- ビット演算

```swift
var x = 171 //10101011
var y = 3 // 00000011

~y // 11111100, 0->1で1->0に変更
x & y // 00000011, 両方1の場合のみ1でそれ以外には0
x | y // 10101011, どちらかが1だったら1
x ^ y // 10101000, 一方のみが1だったら1
```

# 制御 (flow control)
- for / for-in

```swift
for index in 1...5
for char in "This is string"
for _ in "This is string" //現在の値は参照しない
```

- while / do-while
- break
 - loopをやめてloop以降に移動
- continue
 - loopの次の段階に移動
- if / if... else...if ...
- switch

```swift
switch(value) {
 case 0,1,2:
   println("zero, one or two")
 case 3:
   println("tree")
 case 4...10:
   println("four to ten")
 case 50...79:
   println("middle")
 fallthrough // このcaseの場合はbreakせず次のcaseに移動
 case 80...100 where value % 2 == 0
   println("High and even")
 default:
   break //やる作業がない場合はbreak
}
```

#関数
- 引数指定

```swift
func buildMessage() {}
// use: buildMessage()

func buildMessage(name: String, count: Int)
// use: buildMessage("John", 10)

func buildMessage(name: String, count: Int) -> String { return .... }
// use: var message = buildMessage("John", 10)

func buildMessage(#name: String, #count: Int) -> String { return .... }
// use: var message = buildMessage(name: "John", count: 10)

func buildMessage(customerName name: String, customerCount count: Int) -> String { return .... }
// use: var message = (customerName: "John", customerCount: 10)

func buildMessage(count: Int, name: String = "Customer") -> String { return .... }
// use: var message = buildMessage(10) or buildMessage(10, name:"John")

func displayString(strings: String...) { for string in strings { .... } }
// use: displayStrings("one", "two", "three", "four")

func calcuateArea(var length: Float, var width: Float) -> Float { 
  length = length * 2.54
  width = width * 2.54
  return length * width
}
// use: calcuateArea(10, 20)

var myValue = 10
func doubleValue (inout value: Int) -> Int {
  value += value
  return value
}
//use: doubleValue(&myValue) //myValue 10から20に変わる
```

-  return type

```swift
// Tuple
func sizeConverter (length: Float) -> (yards: Float, centimeters: Float, meters: Float) {
  var yards = length * 0.0277778
  var centimeters = length * 2.54
  var meters = length * 0.0254

  return (yards, centimeters, meters)
}

var lengthTuple = sizeConverter(20)
println(lengthTuple.yards)
println(lengthTuple.centimeters)
println(lengthTuple.meters)
```

- 変数としての関数

```swift
func inchesToFeet(inches: Float) -> Float { return inches * 0.08833333 }
let toFeet = inchesToFeet
// use: var result = toFeet(10)

func inchesToYards(inches: Float) -> Float { return inches * 0.0277778 }
let toYards = inchesToYards

func outputConversion(converterFunc: (Float) -> Float, value: Float) {
  var result = coverterFunc(value)
  println(result)
}
// use: outputCoversion(toYards, 10)
// use: outputCoversion(var, 10)


func decideFunction (feet: Bool) -> (Float) -> Float {
  if feet {
    return toFeet
  } else {
    return toYards
  }
}
```

- Closure
 - 名前が関数
 - 非同期関数を呼び出すためのハンドラーとしてよく使われる

```swift
let sayHello = { println("Hello") }
// use: sayHello()

let multiply = { (value1: Int, value2: Int) -> Int in 
  return value1 * value2   
}
// use: let result = multiply(10, 20)

// EvnetHandlerとして利用
eventSTore?.requestAccessToEntityType(EKEntityTypeReminder, completion: {
  (granted, error) -> Void in 
    if !granted {
      println(error.localizedDescription)
    }
})

// Closure
func functionA() -> () -> Int {
  var counter = 0

  func functionB() -> Int {
     return counter + 10
  }
  
  return functionB
}
// use: let myClosure = functionA()
// use: let result = myClosure()
```

# クラス(class)
- property
 - stored property
 - calculated property
- init
- deinit
- method
 - type method
 - instance method

```swift
class BancAccount {
  //property
  var accountBalance: Float = 0
  var accountNumber: Int = 0
  let fees: Float = 25.00

  var balanceLessFees: Float {
    get { return accountBalance - fees }
    set(newBalance) { accountBalance = newBalance - fees }
  }
  // use: var balance1 = account1.balanceLessFees
  // use: account1.balanceLessFees = 12124.12

  // init
  init(number: Int, balance: Float) { .... }
  // use: var account1 = BankAccount(number:112233, balance: 400.54)

  // deinit 
  deinit { .... }

  // instance method
  func displayBalance() { .... }

  // type method
  class func getMaxBalance() -> Float { return .... }
}
```

- クラス生成

 ```swift 
var account1 = BankAccount() 
var account2 = BankAccount(number: 121212, balance: 400.54) //　追加initを利用
```
- 呼び出し

```swift
  classInstance.propertyName
  // use: var balance1 = account1.accountBalance
  // use: account1.accountBalance = 686.99

  classInstance.instanceMethod()
  // use: account1.displayBalance()

  className.typeMethod()
  // use: var maxAllowed = BankAccount.getMaxBalance()
```
- self
 - 基本はそんなに使わなくてもいい
 - closuer内から参照される関数にはselfを必ず利用する
 - 関数内のローカル変数とプロパティ変数名が同じの場合

```swift
document?.openWithCompletionHandler({
  (success:Bool) -> Void in
    if success { self.ubiquityURL = resultURL }
})

class MyClass {
  var myNumber = 10
  func addTen(myNumber: Int) {
    self.myNumber = myNumber
  }
}
```

- 継承
 - 新しい関数、プロパティ追加可能
 - override可能、override funcの中からsuper.methodName()で親クラスの関数を呼び出せる
 - init追加可能、init中から親クラスのinitをsuper.init()で呼び出せる
 
```swift
class SavingAccount: BankAccount { 
  // init追加
  init (number: Int, balance: Float, rate: Float) {
    ....
    super.init(number: number, balance: balance)
  }

  // override
  override func displayBalance() {
    .... 
    super.displayBalance()
  }
  ..... 
}
```

# Index subscripting 配列（Array）
- 生成

```swift
var treeArray = ["Pine", "Oak", "Yew"]　// var 可変
let treeArray = ["Pine", "Oak", "Yew"]  // let 不変

// Type annotation
var treeArray: [String] = ["Pine", "Oak", "Yew"] 
var treeArray = [String]()

// 初期化：サイズ、default値指定
var nameArray = [String](count: 10, repeatedValue: "My String")

// 2つ配列を合わせて新しい配列を作る（ただし、全て同じタイプのデータ）
var firstArray = ["Red", "Green", "Blue"]
var secondArray = ["Indigo", "Violet"]
var thirdArray = firstArray + secondArray
```

- 項目制御

```swift
// 項目の数
var itemCount = treeArray.count

// 中身があるかどうか
if treeArray.isEmpty { .... }

// 特定の項目のみ出力と値の入れ替え
println(treeArray[2])
treeArray[1] = "Redwood"
```

- 項目の追加と削除

```swift
// 追加
treeArray.append("Redwood")
treeArray += ["Redwood"]
treeArray += ["Redwood", "Maple", "Birch"]

// 特定の位置に追加
treeArray.insert("Maple", atIndex: 0)

// 削除
treeArray.removeIndex(2)
treeArray.removeLast()
```

- 項目反復（Loop）

```swift
for tree in treeArray {
  println(tree)
}
```

# Key-Value 配列（Dictionary）
- String, Int, Double, BoolデータタイプのみKeyで使える
- 生成

```swift
var bookDict = ["100-432112" : "Wind in the willows",
                "200-532874" : "Tale of Two Cities",
                "202-546549" : "Sense and Sensibility"]
// annotation
var bookDict: [String: String] = 
               ["100-432112" : "Wind in the willows",
                "200-532874" : "Tale of Two Cities",
                "202-546549" : "Sense and Sensibility"]
// 空の生成
var myDictionary = [Int: String]()
```
- 項目の数

```swift
println(bookDict.count)
```
- 項目制御

```swift
// 特定の項目のみ出力
println(bookDict["100-432112"])

// 特定の項目の値を入れ替える
bookDict["200-532874"] = "Sense and Sensibility"
bookDict.updateValue("The Ruins", forKey: "200-532874")
```
- 項目の追加と削除

```swift
// 追加
bookDict["300-898871"] = "The Overlook"

// 削除
bookDict["300-898871"] = nil
bookDict.removeValueForKey("300-898871")
```

- 項目反復（Loop）

```swift
for (bookid, title) in bookDict {
  println("Book ID: \(bookid), Title: \(title)")
}
```