3

Coreデータを多用する「管理」ゲームを書きたいです。ゲームには、ユーザー/システムが変更できない、事前設定された事前定義されたデータセットが必要です。ゲームにデータをシードするために使用され、読み取り専用であることが意図されています。

私が挙げることができる最良の例はサッカーの管理ゲームですが、それは何でもかまいません。一部のサッカー管理シムでは、シナリオと事前設定されたデータセットが提供されます。

ユーザーがゲームを進めていくと、進行状況を保存/ロードしてコアデータに保存できます。

これに加えて、ユーザーは事前定義されたデータの更新を受信したり、シナリオパックのデータを購入したりできます。これはデバイスに保存されます。

したがって、複数の「コアデータデータベース」(はい、コアデータは厳密にはデータベースではないことを知っています)またはアプリが飛び込んで使用できる「バケット」が存在する可能性があります。

データのスキーマは変更されません。

だから私たちは持っています:

  1. ゲームのシードにのみ使用される事前定義されたデータ(デフォルトデータ)。
  2. ユーザーの現在のセーブゲーム。
  3. ユーザーがインターネットからシナリオをダウンロードしました。
  4. 問題:ユーザーが「シナリオ」でゲームを保存するとどうなりますか。
  5. 問題:すべてのシナリオとすべてのユーザーがコアデータに保存したゲームを追跡するにはどうすればよいですか?

これは、一度に複数のデータベースのように聞こえます。明らかに、ユーザーが作成できるセーブゲームの数を制限する必要があります。

これに対する代替ソリューションは、ユーザーのデバイスがデータのバックアップコピーをJSONまたはXMLでエクスポートすることです。これは「データの保存」として機能し、シナリオにもこの戦略を使用できます。明らかに、人々がXMLを介してゲーム内の統計を単純に変更することを防ぐために、ある種の暗号化が必要になります。

しかし、最初から、iOSデバイスでCoreデータを使用して複数のコアデータ「データベース」を処理するための最良の方法は何でしょうか。

御時間ありがとうございます

4

2 に答える 2

4

データモデルが同じである場合は、MOCをセットアップして、両方の永続ストアを使用することができます。一方は読み取り専用で、もう一方は読み取り/書き込みです。

または、ストアごとに個別のMOCを使用することもできます。

したがって、MOC / PSCのほぼすべての組み合わせを使用できるため、どのように使用するかが唯一の決定要因になります。

詳細については、こちらのドキュメントをご覧ください。


編集

この質問で与えられたリンクは死んでいます、他の誰かが別の削除された答えでこのリンクを提案しました。

于 2012-10-29T19:43:11.427 に答える
2

NB:これは古い質問ですが、それが説明する問題は時代を超えているので、今日質問が投稿されたかのように答えを書きました。

実際、これは複数のデータベースの必要性を示唆するものではありません。だから私たちは持っています:

1)ゲームのシードにのみ使用される事前定義されたデータ(デフォルトデータ)。

データを永続ストア(データベース)にロードするメソッドを記述します。ユーザーデフォルト、defaultDataHasBeenLoadedなどでフラグを設定し、appDelegataで確認します。

2)ユーザーの現在のセーブゲーム。

1対多の関係を持つUsersテーブルとGamesテーブルが必要です。Gamesテーブルで、isCurrentGame属性を追加します。

3)ユーザーがインターネットからシナリオをダウンロードしました。

今では面白くなってきています。そのためのインポート関数またはクラスが必要であり、それをバックグラウンドスレッドで実行する必要があります。そうすれば、新しいシナリオがインポートされている間、ユーザーはプレイを続けたり、スコアなどを確認したりできます。シナリオがインポートされると、ユーザーは通知と新しいシナリオに切り替える機会を受け取る必要があります。

これを行う最も効率的な方法は、iOS 10.0、macOS 10.12、tvOS 10.0、およびwatchOS3.0から利用可能なNSPeristentContainerを使用することです。NSPeristentContainerにデータモデルの名前を付けると、永続ストアが作成またはロードされ、persistentStoreCoördinatorとmanagedObjectContextが設定されます。

// AppDelegate.h or class header file
@property (readonly, strong, nonatomic) NSPersistentContainer *persistentContainer;
@property (readonly, weak, nonatomic) NSManagedObjectContext *managedObjectContext;


// AppDelegate.m or other implementation file
@synthesize persistentContainer = _ persistentContainer;
@synthesize managedObjectContext = _ managedObjectContext;

- (NSPersistentContainer *)persistentContainer
{
    @synchronized (self) {
        if (_persistentContainer == nil) {
            _persistentContainer = [[NSPersistentContainer alloc] initWithName:@"nameOfDataModel"];
            [_persistentContainer loadPersistentStoresWithCompletionHandler:^(NSPersistentStoreDescription *storeDescription, NSError *error) {
                if (error != nil) {
                    // Handle the error
                } else {
                    _managedObjectContext = _persistentContainer.viewContext; // NB new name for moc is viewContext!
                }
            }];
        }
    }
    return _persistentContainer;
}

NSViewControllerのappDelegateからコンテナーを使用するには、viewDidLoadに以下を追加します。

self.representedObject = [(AppDelegate *)[[NSApplication sharedApplication] delegate] persistentContainer]; 

// Use representedObject in bindings, such as:
[_gameNameTextField bind:NSValueBinding toObject:self
                  withKeyPath:@"representedObject.game.name"
                      options:options];

新しいシナリオをインポートするには、performBackgroundTask:を使用します。これは、新しいスレッドと新しいmanagedObjectContext(ここではmoc_backgroundと呼ばれます)を自動的に作成するブロックです。ブロック内で行うことにはすべてmoc_backgroundのみを使用します。ブロック外でメソッドを呼び出す場合は、moc_backgroundを渡します。

  NSPersistentContainer *pc = (NSPersistentContainer *)self.representedObject;
    pc.viewContext.automaticallyMergesChangesFromParent = YES; // this will ensure the main context will updated automatically

    __block id newScenario;
    [pc performBackgroundTask:^(NSManagedObjectContext * _Nonnull moc_background) {
        NSEntityDescription *scenarioDesc = [NSEntityDescription entityForName:@"Scenario" inManagedObjectContext:moc_background];
        NSManagedObject *scenario = [[NSManagedObject alloc] initWithEntity:scenarioDesc insertIntoManagedObjectContext:moc_background];
        // configure scenario with the data from newScenario

        NSError *error;
        BOOL saved = [moc_background save:&error];
        // send out a notification to let the rest of the app know whether the import was successfull
    }];

問題:ユーザーが「シナリオ」でゲームを保存するとどうなりますか。

これは、誰が最初にそこに到達するか、マージを試みるバックグラウンドスレッド、または保存操作によって異なります。多対1の関係にあるシナリオテーブルをゲームテーブルに追加しても、問題はありません。

問題:すべてのシナリオとすべてのユーザーがコアデータに保存したゲームを追跡するにはどうすればよいですか?

データモデリングには注意が必要です。最初はシンプルに保ち、明確な必要性が見つかったらテーブルとリレーションシップを追加します。そして、テスト、テスト、テスト。

于 2018-04-13T12:25:28.083 に答える