28
29

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Swift2.0 + ObjectMapper + RealmでローカルDB構築に挑戦

28
Posted at

アプリのローカルに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万件。

  1. AlamofireでJSONを取得
  2. ObjectMapperでRealmオブジェクト配列にパース
  3. 初期化したいので、Realmを全部削除
  4. 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の散在はだるい。

とりあえずこれで動いたので、ローディングウインドウを出して、そのコールバックで上記初期化処理を行うように作って、リファクタリングに移行したいと思います。

28
29
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
28
29

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?