6

NSCoding、より正確には NSKeyedArchiver を使用してデータを永続化する iOS アプリケーションがあります。このアプリケーションはすでに App Store で入手できます。

アプリケーションのバージョン 2 に取り組んでおり、データ モデルを変更する必要があります。そのため、データ モデルの移行を処理する必要があります。単体テストでカバーしてほしい。

私のテストでは、古いデータ モデルを使用して永続化されたデータを動的に生成し、移行を開始して、すべてがうまくいったかどうかを確認したいと考えています。

現在、オブジェクトのアーカイブは次のようになっています。

MyDataModelObject *object = ....
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
[archiver encodeObject:object forKey:key];
[archiver finishEncoding];

問題は、バージョン 2 のアプリケーションで MyDataModelObject がリファクタリングされたり、削除されたりする可能性があることです。したがって、テストでこのクラスを使用して「古いバージョンのアーカイブ」を生成することはできません。

encodeWithCoder:このクラスを使用せずにクラスのメソッドで行われることをシミュレートする方法はありますか?


私が達成したいことは次のとおりです

- testMigrationFrom_v1_to_v2 {
    // simulate an archive with v1 data model
    // I want this part of the code to be as simple as possible
    // I don't want to rely on old classes to generate the archive
    NSDictionary *person = ... // { firstName: John, lastName: Doe }
    NSDictionary *adress = ... // { street: 1 down street, city: Butterfly City }
    [person setObject:adress forKey:@"adress"];

    // there's something missing to tell the archiever that:
    // - person is of type OldPersonDataModel
    // - adress is of type OldAdressDataModel

    [archiver encodeObject:person forKey:@"somePerson"];
    // at this point, I would like the archive file to contain :
    // a person object of type OldPersonDataModel, that has an adress object of type OldAdressModel 

    NewPersonModel *newPerson =  [Migration readDataFromV1];

    // assertions
    NSAssert(newPerson.firstName, @"John");
    NSAssert(newPerson.lastName, @"Doe");
}
4

1 に答える 1

0

質問の意味がよくわからないので、次の 2 つを回答します。

古いクラスで使用するキー/値を持つインスタンスをプリロードしNSDictionary、新しいキー付きアーカイバを作成し、すべてのキーをループしてアーカイブすることができます。

クラスの-attributeKeysメソッドを取得してすべてのキーを取得し、次のコードを使用してアーカイブをシミュレートすることもできます。

NSKeyedArchiver *archive = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
[archiver encodeObject:object forKey:key];
for (NSString *key in object.attributeKeys) {
    [archive encodeObject:[object valueForKey:key] forKey:key];
}
[archive finishEncoding];

データを移行する点で、NSKeyedArchiver にはメソッドが-setClass:forClassName:あり、新しいオブジェクトで古いキーをすべてサポートして、それらを異なるプロパティに変換できます。

于 2011-11-28T04:26:53.790 に答える