2014年11月14日金曜日

CloudKitでページング読み込み

皆様こんばんわ。
京都はすっかり朝夕冷え込んできまして、紅葉シーズン真っ盛りです。

さて、色々とスッといかないCloudKitさんですが、懲りずにまだやってます。

というわけで、今回はページング処理についてです。
前回も書きましたが、CloudKitはCKDatabase.perfomQueryにて一回で取ってこれる行数が100行までとなってます。少ない行数のクエリでしたらコチラのほうが楽ちんですが、普通はコレでは色々困るかと思います。

で、100件毎ページングしながら取ってくる、、という処理にするのですが、もちろん上のCKDatabase.perfomQueryでも自前でページング処理を書けば動きます。が、そんなの面倒くさい、、ということでCKQueryOperationの登場です。

簡単なサンプルを書きます。
------------------------------------------------------
// CKQueryCursorをクラス変数に持ちます
var cursor:CKQueryCursor?
// レコードを保持する配列
var records:[CKRecord] = []

func record_search() {
    // データベース接続です
    var db: CKDatabase! = CKContainer.defaultContainer().publicCloudDatabase

    // 条件です。
    var p:NSPredicate = NSPredicate(format: "id > 0")!

    // TableNameからレコードを取得します
    let q : CKQuery = CKQuery(recordType: "TableName", predicate: p)

    // CKQueryOperationの定義です
    var queryop : CKQueryOperation
    
    // ★ここがポイント、カーソルをチェックします。
    if self.cursor == nil{
        // カーソルがnil、すなわち最初のクエリ
        queryop = CKQueryOperation(query: q)
    } else {
        // カーソルがある状態(次のレコードを取ってくる)
        queryop = CKQueryOperation(cursor: self.cursor)
    }
    
    // 一回に取ってくる件数
    queryop.resultsLimit = 100
    
    // フェッチ毎の処理を書きます
    queryop.recordFetchedBlock = {(record:CKRecord!) -> Void in
       // 配列にCKRecordをAdd
        self.records.append(record)
    }

    // すべてのフェッチが終わった後の処理を書きます
    queryop.queryCompletionBlock = { (cursor:CKQueryCursor!, error:NSError!) -> Void in
        // カーソル状態を、クラス変数のカーソルに保持します。
        self.cursor = cursor
        // UITableViewのリロード処理
        dispatch_async(dispatch_get_main_queue(), { () -> Void in
            self.tblView.reloadData()
         })
    }        

    // dbに上記のCKQueryOperationをセットします。
    self.db?.addOperation(queryop)
}

------------------

という感じで、上記のようなメソッドを初期処理で呼ぶと最初のレコード100件が、そして、たとえばTableViewの下端に差し掛かった時に同じメソッドを読んでやれば次の100件を再度積み上げて行ってくれる、、、といった感じです。どうでしょう割とスッキリですね。

しかし、いまこのソースをテストしてみたら、Maxまでカーソルをフェッチしたらまた最初からレコードを繰り返し読んできて再度積み上げてくれる、、、という感じになってしまってます。今日はもう帰って晩御飯を作らないといけないのでまた次回までにバグを直します。ではさようなら。