コンユウメモ @kon_yu

作ったガラクタとか、旅行とかの話

SugarRecordでCoreDataを簡単に扱え

https://github.com/SugarRecord/SugarRecord/raw/develop/resources/Slogan.png

はじめに

SugarRecordとはアプリ内のDBを簡単に使えるようにするよっていうもの Objective-CのCoreDataのラッパライブラリであるMagicalRecordのSwift版みたいなもん、注目すべきはRealmに対応しているところ。 今回はRealmではなくCoreDataでデータ書き込み/取得する方法を記す

サンプルコードはこちら

konyu/SugarRecordSample · GitHub

Xcodeのプロジェクトを作る

Core Dataのチェックを入れるのを忘れないように

f:id:kon_yu:20150126224146p:plain

Podfileを作る

ブランチ指定しているのは、masterだと取得したデータをイテレータで取得できないバグが有るため。(2015/1/25現在)

作成したプロジェクトのルートディレクトリに行く

> cd  SugarRecord
> emacs Podfle

Podfile

source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'
pod 'SugarRecord/CoreData', :git => 'https://github.com/SugarRecord/SugarRecord.git', :branch => 'develop'

cocoapodsのswift対応版の0.36のpre版のインストール方法は、前のポストを参照

pod installでインストール

> pod --version
0.36.0.beta.1

> pod install

cocoapodsを利用したファイル群と、SugarRecordのライブラリが追加される Xcodeでxcworkspaceファイルを開くようにする

> open SugarRecordSample.xcworkspace

CoreDataの準備

CoreDataの設定ファイルSugarRecordSample.xcdatamodeldを開く

SugarRecordの準備

Stackというモノを生成して、SugareRecordのクラスメソッドに食わせる

//import lib CoreData and SuparRecord
import CoreData
import SugarRecord

class ViewController: UIViewController {
    let model: NSManagedObjectModel = {
        let modelPath: NSString = NSBundle.mainBundle().pathForResource("SugarRecordSample", ofType: "momd")!
        let model: NSManagedObjectModel = NSManagedObjectModel(contentsOfURL: NSURL(fileURLWithPath: modelPath)!)!
        return model
        }()
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // init SugarRecord with CoreData
        let stack = DefaultCDStack(databaseName: "SugarRecordSample.sqlite", model: self.model, automigrating: true)
        // persistence setting
        (stack as DefaultCDStack).autoSaving = true
        SugarRecord.addStack(stack)
        
    }

SugareRecordで書き込み

Userオブジェクトを生成して、属性を設定し保存、これでCoreDataを通してSqlLiteに書き込みされる すごい簡単RailsActiveRecord

    // write record method
    func writeRecord(i : Int) {
         // オブジェクトの生成
        let user = User.create() as User
         // 属性の設定
        user.name = "test" + i.description
        user.age = 1 + i
        user.email = "test@test.com"
         // CoreDataに保存
        user.save()
    }

SugareRecordで読み込み

読み取りの場合は、読み取る条件を指定して、結果取得用のオブジェクトSugarRecordResultsを取得する 取得したデータの取り出し方は、イテレータを使う方法と、配列の添字を指定して取得する方法がある

イテレータを使う方法は、一つ前のエントリーでオレが修正して取り込んでもらったばかりなのでマスターブランチでは使えないので注意が必要だ http://konyu.hatenablog.com/entry/2015/01/25/175839

    // read records method
    func readRecords() {
        var names : [String] = []
        var emails : [String] = []
        var ages : [NSNumber] = []
        
       // age属性をASCでソートしたUserオブジェクトの結果を取得
       // 取得した形式はダタの配列ではなくSugarRecordResultsオブジェクト
        // get records with SugarRecord
        // ascending : true is ASC, false is DESC
        let results : SugarRecordResults = User.all().sorted(by: "age", ascending: true).find()
        
        // 取得結果からオブジェクトを取る方法として、最初と最後を取る方法はこれ
        let firstObj : User = results.firstObject() as User
        let lastObj : User = results.lastObject() as User
        
       // イテレータを利用してデータを取り出す方法はこちら
        // get date with iterator
        // イテレータを取得する
        let iterator = results.generate()
       // nextメソッドで一つづつ順番にオブジェクトを取り出せる
        while let record: AnyObject = iterator.next() {
            let data = record as User
            names.append(data.name)
            emails.append(data.email)
            ages.append(data.age)
        }
        
         // for文で愚直に取るにはこちら
        // get date with for-loop
       // countで取得結果の数を得られ、取得結果[num]で取得結果からオブジェクトを取り出す
        for ( var i = 0; i < results.count; i++ ){
            let data = results[i] as User
            names.append(data.name)
            emails.append(data.email)
            ages.append(data.age)
        }
        
        
        // show result
        println("-----------")
        println(names)
        println(emails)
        println(ages)
    }

これでCoreDataの実装で面倒な思いをしなくても良くなるはず。 まだまだ出来立てのライブラリなのでエンタープライズ向けで使うのは時期尚早だと思うけど 個人アプリ程度ならつくかって見てもいいのでは。