40歳からのiPhoneアプリ開発奮闘記!?実践編

# 告知!

折角なので、ブログにまとめることにしました。

[まこネタ -Tech-](https://h7i.jp/category/computer/development/40yearsold-ios-develop) で読めます。よろしくね!

# 目次
* 2015/06/01 はじめに
* 2015/06/03 下準備とか 
* 2015/06/05 「画面とか面倒だぞ!?」
* 2015/06/06 Swift/GUIの初歩の初歩
* 2015/06/07 ボタンを押したら、[Realm](https://realm.io/)のREST機能で、jsonをゲットしよう!
* 2015/06/08 そもそも冷静に考える。本当に[Realm](https://realm.io/)なのか!?
* 2015/06/10 [SwiftData](https://github.com/ryanfowler/SwiftData)にハマりまくり

# はじめに
Macbook Pro 13 Retina 2015が届いて2週間。環境構築も進み、「そろそろはじめますか」という気持ちになった。

はい! 実践編スタートです。

# 下準備とか
とりあえず、作りたいアプリとして、LinuxのMySQLに登録されたデータを、何らかの方法で吸い上げて、iOSのローカルDBに登録し、そのローカルDBでうにゃうにゃやって、情報を表示するものです。

そのため、MySQLと交信する必要があるが、いろいろ調べると、流行は[REST(Representational State Transfer)](https://www.wikiwand.com/ja/REST)というものを使うようだ。ならば!と、数時間格闘し、FuelPHPでREST機能を設計・実装して、とりあえず1つのデータを抜き出せるようにした。まあ、そもそものMySQLに格納されるデータ作りに手間取ったんだが...

iOSのローカルDBは、[Realm](https://realm.io/)を利用するつもりなので、CococaPods を使えるようにする。Mac OS Xなら簡単。[Realm](https://realm.io/)は、RESTサーバと通信する機能もあるので、簡単に実装できると思っていた...

# 「画面とか面倒だぞ!?」
Swiftの言語仕様も理解していないし、iOSアプリの作り方も理解していない。これは困ったな～と思っていたら、Swiftには「Playground」というお試し環境があるようだ。
[Realm](https://realm.io/)のソースにあるサンプルをじっくり読み、「Playground」で試そうとして、エラーが(T.T)/ そもそも「import」が見えないとのこと。ググってみると、[Swift PlaygroundでCocoaPodsのライブラリを使う](http://qiita.com/banjun/items/f8a5df4ddef3e9d2405b)を見つける。なるほどーこういう事をしないといけないのね。
やってみよう...
...
....
.....エラーだ(T.T)/ どうも、サンプルがだめっぽい。よし、出直しだ!w

# Swift/GUIの初歩の初歩
[Xcode6/Swiftで、ボタンを押すとラベルが変わるだけのアプリを作る](http://qiita.com/Kta-M/items/087b3cc4bca1fbf6c77a) を参考に、ボタンを押したらラベルが変わるアプリを作る。えーこの程度もわからないのか、悲しい。まあ、超初心者だからな。

ザクッと。GUIパーツと、ソースを連携させる事が出来ない。なに、このアイコン。Xcode 6.3には無いぞ!(T.T) あー[View]→[Assistant Editer]→[Show Assistant Editer]で出るね。グイッと。

よしビルド。ほうほう。動きますな。とりあえず、こういう風にすると、GUIとソースの連携が出来るのね。

# ボタンを押したら、[Realm](https://realm.io/)のREST機能で、jsonをゲットしよう!
いきなり、難しい所を攻めてみる(苦笑)

環境は、こちら!
* Xcode 6.3.2 (6D2105)
* Realm Swift 0.93.1

```swift:ViewContoroller.swift
import UIKit
import RealmSwift

class ViewController: UIViewController {

    @IBOutlet weak var testLabel: UILabel!
    
    @IBAction func downButton(sender: AnyObject) {
        let url = NSURL( string: "http://search.twitter.com/search.json?lang=ja&rpp=20&q=%23AKB")!
        let response = NSData(contentsOfURL: url)!
        
        var buffer = [UInt8](count:response.length, repeatedValue:0)
        response.getBytes(&buffer, length:response.length)
        var datastring = String(bytes:buffer, encoding:NSUTF8StringEncoding)
        
        testLabel.text = datastring
    }

}
```
ボタンを押すと、REST連携でjson値をゲットして、testLabel が置換される"はず"!本来は、[Realm](https://realm.io/)のDB形式?に変換するんだろうけど、まだよく判らないから、こんな感じに。

# そもそも冷静に考える。本当に[Realm](https://realm.io/)なのか!?

REST連携で、DBに格納しようとしているが、本当にその部分は必要なのか?

iOSアプリで、データを更新した場合、REST PUTで送信するのが良さそうなので、実装は無駄にならないが、MySQLからデータを抜き出す場合、そんなにデータ量も多くないので、一括ダウンロードでも良いかも。
このパターンは、既に第一線でiOSアプリを開発しているエンジニアの方から聞いた情報。iOSアプリのローカルDBに、登録・更新をおこなうより、.sqliteファイルをダウンロードした方が速くね!?って。
その実装形態は一理あるなー。

と、言うわけで[Realm](https://realm.io/)以外も調べてみる。
* [FMDB](https://github.com/ccgus/fmdb) : A Cocoa / Objective-C wrapper around SQLite
* [SwiftData](https://github.com/ryanfowler/SwiftData) : Simple and Effective SQLite Handling in Swift
の2つが有名らしい。Swiftだと、[SwiftData](https://github.com/ryanfowler/SwiftData)が良いようだ。 > [SwiftでSQLiteを使う(SwiftData)](http://fisherman08.hateblo.jp/entry/2014/11/20/234638)

で、MySQLデータを簡単に、.sqlite ファイルに変換するのは、こちら > [mysql2sqlite.sh](https://gist.github.com/esperlu/943776)

Swiftで非同期ダウンロードが出来るようにする方法も調べないと。

# [SwiftData](https://github.com/ryanfowler/SwiftData)にハマりまくり

サンプル通り実装しているんだけど、値が取れない。なんでだーで、4時間を費やし、判ったことをまとめます。[mysql2sqlite.sh](https://gist.github.com/esperlu/943776)との連携部分も多いけどね。
* なぜか、varchar のデータが取れない。SQLite って、varcharも許容しているんだけど、SwiftData は値で値が取れませんでした。MySQLのvarchar部分を、text型に変更して、逃げました。
* [mysql2sqlite.sh](https://gist.github.com/esperlu/943776)で、日本語が化ける。これは、ソース内の mysqldump で「--default-character-set=binary」をつけると良いみたい。

まあ、こんな感じ。まだまだ、初心者丸出しですね〜