Постоянная стратегия хранения iOS - программирование
Подтвердить что ты не робот

Постоянная стратегия хранения iOS

Я разрабатываю приложение, которое будет сохранять данные в локальной файловой системе. Данные, которые будут сохранены, будут в основном NSString и NSDate. Данные не будут сохранены, что часто, возможно, новые данные будут введены 10 раз при типичном использовании. Разумеется, данные также должны быть извлечены (CRUD)

Как сохранить эти данные? Во-первых, необходимо ли моделировать эти объекты? Если нет, я должен использовать списки свойств? Или SQLLite3?

Нужно ли архивировать модели классов? Использовать SQLLite3?

РЕДАКТИРОВАТЬ: Я случайно оставил важную информацию о приложении. На самом деле мое приложение будет иметь 2 модели данных, которые имеют агрегированные отношения. Поэтому моя первая модель данных (назовем ее DataA), которая будет иметь NSString и NSDate, также будет иметь ссылку на вторую модель данных (позволяет вызывать ее DataB), которая сама будет состоять из NSString и NSArray. Так что теперь становится немного сложнее. Если объект из DataB удаляется, он, конечно, должен перестать существовать в DataA (но остальная часть DataA не должна оставаться нетронутой).

4b9b3361

Ответ 1

Этот вид данных очень прост для хранения и извлечения и не имеет каких-либо других зависимостей, таких как ужасно сложный граф объектов.

Эти данные следует хранить в плоском файле или в 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

Отказ от ответственности: я не тестировал этот код.

Ответ 2

Я предлагаю вам пойти с NSUserDefaults. Это, безусловно, лучший способ хранить информацию, относящуюся к вашему приложению, и любые связанные с приложением данные. Проверьте documentation!!

Ответ 3

NSUserDefault - хороший выбор, если у вас ограниченный набор данных. Но если вы рассматриваете фильтрацию и выборку, тогда вы должны взглянуть на Core Data для хранения объектов.

Даже если график объекта минимален, вы получите управление кэшированными объектами и освободите управление отменой/повтором.