Swift日本語チュートリアル ~ 前編(Apple公式ドキュメントSwift Tour±α)
このドキュメントは、
- Ruby/C++などでプログラミング経験がある人が
- Swiftを初めて勉強するときに、
- インストールから始めて、
- 標準ライブラリを調べながらなら一通りはコーディング出来るようになる
ことを目的としたチュートリアルの前編です。
Swift日本語チュートリアル ~ 後編(Apple公式ドキュメントSwift Tour±α) - こんにゃくマガジン
と併せて
Apple公式Swiftサイト Swift - Apple Developer にあるA Swift Tour — The Swift Programming Language (Swift 5.5)相当(翻訳ではないです)±αな内容になっています。
後編の内容は、クラス、列挙、構造体、ジェネリクス、簡単なネットワークライブラリの使い方、ちょっと進んだSwiftでのiPhoneアプリ開発、コマンドラインでのSwiftの使い方です。
後編まで読み終われば、このブログのような面白いアプリを作るための準備は整います。
Swiftでのゲーム開発にあたっては、こちらもご参照下さい。
原稿をGitHubで管理することにしました。間違いの訂正や古い情報の更新はプルリクエストして頂けると助かります。
https://github.com/knj4484/hateblo-xavier
Swiftチュートリアル
Xcode 6をダウンロードする
- iOS Developer Programにメンバー登録したApple IDでログインしておく
- 分からない場合は、こちらのサイトなどを参考に登録を済ませて下さい
- Xcode 6 betaのDownload Xcodeボタンを押してしばらく待つ
- ここに行く https://developer.apple.com/jp/xcode/downloads/
- Xcode 6 GM seed を無料でダウンロードをクリック
インストール
- ダウンロードしたファイルxcode_6.dmgをダブルクリックして、しばらく待つ
- 出てきたウインドウで左のXcodeアイコンを右のAppアイコンにドラッグ&ドロップ
スポンサーリンク
Xcode 6を起動する
初回起動はわりと時間がかかります
- Internetからダウンロードしたアプリうんぬん > Open
- Licence Agreement > Agree
- These application must be quit before installation can continued > Quit All
- Welcome to Xcode > Get started with a playground
- Save as : MyPlayground > Create
- コンソール出力エリアを表示:メニューからView > Assitant Editor > Show Assistant Editor
- 左側にprintln("hello swift")と入力
- 右側Consolo Outputのところにhello swiftと出力されましたか?
このようにplaygroundという機能でswiftのコードを試すことが出来ます。
もう一度playgroundを作りたい場合は、
メニューからWindow > Welcome to Xcode
で出来ます。
以前のXcodeが起動している状態で6betaを起動するとうまく行かないかもしれません
コメント、定数、変数、型、出力、文末セミコロン
// 一行コメント /* 複数行コメント */ var myVar = 42 myVar = 50 let myConst = 42 myConst = 1 // => error: cannot assign to 'let' value 'myConst' let implicitDouble = 70.0 let explicitDouble: Double = 70 let errorCode = 94 "error code: " + errorCode // => error: could not find an overload for '+' that accepts the supplied arguments println("error code: " + String(errorCode))
- //以降はコメントになる
- /* */で複数行をコメントにできる。これは入れ子にもできる
- 定数はletで定義する。変数はvarで定義する。
- 変数の後ろにコロンで区切って型を指定することが出来る
- 型を指定しなくても良い場合もある
- 定数や変数を初期化するときに値から型が決められる場合など
- 値が暗黙に他の型に変換されることは決してない
- 他の型に変換する必要がある場合、明示的に所望の型のインスタンスを作る
- printlnまたはprintで出力できる(printは改行なし)
- 文末を表すセミコロンは普通は書かない
- 一行に2文書くときや入れたいときだけ入れれば良い
文字列
var name = "Swift" + " " + "Programming" name += " Language" countElements(name) let boyCount = 3 let girlCount = 5 println("There are \(boyCount + girlCount) children.")
- 文字列リテラルはダブルクオートで囲む
- 文字列の連結には+演算子を使う
- 文字列オブジェクトに文字列を追加するには+=演算子を使う
- 文字列の長さはグローバル関数countElementsで分かる
- 文字列中に値を含めるため簡単な書き方は、括弧に挟んで値を書き、括弧の前にはバックスラッシュを書く
配列
var colours = ["red", "black", "white", "blue"] let names = String[]() // 空配列 colours[0] = "pink" colours += "grey" colours.count for colour in colours { println(colour) }
- 配列はブラケットを使って定義する
- 空の配列は、初期化子構文で定義する
- 配列の要素にアクセスするには、インデックスをブラケット中に書く
- インデックスはゼロ始まり
- 配列の要素数はcountプロパティー
- 要素追加は+=演算子
- 要素をイテレートするにはfor-inを使う
dictionary
var petCounts = ["dog": 2, "cat": 3] var wordCounts = Dictionary<String, Int>() // 空ハッシュ wordCounts["dog"] = petCounts["dog"] wordCounts.count wordCounts.keys wordCounts.values for (pet, count) in petCounts { println(pet + ":" + String(count)) }
- ハッシュはブラケットを使って、キーとバリューをコロン区切りにして定義する
- 空ハッシュは、初期化子構文で定義する
- ハッシュの要素にアクセスするには、キーをブラケット中に書く
- 要素数はcountプロパティー
- キー一覧の取得はkeysプロパティー
- 値一覧の取得はvaluesプロパティー
- ハッシュの要素をイテレートするにはfor-inを使う
真偽値
var endFlag : Bool = false endFlag = true
- 型を指定する場合は、Boolと書く
- trueまたはfalseどちらか(小文字表記のみ可)の値を持つ
関数の定義と呼び出し - 入門
func createMessage(title: String, body: String) -> String { return "title: \(title)\nbody: \(body)" } createMessage("task", "mail John") func createMessage2(title t: String, #body: String) -> String { return "title: \(t)\nbody: \(body)" } createMessage2(title: "task", body: "call John")
- 関数を定義するためにfuncを使う
- パラメーターの後ろに->につづけて関数の戻り値の型を書く
- 関数に括弧に入れた引数リストを続けて関数呼び出しをする
- パラメーター名は呼び出し側で使う名前も指定できる
- 呼び出し側と関数内部で使う名前をスペース区切りで指定できる
- 関数内部の名前と同じでよければ、#をつけておく
条件分岐 if、三項演算子
func rank(score : Double) -> String { if (score > 90) { return "A" } else if score > 70 { return "B" } else { return "C" } } let score = 99 score > 90 ? "OK" : "NG"
- 条件前後の括弧は書かなくても良い。本体前後の括弧は必須
- if文の条件はブール値(あるいは後述のオプショナル値)でなければならない
- 数値がブール値に型変換されたりしない。if score {}みたいなコードはエラーである
- 三項演算子も使える
オプショナル値
値があるかもしれないし、ないかもしれないことを表すために、オプショナル値を使う
func createMessage(optionalTitle : String?, optionalContent : String?) -> String? { var message = "" if optionalTitle { message += "title: " + optionalTitle! + "\n" } if let content = optionalContent { message += "content: " + content } if message == "" { return nil } else { return message } }
- オプショナル値型であることを表すために、型名に?を付ける
- 値がないことを表すのにnilを使う(Nilとかnullとかはない)
- if文でオプショナル値に値があるか知ることができる。
- あればtrue、なければfalse扱い
- 値を持つオプショナル値は!を付けることで値を取り出せる
- if let tmpVar = OptionalVar 構文でオプショナル値のありなし判定と同時に値を変数に束縛できる(Optional Bindingという)
func messageCount(optionalMessages: Array<String>?) -> Int? { return optionalMessages?.count // => optionalMessages!.count または nil } func lastItem(items : Array<Int>?) -> Int? { return items?[items!.count - 1] }
- オプショナル値を利用する時には、メソッドやプロパティーや[]などの操作の前に?を書くことが出来る
- もし、?の前の値がnilであれば、
- ?以降のもの全てが無視さる
- 全体の式の値はnilである。
- ?の前の値がnilでなければ、
- オプショナル値はunwrapされる
- ?以降の全てがunwrapされた値に対して作用する
- いずれにしても、全体の式の値はオプショナル値である
- もし、?の前の値がnilであれば、
条件分岐 switch
func evaluate(diff : Int) -> String? { switch diff { case 100: return "max" case let x where 0 < x && x < 100: return "up" case 0: return "-" case let x where x < 0: return "down" default: return nil } }
- switchでは(整数値の等値チェックに限らず)任意の種類のデータと様々な比較演算子が利用できる
- マッチしたcaseの中のコード実行後には、プログラムはswitch文から抜ける
- 実行は次のcaseに続かないので、caseの最後で明示的にbreakしなくてよい
よく使う演算子の紹介
- 代入:=
- 値を返さない(==と間違えて使われるのを避けるため)
- 算術演算子:+ - * / %
- だいたいいつも通りの使い方が出来る
- 余り%は小数でも計算できる
- インクリメント/デクリメント:++ --
- 前置も後置もできる
- 小数にも使える
- 複合代入演算子:+=みたいなやつ色々
- 比較演算子:== != > < >= <=
- 範囲演算子:..< ...
- 1..<5 => 1,2,3,4
- 1...5 => 1,2,3,4,5
- 論理演算子:! && ||
ループ(for、while、do-while)
var sum1 = 0 for i in 0..3 { sum1 += i } // この上下二つのループは同じこと var sum2 = 0 for var i = 0; i < 3; ++i { sum2 += 1 } var x = 1 while x < 100 { x = x * 2 } var y = 2 do { y = y * 2 } while y < 100
- forループのインデックスの範囲を作るために..を使える
- 初期化;条件;インクリメントを明示的に書くことも出来る
- whileループは、条件が変化するまでコードブロックを繰り返すために使う
- whileの条件は、ループが少なくとも一回は実行されることを保証するために、最後におくことも出来る
関数の定義と呼び出し - 初級編
func getProfile() -> (name: String, age: Int, size: Double) { return ("Steve", 46, 8.9) } let profile = getProfile() println("name: " + profile.name) func squareSum(numbers: Int...) -> Int { // 二乗和 var sum = 0 func addSquare(x:Int) { sum += x * x } for number in numbers { addSquare(number) } return sum } squareSum(4, 6, 8, 9)
- 関数から複数の値を返すためにタプルを使う
- 関数は可変引数を取ることが出来る。可変引数は配列になる
- 関数は入れ子に出来る(関数中のコードが長いあるいは複雑な場合に利用する)
- 入れ子になった関数は、外側の関数で宣言された変数にアクセスできる
func greaterThanN(n: Int) -> (Int -> Bool) { func gt(x: Int) -> Bool { return n < x } return gt } func get1st(#condition: (Int -> Bool), #targets: Int[]) -> Int?{ for item in targets { if condition(item) { return item; } } return nil } let greaterThan300 = greaterThanN(300) let squares = [11*11, 12*12, 13*13, 14*14, 15*15, 16*16, 17*17, 18*18, 19*19] get1st(condition: greaterThan300, targets: squares)
- 関数は、戻り値として関数を返すことが出来る
- 関数は引数として関数を取ることが出来る
- 関数をとるパラメーターの型には(引数の型 -> 戻り値の型)を指定する
クロージャー
- クロージャーは、一連の処理の塊をオブジェクトとして扱えるようにしたものである
- 他の言語では、関数ポインターとかラムダとかと似たようなものである
var numbers = [4, 6, 8, 9] numbers.map({ (x: Int) -> Int in return x * x }) numbers.map({ number in 3 * number }) sort([1, 5, 3, 12, 2]) { $0 > $1 }
- 名前なしクロージャーは、コードを{}で囲うことで書ける
- 戻り値と本体を分けるためにinを使う
- クロージャーを簡潔に書くための方法
- クロージャーの型が既知の場合(委譲のコールバックなど)、パラメーターの型や戻り値の型を省略できる
- 1文のクロージャーは、暗黙にその一文の値を返す
- 名前ではなく番号で引数を利用できる
- 最後の引数として渡すクロージャーは括弧の直後にも置ける
標準ライブラリを使いこなす
Swift標準ライブラリリファレンス(Swift Standard Library Reference)
https://developer.apple.com/library/prerelease/iOS/documentation/General/Reference/SwiftStandardLibraryReference/index.html
今のところSwiftのライブラリとしては下記のものがあり、まだ少ないですが、これから充実していく予感がします
- 型:String、Array、Dictionary、数値型
- プロトコル:Equatable、Comparable、Printable
- Free Function:Printing(printとprintln)、Algorithm(sort)
SwiftでのiOSアプリ開発 - はじめの一歩
iPhone上のボタンを押すと押した回数が表示されるアプリを作ってみます
プロジェクトを用意
- Xcode 6 betaを起動する
- メニュー:File > New > Project
- テンプレート選択ダイアログ: ①左枠iOS直下のApplication > ②右枠のSingle View Application > ③Next
- オプション選択ダイアログ
- Project Name: 本当はなんでもよいがとりあえずMyFirstSwiftApp
- Organization Name:適当に入れて下さい
- Organizatin Identifier:適当に入れて下さい
- Language : Swiftを選択
- Device : とりあえずiPhoneを選択
- 保存場所ダイアログ:どこでもよいがとりあえず左側のDocumentをクリック > Create
GUIパーツの配置
- 左カラムのMain.storyboardをクリック
- 真ん中カラムにiPhoneの画面的なものが出てくる
- 右カラム下をスクロールしてLabelを探す > Labelを真ん中カラムのView Controllerの中にドラッグ&ドロップ
- 右カラム下をスクロールしてButtonを探す > Buttonを真ん中カラムのLabelドロップ位置周辺にドラッグ&ドロップ
GUIパーツとコードの結びつけ
- ウインドウ右上に四角いアイコンが6個あるうちの左から2個目(マウスオーバーするとShow the assistant editorとなる)をクリック
- 画面が分割され、左側はiPhone画面的なもの、右側はコードエディターになる
- controlを押しながらiPhone画面的なものにあるLabelをドラッグ > 右側コードのclass定義の内側一番下にドロップ > 出てきたダイアログのNameにlabelと入力 > connectクリック
- controlを押しながらiPhone画面的なものにあるButtonをドラッグ > 右側コードのclass定義の内側一番下にドロップ > 出てきたダイアログで下記入力 > connectクリック
- connection : Actionを選択
- Name : countUpと入力
- Argument : Noneを選択
- その他はいじらずにそのまま
Swiftコードの記述
- countUpの上に追加するコード
var count = 0
- countUp内に追加するコード
self.count += 1 self.label.text = String(self.count)
動作確認
- ウインドウ左上の再生ボタンを押す
- ビルドが成功するとiOSシミュレーターが起動する
- ビルドが失敗すると、エラーになったところが赤く表示されるので直しましょう
- Buttonを何回かクリックしてみる
- クリックするたびにLabelの文字がカウントアップされましたか?
SwiftでのiOSアプリ開発で、GUI作成は従来のObjective-Cを使った方法と基本的には同じなので、さらに深めたい方は書籍などを読んで進めて下さい。
絶対に挫折しない iPhoneアプリ開発「超」入門【iOS7対応】増補改訂版
Swift日本語チュートリアル ~ 後編(Apple公式ドキュメントSwift Tour±α) - こんにゃくマガジンにつづく
後編の内容は、クラス、列挙、構造体、ジェネリクス、簡単なネットワークライブラリの使い方、ちょっと進んだSwiftでのiPhoneアプリ開発、コマンドラインでのSwiftの使い方となっています。
編集後記
今までネット上の技術ドキュメントに関しては完全なROMだったのですが、
こうして初めて自分で書いてみてなかなか大変な作業だなぁと思いました。
今まで参考にさせて頂いたネット上のドキュメントの執筆者の方々に
この場を借りてお礼を申し上げたいと思います。
ありがとうございました。
ところで、最近、残業が多く、ちゃんと寝たつもりでも疲れが抜けなかったので、「もっと快眠できるように布団を買い直そう!」と思い、浅田真央さんがTVCMをしているAirWeaveを買ってみました。
すごく快適に寝られるようになりました。AirWeave、お勧めです!