2016-07-06 4 views
4

CKRecordrecordTypeの投稿を持っているとします。投稿には、タイトルや説明などのいくつかの値があります。投稿がアプリに表示されると、それを書いたユーザーの名前とプロフィールの図が表示されます(ライターと呼ぶ)。私の質問は、CKReferenceをライターのプロファイルに保存する方が良いでしょうか(プロファイルはライターの詳細を保持する別のタイプのレコードです)、ライターの詳細を投稿時に直接投稿する方が良いでしょうか?CKReference vs. CKRecordを使用したCloudKitのパフォーマンス

最初のオプションはデータベーススキーマの観点からは理にかなっていますが、パフォーマンスの観点からは本当に悪いようです。このシステムには何千人ものユーザーがいるため、フェッチの量とそれらをロードする時間はすべて不合理なようです。

最初の部分はすべての投稿を読み込むことです。クエリが行わ

func loadPosts() { 
    // ...Setup the query 
    publicData.performQuery(query, inZoneWithID: nil) { (results: [CKRecord]?, error: NSError?) in 
     if let posts = results { 
      self.loadProfiles(posts) 
     } 
    } 
} 

一つは、今、私たちは、私たちはreferenceIDsをつかん時間を費やし、その関数で

func loadProfiles(posts: [CKRecord]) { 
    // Get the reference IDs out of the Posts 
    var referenceIDs = [CKRecordID]() 
    for post in posts { 
     // Get the reference from the post 
     // Append the recordID to the referenceIDs array 
    } 

    // Perform the Profiles fetch 
    let fetchOperation = CKFetchRecordsOperation(recordIDs: referenceIDs) 
    fetchOperation.fetchRecordsCompletionBlock = { records, error in 
     // ...Handle the fetched Profiles 

     // Everything has been fetched, update the UI now 
     dispatch_async(dispatch_get_main_queue(), { 
      self.tableView.reloadData() 
     }) 
    } 
    CKContainer.defaultContainer().publicCloudDatabase.addOperation(fetchOperation) 
} 

loadProfilesと呼ばれます。その後、プロフィールの取得に時間を費やしました。元のポストフェッチの後で、これがすべて起こっていることを覚えておいてください!

... Yikes。何らかのキャッシュシステムがあっても、オリジナルのフェッチは狂っているでしょう(特に多くのユーザーがいると)。

したがって、書き込み時に投稿者の詳細を投稿に直接追加する方が良いでしょうか?これの長所:フェッチが少なく、読み込みが高速です。これの短所:ライターがプロフィールの詳細を変更した場合、アプリはすべての投稿をループして詳細を手動で更新する必要があります。

このジレンマ全体があなたの毒のシナリオを選んでいます。これを行うより良い方法はありますか?

+0

私は絶対に参考にしたいと思います。いくつかのタイプのローカルキャッシュシステムを作成し、それがバージョンと異なる場合は各自のデータを取得し、おそらくサブスクリプション通知を通じて更新します。それはおそらくこれがこの質問のための最善のフォーラムではないと言われていますが、あなたはプログラマーにもっと良い運を与えるかもしれません.stackexchange.comまたはアップルのdevフォーラム。 –

+0

@thefredelement永続的なストアを更新するための何らかの通知を持つCore Dataは理にかなっています。ただし、元のフェッチはまだ長くなります。コードレベルの実装があるので、私はプログラマーよりもStackOverflowを選択しました。私は広い構造を完全に見直すことなく、これを再構築するより良い方法があると期待しています。 –

+0

CloudKitサブスクリプションをチェックすると、フェッチされた結果コントローラを持つコアデータを含むサブスクリプションのコンボを使用して、すばらしいソリューションを利用できます。 1つは、バックグラウンドでいくつかのデータを更新することさえできます。 –

答えて

5

説明しているトレードオフの語はdenormalizationです。あなたが描くジレンマです。トレードオフの重み付けは、基礎となるテクノロジとアプリケーションドメインと予想される動作の両方に依存します。

2つのモデルオブジェクト、投稿とプロフィール、投稿のプロフィールへのライター参照を記述しました。あなたは彼らの使い方を正確には説明していませんが、リスト内の各セルの作者名とプロフィール画像を使って、スクロールする投稿のリストをテーブルビューで表示します。なぜそれぞれのリファレンスを引っ張るのが心配なのかは明らかです。

CloudKitの優先順位は、サーバーへの往復回数を最小限に抑えることです。しかし、1つのポストを取得し、2つ目にそのリンクされたプロファイル名を取得することは、特に煩わしいことではありません。 非常に重要:ここでフェッチやクエリにdesiredKeysプロパティを使用してください。 CloudKitは、デフォルトではレコード全体を取得し、あなたはおそらく、それがユーザーの名前を、ユーザー取得取得、完全なプロファイルをとの違いだwire--の上に余分な情報を渡すことになります。

可能であれば、desiredKeysを使用するポイントは、最適化の重要性や実装の簡素化に関して、ドキュメントでは十分に解りません。

しかし、あなたはより多くの、あなたが非正規化したい場合があります引っ張っている間、ユーザが待っているされようとしている場合など、投稿を引いたときに応答することを懸念している場合。

プロファイルも頻繁に変更されないと仮定します。これは重要なポイントですが、変更することができ、アプリはそれを考慮する必要があります。実際には非常にシンプルです:ポストをループして更新するのは理想的ではありませんが、それほど大したことではありません。あなたはCKQueryOperation/CKModifyRecordsOperationのペアでそれを行うことができるはずです。

さらに、desiredKeysを使用することをお勧めします。特に、すべての投稿の非正規化フィールドを更新するためにフェッチしていて、それを表示する予定がない場合、完全な内容を渡す必要はありません。すべてのポストをワイヤーで。

プロファイルピクチャで非正規化する場合は、同じCKAssetを使用していることを確認して、キャッシュに組み込まれ、誤って同じイメージを上下に送信したり、回。 CKAssetとローカルキャッシングの仕組みに関する注意点を参照してください。明らかにあなたがそれがローカルに格納されていることを保証したい場合は、自分でそれをキャッシュしなければなりません。

は、そしてそれは、これらすべてのCloudKitデータ型は、特にあなたのアプリでモデルオブジェクトとして使用されることになっていないをしていることに注意することは良い点だし、これはその層と相互作用する方法をあなたが作るものは何でも選択肢に影響します。

CloudKitは実際には素晴らしいですが、私の意見では、それは体系化されていないドキュメントで開催されています。私は今年WWDCに行くのに十分な運が良かった('16)、この情報の一部が提供されているCloudKitエンジニアと話すことができました。お役に立てれば。

+0

Ah gotcha思考!私はすでにフェッチごとに 'desiredKeys'を使用しています。私は、CKSubscription&Core Dataを見て、更新通知と永続ストアとして機能するようにしてください。 –

+0

@ShaanSingh CKSubscriptionも扱いにくく、Core Dataはそれ自身の獣です。これらはアプリケーション設計の質問であり、簡単な答えはありません。 ジレンマ(非正規化)についての質問に十分な回答が得られた場合は、回答を受け入れ済みとマークすることができます。ありがとうございます。 –

+1

私はすでにCore Data NSManagedObjectsを使って投稿、ユーザー、すべてを保持しています。コアデータは他のネイティブiOSキャッシングシステムにも明らかな利点があります。この回答は本当に非正規化に関する私の質問に答えるのを助けました。ありがとうございました。 –