問題タブ [ensembles]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
ios - Core Data と Ensembles (iCloud) を使用して重複に近いものを削除する
概要
私の問題は、 Ensemblesを使用して iCloud と同期するCore Data ベースの iOS プロジェクトでほぼ重複するものを取り除きたいということです。
- 私のアプリでは、iCloud との同期は基本的にうまく機能します。
- 問題は、永続ストアが (iCloud に接続された) Ensembles によってリーチされる前に、ユーザーが複数のデバイスで同様のオブジェクトを作成する場合です。
- これにより、事実上正しいほぼ重複が生成されます。
- これらの重複を削除する私のアプローチはうまくいかないようです。
詳細な問題
ユーザーはNSManagedObjects
、iCloud に接続する前に、さまざまなデバイスで作成できます。彼が と"対多" の関係を持つ名前付きに対して "対 1" の関係を持つNSManagedObject
名前を持っているとしましょう。これは次のようになります。
Car
NSManagedObject
Person
Car
ユーザーが 2 つのデバイスを持っていてNSManagedObjects
、各デバイスに 2 つ作成するとします。Car
「アウディ」という名前Person
と「ラファエル」という名前。両方が関係を通じて接続されました。もう一方のデバイスで、彼はCar
「BMW」という名前のデバイスPerson
と「Raphael」という名前の別のデバイスを作成します。また、相互に接続されています。これで、ユーザーは各デバイスに 2 つの類似したオブジェクトを持ちます:Person
両方とも「Raphael」という名前の 2 つのオブジェクト。
私の問題は、ユーザーがPerson
同期した後、各デバイスに「Raphael」という名前のオブジェクトが 2 つあることです。
ユーザーが永続ストアをリーチすると、オブジェクトは (アンサンブル内のオブジェクトを識別するために) uniqueIdentifiers を取得するため、これは実際には正しいです。オブジェクトは実際には異なります。しかし、これは私が修正したいものです。
私のアプローチ
このデリゲート メソッドを実装し、reparationContext の重複を削除しました。
基本的に、これは最初のデバイスからのデータをマージする 2 番目のデバイスでうまく機能するようです。残念ながら、reparationContext で削除された場合でも、ローカルの人はまだ iCloud に同期されているようです。
これは、最初のデバイスが 2 番目のデバイスからの変更をマージし、2 番目のデバイスで既に削除された人を再び置き換えるため、壊れた状態につながります。後でいくつかの同期を行うと、車の関係でその人が最終的に行方不明になり、アプリは同期エラーをスローします。
問題を再現する手順
ステップ 1 (デバイス 1)
- オブジェクトを作成する
- データ: 車「アウディ」 -> 人「ラファエル (デバイス 1)」
ステップ 2 (デバイス 2)
- オブジェクトを作成する
- データ: 車「BMW」 -> 人物「ラファエル (デバイス 2)」
ステップ 3 (デバイス 1)
- ストアからのリーチ データ
- iCloudに接続
- iCloudにデータを送る
- データ: 車「アウディ」 -> 人「ラファエル (デバイス 1)」
ステップ 4 (デバイス 2)
- ストアからのリーチ データ
- iCloudに接続
- iCloud からのデータをマージする
- デバイス 2 のローカルの人をデバイス 1 の挿入された人に置き換えます
- デバイス 2 からローカルの人を削除する
- iCloudにデータを送る
- データ:
車 "Audi" -> 人物 "Raphael (Device 1)"
車 "BMW" -> 人物 "Raphael (Device 1)"
ステップ 5 (デバイス 1)
- iCloud からのデータをマージする
- デバイス 1 のローカルの人をデバイス 2 の挿入された人に置き換えます (これは発生しないはずです)。
- デバイス 1 からローカルの人を削除します (これは発生しないはずです)。
- iCloudにデータを送る
- 期待されるデータ:
車 "Audi" -> 人 "Raphael (Device 1)"
車 "BMW" -> 人 "Raphael (Device 1)" - 実際のデータ:
車 "Audi" -> 人物 "Raphael (Device 2)"
車 "BMW" -> 人物 "Raphael (Device 2)"
実際にはステップ 4 でローカル人物オブジェクト「Raphael (Device 2)」が削除されましたが、ステップ 5 でデリゲート メソッド savingContext.insertedObjects
から挿入としてポップアップされるため、iCloud に送信されたままになっているようです。shouldSaveMergedChangesInManagedObjectContext
私が理解している限り、Ensembles は最初に iCloud から変更を取得し、デリゲート メソッドを介してすべてが期待どおりかどうかをユーザーに尋ね、次に永続ストアにマージし、マージ後にデルタを iCloud に送信します。
私は何か間違ったことをしていますか?それとも、これは Ensembles のバグですか?
ios - XCode がサードパーティ ライブラリのヘッダーを見つけられない
Ensembles 2 フレームワークを iOS プロジェクトに追加しようとしています (オープン ソースの Ensembles 1 から切り替えると、v2 はオープン ソースではないため、コードやココア ポッドにアクセスできなくなります)。
私はインストール手順を要点まで従ったと思います:
- フレームワーク (および .bundle) にドラッグ
- ターゲットと「アイテムのコピー」が選択されていることを確認
- -ObjC が設定されていることを確認しました
XCode はフレームワークを $(PROJECT_DIR) にコピーします。この $(PROJECT_DIR) は、 (他のディレクトリの中でも) Framework Search Pathsにも設定されています。<Ensembles/Ensembles.h>
いくら探しても見つからないようです。SO などで同様の質問を検索し、フレームワーク検索パス設定とヘッダー検索パス設定のさまざまな組み合わせを試しましたが、これまでのところ成功していません。具体的に私が試した
- 既存のフレームワーク検索パス設定からの引用符の追加と削除
- 再帰設定で遊ぶ
- Frameworksサブディレクトリを作成し、そこにフレームワークを追加します。次に、フレームワーク検索パスとヘッダー検索パス(再帰的および非再帰的の両方)に追加
"$(SRCROOT)/Frameworks
します。 - ヘッダー検索パス
"$(SRCROOT)/Frameworks/Ensembles/Headers"
への追加 - フレームワークの削除、クリーニング、および再追加を複数回行う
これはイライラしています。他のアイデアはありますか?私はXCode 7.2.1 btwを使用しています。
ios - アンサンブルとコア データ ライト マイグレーション
私は現在、Ensembles を使用していくつかのテストを行っています。具体的には、Core Data ライトの移行をテストしています。
私の現在の構成は次のとおりです。
- データ モデル 1 でアプリを実行しているデバイス A
- データ モデル 2 でアプリを実行しているデバイス B
- データ モデル 2 はデータ モデル 1 に基づいており、オプションの文字列プロパティが 1 つ追加されています。
私のシナリオは次のとおりです。
- 最初に、デバイス A とデバイス B の両方でデータ モデル 1 を使用してアプリを実行すると、Ensembles (iCloud 構成) を使用してすべてが正常に同期されました。
- デバイス B で、データ モデル 2 を使用して更新したアプリをインストールして実行します
- デバイス A で、データ モデル 1 を使用して古いアプリを実行し続け、新しいレコードを追加します
- 結果: デバイス A に追加された新しいレコードが iCloud にアップロードされ、デバイス B に同期されます。
私の質問: 関連するデータ モデルが最新のものでない場合に、変更が iCloud にアップロードされないように Ensembles を構成できますか? (つまり、私の場合、デバイス A はデータ モデル 1 に基づいてオブジェクトをアップロードしますが、iCloud は既にデータ モデル 2 に基づいています)
前もって感謝します!
更新 1:
ドリューさん、ご回答ありがとうございます。Ensembles は分散型のピア ツー ピア システムであるため、アップロードを防止できない (そしておそらく防止すべきではない) ことに、私は間違いなく同意します。
理想的には、新しいデータ モデルを使用するデバイスが、古いデータ モデルに基づくデータを無視するようにしたいと考えています。(古いデータ モデルを持つデバイスが新しいデータ モデルに基づくデータを無視する既存の動作と同様の方法で)。それはサポートされていますか?
そうでない場合は、次のシナリオを例として検討してください。
- 古いデータ モデルには、タイトルと作成者の 2 つのプロパティを持つ「Book」というエンティティがあります (両方のフィールドはオプションではありません)。
- 新しいデータ モデルには、タイトル フィールドの最初の文字を保持する必要がある、titleFirstLetter と呼ばれる新しいオプション プロパティがあります。
現在、Ensembles が関与していない場合は、新しい NSManagedObject を永続ストアに保存するときに完全に制御できます。したがって、新しい本の追加を担当するアプリの更新されたコードは、タイトル フィールドから最初の文字を抽出し、それを新しい titleFirstLetter プロパティに保存するようにします。(つまり、Catch-22 というタイトルの本は、本が保存されると、titleFirstLetter プロパティに C が含まれます)。
さらに、コア データ スタックで軽度の移行が発生すると、それを検出し、データベース内の既存のすべての本を反復処理する 1 回限りの手順を実行し、タイトルの値に従って titleFirstLetter を設定します。この時点以降、データベースは一貫性があり有効であり、新しいコードにより、データベースに追加された将来の本がデータベースを有効に保つことが保証されます。
Ensembles に関して、古いデータ モデルを持つデバイスからの古いデータを制御できない場合、コードが呼び出されない場合、titleFirstLetter の新しいプロパティをどのように入力できますか?
親切なお力添えありがとうございます!
ios - アンサンブルと journal_mode="DELETE"
現在の Core Data スタックは、次のように journal_mode="DELETE" で構成されています。
このコードは、Core Data に (WAL モードの 3 つの異なるファイルではなく) 1 つの sqlite ファイルを作成するように強制します。これにより、sqlite データベースをユーザーの Dropbox にバックアップおよび復元する際の作業が楽になります。(3 つではなく 1 つのファイルのみをバックアップまたは復元する必要があります)
Ensembles コードを追加すると、NSSQLitePragmasOption がオーバーライドされ、カスタムの DELETE ジャーナル モードが削除されるようです。Ensembles コードを追加した直後から、1 つではなく 3 つの sqlite ファイルが生成されていることがわかります。
これは、アンサンブルの既知の要件/動作ですか? Ensemble は WAL ジャーナル モードでのみ正しく機能しますか? それとも、DELETE ジャーナル モードを使用するように構成できますか?
前もって感謝します。
ios - アンサンブル: 画像にはどのタイプのグローバル識別子を選択すればよいですか?
現在、persistentStoreEnsemble:globalIdentifiersForManagedObjects: デリゲートを実装しており、提供するグローバル識別子を決定するのが困難です。
私の Core Data モデルには、book と image の 2 つのエンティティがあります。
ブック オブジェクトの場合、おそらく UUID を返す必要があるため、問題はありません。UUID は、ブックの専用プロパティに格納する必要があります。
ただし、画像のグローバル識別子についてはわかりません。イメージ エンティティとブック エンティティは、データ モデル内で 1 対 1 の関係にあり、「カスケード」削除ルールが適用されていることに注意してください。これは、ブックが削除されると、リンクされたイメージも削除されることを意味します。したがって、書籍にリンクされていない画像はデータベースに存在できません。
上記の説明に基づいて、特定の画像オブジェクトのグローバル識別子として、NSNull、UUID、またはハッシュ コード (画像データから実行時に計算される) を返す必要があるかどうか疑問に思っていました。
提案をありがとう。
ios - Ensembles のマージ中は永続ストアへの保存を避けるべきですか?
現在、Ensembles を使用して Core Data 同期を実装しています。CDEPersistentStoreEnsemble のマージ中に、ユーザーが Core Data に保存できないようにする必要があるかどうか疑問に思っていました。
mergeWithCompletion のメソッドのドキュメントのために、私はこれを求めています:
マージは、ファイルのダウンロードが不完全だったり、永続ストアへの保存によってマージが中断されたりするなど、さまざまな理由で失敗する可能性があります。通常、マージ中のエラーはそれほど深刻ではないため、少し後でマージを再試行する必要があります。エラー コードは、CDEDefines にあります。
-(void)mergeWithCompletion:(CDECompletionBlock)completion;
ios - そのようなモジュール「アンサンブル」エラーはありません-迅速なプロジェクトで使用する目的のcフレームワークをインポートしています
私は Swift プロジェクトにアンサンブルを追加しています - https://github.com/drewmccormack/ensemblesにあります。アプリにiCloudサポートを追加してデバイス間でデータを同期することができなかったので、これがうまくいくことを願っています.
フレームワークをアプリに追加するための次の手順に従いました。
- Finder で、Ensembles iOS.xcodeproj プロジェクトを Framework ディレクトリから Xcode プロジェクトにドラッグします。
- 左側のソース リストでアプリのプロジェクト ルートを選択し、アプリのターゲットを選択します。
- [全般] タブで、[リンクされたフレームワークとライブラリ] セクションの [+] ボタンをクリックします。
- libensembles.a ライブラリを選択して追加します。
[ビルド設定] タブを選択します。Other Linker Flags 設定を見つけて、フラグ -ObjC を追加します。
これが私のプロジェクトでの外観です。この手順を正しく行ったかどうかはわかりません。
- [ビルド フェーズ] タブを選択します。[ターゲットの依存関係] を開き、[+] ボタンをクリックします。
- Ensembles Resources iOS 製品を見つけて、それを依存関係として追加します。
- ソース リストで Ensembles iOS.xcodeproj プロジェクトを開き、Products グループを開きます。
- Ensembles.bundle プロダクトをアプリの Copy Bundle Resources ビルド フェーズにドラッグします。
- プリコンパイル済みヘッダー ファイル、または Ensembles を使用する任意のファイルに、次のインポートを追加します。
私が問題を抱えているのはステップ10です。ブリッジング ヘッダーを作成するか、フレームワークを Swift ファイルにインポートする必要がありますか?
CoreDataStack.swift
これは、ファイル内でインポートする方法です
これによりエラーが発生します。
そのようなモジュール「アンサンブル」はありません
次のようにして、ブリッジヘッダーを作成してみました。
- 新しいヘッダファイルを追加
- アンサンブルのインポート
これがその外観です。
私の迅速なプロジェクトで使用するためにフレームワークをインポートしようとするときに、どこが間違っているのか誰かが知っていますか?
ios - Swift プロジェクトで Ensembles フレームワークを使用する方法
Core Data を既に使用しているプロジェクトがあります。iPad のサポートを追加しましたが、データを同期するには iCloud と Core Data を使用する必要があります。
Ensembles に出会いました。プロジェクトに追加するのは簡単で堅牢なフレームワークのようです。ここにあります: https://github.com/drewmccormack/ensembles
ただし、Ensembles プロジェクトには Swift のサンプル プロジェクトがないため、自分でやろうとしました。ここに私が取ったステップがあります、
ステップ1
アンサンブルを iOS プロジェクトに手動で追加します。
ステップ2
既存の永続ストア .sql ファイルを使用して、新しい CoreDataStack を作成します。
ステップ 3
App Delegate を更新して同期し、通知を追加する
ステップ 4
プロジェクトに通知を追加して UI を更新する
ステップ 5
魔法が起こるのを見てください。残念ながら、魔法の ATM はありません。新しい CoreDataStack は正常に動作し、永続ストアからデータを保存および取得できます。
同じ iCloud アカウントにログインしている 2 つのデバイスがあり、どちらのデータも他のデバイスと共有されていません。
アプリを削除して再インストールすると、データは iCloud から取得されず、永続ストアに保存されます。
NSLog
「時々」データを保存したり、アプリをロードしたりすると、次のようになります。
これは、次の appDelegate 通知関数の結果です
変更がマージされると、CoreDataStack のこの関数から通知が送信されます。
したがって、すべてが正常に機能するはずです。エラーは発生しませんが、データが同期されていません。問題が iCloud へのデータのバックアップなのか、それとも iCloud からの取得と永続ストアとのマージなのかはわかりません。私が言えることは、同じ iCloud アカウントを使用しているデバイス間でデータが共有されておらず、アプリを再インストールするときにアプリが実際に iCloud からデータを復元していないということだけです。
ios - iOS 用のアンサンブル: どのタイプの iCloud バックエンドを使用すればよいですか?
ユーザーが組み込みの iCloud アカウントを使用して同期できるように、Ensembles ベースのアプリで iCloud バックエンドをサポートしたいと考えています。ただし、iCloud Drive バックエンドと CloudKit バックエンドのどちらを使用する必要があるかはわかりません。どちらもユーザーの iCloud アカウントを使用して同期できるようです。
使用するバックエンドに関する提案はありますか?
私のアプリには iOS 8.0 以降が必要です。
前もって感謝します。