2012-01-04 16 views
15

データをローカルファイルシステムに保存するアプリを開発しています。保存されるデータは主にNSStringとNSDateになります。データは頻繁に保存されません。通常、新しいデータは通常の使用で10回入力されます。データはもちろん取得可能(CRUD)iOS永続ストレージ戦略

このデータはどのように保存する必要がありますか?まず、これらのオブジェクトをモデル化する必要がありますか?プロパティリストを使用する必要はありませんか?またはSQLLite3?

それ以外の場合は、クラスモデルをアーカイブする必要がありますか? SQLLite3を使用しますか?

編集:私は誤って、アプリに関する重要な情報をいくつか削除しました。実際に私のアプリは、集約された関係を持つ2つのデータモデルを持っています。したがって、NSStringとNSDateを持つ私の最初のデータモデル(DataAと呼ぶことができます)は、NSStringとNSArrayで構成される2番目のデータモデル(DataBと呼ぶことができます)への参照を持ちます。だから、もう少し複雑になります。 DataBのオブジェクトが削除された場合は、もちろんDataAには存在しなくなります(ただしDataAの残りの部分はそのまま残す必要があります)

+0

データの量が巨額でない場合、あなたがNSUserDefaultsを使用することができますと言っているように...そのシンプルで使いやすいです。 – Bonnie

答えて

17

この種のデータは非常に保存して検索するのが簡単で他のものはありません恐ろしく複雑なオブジェクトグラフなどの依存関係。

このデータはフラットファイルまたはNSUserDefaultsに保存する必要があります。

私はNSCodingプロトコルを使用して、オブジェクトのアーカイブを使用して、あなたの両方の例をあげる:次に

@interface ApplicationData <NSCopying, NSCoding> {} 

@property (nonatomic, strong) NSDate *someDate; 
@property (nonatomic, strong) NSDate *someOtherDate; 

@property (nonatomic, copy) NSString *someString; 
@property (nonatomic, copy) NSString *someOtherString; 

@end 

@implementation ApplicationData 

@synthesize someDate = _someDate, someOtherDate = _someOtherDate, someString = _someString, someOtherString = _someOtherString; 

- (NSArray *)keys { 
    static dispatch_once_t once; 
    static NSArray *keys = nil; 
    dispatch_once(&once, ^{ 
     keys = [NSArray arrayWithObjects:@"someString", @"someOtherString", @"someDate", @"someOtherDate", nil]; 
    }); 
    return keys; 
} 

- (id) copyWithZone:(NSZone *) zone { 
    ApplicationData *data = [[[self class] allocWithZone:zone] init]; 
    if(data) { 
     data.someString = _someString; 
     data.someOtherString = _someOtherString;  

     data.someDate = _someDate; 
     data.someOtherDate = _someOtherDate; 
     //... 
    } 
    return data; 
} 

- (void) encodeWithCoder:(NSCoder *) coder { 
    [super encodeWithCoder:coder]; 

    NSDictionary *pairs = [self dictionaryWithValuesForKeys:[self keys]]; 

    for(NSString *key in keys) { 
     [coder encodeObject:[pairs objectForKey:key] forKey:key]; 
    } 
    } 


    - (id) initWithCoder:(NSCoder *) decoder { 
    self = [super initWithCoder:decoder]; 
    if(self) { 
     for(NSString *key in [self keys]) { 
      [self setValue:[decoder decodeObjectForKey:key] forKey:key]; 
     } 
    } 
    return self; 
    } 

    @end 

は、アプリケーションデリゲートで言う、あなたはこれを行うことができます。

@interface AppDelegate (Persistence) 

@property (nonatomic, strong) ApplicationData *data; 

- (void)saveApplicationDataToFlatFile; 
- (void)loadApplicationDataFromFlatFile; 
- (void)saveApplicationDataToUserDefaults; 
- (void)loadApplicationDataFromUserDefaults; 

@end 

@implementation AppDelegate (Persistence) 
@synthesize data; 

- (NSString *)_dataFilePath { 
    static NSString *path = nil; 
    static dispatch_once_t once; 
    dispatch_once(&once, ^{ 
    path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) stringByAppendingPathComponent:@"xAppData.dat"]; 
    }); 
    return path; 
} 

- (void)loadApplicationDataFromUserDefaults {   
    NSData *archivedData = [[NSUserDefaults standardUserDefaults] objectForKey:@"appData"]; 
    self.data = [NSKeyedUnarchiver unarchiveObjectWithData:archivedData]; 
} 

- (void)saveApplicationDataToUserDefaults { 
    NSData *archivedData = [NSKeyedArchiver archivedDataWithRootObject:self.data]; 
    [[NSUserDefaults standardUserDefaults] setObject:archivedData forKey:@"appData"]; 
    [[NSUserDefaults standardUserDefaults] synchronize]; 
} 

- (void)loadApplicationDataFromFlatFile { 
    NSData *archivedData = [NSData dataWithContentsOfFile:[self _dataFilePath]]; 
    self.data = [NSKeyedUnarchiver unarchiveObjectWithData:archivedData]; 
} 

- (void)saveApplicationDataToFlatFile { 
    NSData *archivedData = [NSKeyedArchiver archivedDataWithRootObject:self.data]; 
    [archivedData writeToFile:[self _dataFilePath] atomically:YES]; 
} 

@end 

免責事項:私はこのコードをテストしていません。

+0

あなたの完全な答えをありがとう。実際に私のアプリは、集約された関係を持つ2つのデータモデルを持っています。したがって、NSStringとNSDateを持つ私の最初のデータモデル(DataAと呼ぶことができます)は、NSStringとNSArrayで構成される2番目のデータモデル(DataBと呼ぶことができます)への参照を持ちます。だから、もう少し複雑になります。 DataBのオブジェクトが削除された場合、もちろんDataAには存在しなくなります。 –

+0

@ PeterWarboそうであれば、Core Dataを使用することをお勧めします。これは、カスケーディング関係ルールなどを実行する最も簡単な方法だからです。私はコアデータスタックを設定することのトレードオフについて議論していますが、実装するのは簡単ではありません。 –

+0

基本的には、私のデータモデルのアーカイブを使用するかコアデータを使用するかのどちらかです。 –

1

私はあなたがNSUserDefaultsと行くことをお勧めします。アプリやアプリ関連のデータに関係する情報を保存するには、確かに最善のアプローチです。 documentationを確認してください!

1

NSUserDefaultは、データセットが限られている場合に適しています。 しかし、フィルタリングとフェッチを考慮すると、オブジェクトを格納するためにコアデータを調べる必要があります。

オブジェクトグラフが最小限であっても、キャッシュされたオブジェクト管理と自由なアンドゥ/リドゥ管理が得られます。