アプリのローカルにRealmを作って、そこにデータをいれこんで検索等を行う必要があり、やってみました。シミュレーター(iOS8.4)で確認しただけなので、そこは悪しからず..
使ってるライブラリ
- Realm
- ObjectMapper ~> 0.16
- Alamofire ~> 2.0
RealmはCocodPodsで、それ以外はCarthageで入れました。ドキュメント見たら、RealmのSwift2.0用はCarthageで入らないそうなので。
モデルの宣言
AlamoFireで取得したJSONをオブジェクトにする為に、ObjectMapperを差し込んでおります。Realmオブジェクトでも簡単にシリアライズ出来ます。
Item.swift
import ObjectMapper
import RealmSwift
class Item: Object,Mappable {
dynamic var item_id = 0
dynamic var itemcode = ""
dynamic var name = ""
dynamic var lot = 1
dynamic var price = 0
dynamic var jancode = ""
required convenience init?(_ map: Map) {
self.init()
}
func mapping(map: Map) {
item_id <- map["item_id"]
name <- map["name"]
price <- map["price"]
lot <- map["lot"]
jancode <- map["jancode"]
itemcode <- map["itemcode"]
}
}
ViewController
やってることは下記の通りです。データ数は1万件。
- AlamofireでJSONを取得
- ObjectMapperでRealmオブジェクト配列にパース
- 初期化したいので、Realmを全部削除
- 2で取得した配列を1件ずつbegin→add→commit
ViewController.swift
import UIKit
import ObjectMapper
import Alamofire
import RealmSwift
class LoginViewController: UIViewController {
@IBOutlet weak var btn: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
btn.addTarget(self, action: "btnPressed:", forControlEvents: .TouchUpInside)
let json_url = "http://fkcorporation.co.jp/files/sample_10k.json"
//1.
Alamofire.request(.GET, json_url).responseJSON { _, _, result in
//2.
if let item_data_arr:[Item] = Mapper<Item>().mapArray(result.value) {
do {
let realm = try Realm()
//3.
realm.beginWrite()
realm.deleteAll()
try realm.commitWrite()
//4.
for v in item_data_arr {
realm.beginWrite()
realm.add(v)
try realm.commitWrite()
}
} catch {
}
}
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func btnPressed(sender:AnyObject?) {
do {
let realm = try Realm()
let records:Results = realm.objects(Item).filter("itemcode BEGINSWITH '0'").sorted("itemcode")
for v in records {
print(v) //Itemオブジェクトがprintされる
}
} catch {
}
}
}
よくわかってないこと
- Realmのコンストラクタ並びにcommitWriteにthrowsがあるので呼び出し時にtryをつけるのだけど、どんなエラーをcatchしたら良いのか。RealmException的なものが分からなかった。このままでは握りつぶしてしまっているで...
- 全削除→複数件INSERTをする際には、2回トランザクションを開始するものなのか。
- realmオブジェクトはメンバ変数でも..って思ったけどバックグラウンドでスレッド立てた時に同期されなそうだから、使う時に都度インスタンス生成したほうが良さげ。 ファクトリーメソッド的なものは必要かな。do-try-catchの散在はだるい。
とりあえずこれで動いたので、ローディングウインドウを出して、そのコールバックで上記初期化処理を行うように作って、リファクタリングに移行したいと思います。