для вдохновения Я копирую свой метод для разархивирования данных из файла с помощью [NSKeyedUnarchiver unarchivedObjectOfClasses: fromData:] ... Небольшое улучшение: вам не нужно перечислять все классы в вызове метода, потому что наиболее используемые классыавтоматически добавляются в тело метода.
// MyFileManager.m
- (id)getDataFromFile:(NSString *)file inSubfolder:(NSString *)subfolder dataClasses:(NSArray<Class> *)classes {
NSString *filePath = [self pathForFile:file subfolder:subfolder];
NSData *data = [[NSFileManager defaultManager] contentsAtPath:filePath];
NSArray *extendedClasses = [classes arrayByAddingObjectsFromArray:@[[NSArray class], [NSMutableArray class], [NSDictionary class], [NSMutableDictionary class], [NSDate class], [NSNumber class]]];
NSError *unarchivingError;
id unarchived = [NSKeyedUnarchiver unarchivedObjectOfClasses:[NSSet setWithArray:extendedClasses] fromData:data error:&unarchivingError];
if (unarchivingError) {
return nil;
} else {
return unarchived;
}
}
А вот использование метода // ожидаемые неархивированные данные находятся в словаре
NSDictionary *dictionary = [FILE_MANAGER getDataFromFile:@"testfile" inSubfolder:nil dataClasses:@[[MyClass class]]];
И небольшой совет.Ваш «MyClass» должен соответствовать протоколу «NSSecureCoding».А также реализовать 3 метода в вас "MyClass" ...
@interface MyClass : NSObject <NSSecureCoding> // MyClass.h
@property (nonatomic, copy) NSString *name;
@property (nonatomic, strong) NSDate *date;
@property (nonatomic) NSInteger count;
@end
@implementation MyClass // MyClass.m
- (id)initWithCoder:(NSCoder *)decoder {
if (self = [super init]) {
self.name = [decoder decodeObjectOfClass:[NSString class] forKey:@"name"];
self.date = [decoder decodeObjectOfClass:[NSDate class] forKey:@"date"];
self.count = [decoder decodeIntegerForKey:@"count"];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)encoder {
[encoder encodeObject:self.name forKey:@"name"];
[encoder encodeObject:self.date forKey:@"date"];
[encoder encodeInteger:self.count forKey:@"count"];
}
+ (BOOL)supportsSecureCoding{
return YES;
}
Для тех, кто хочет увидеть вспомогательный метод "pathForFile" - я использую в качестве основного forlder "Поддержка библиотек / приложений" (из-заэта статья Таблица 1-3 : Основы файловой системы iOS )
// MyFileManager.m
- (NSString *)pathForFile:(NSString *)file subfolder:(NSString *)subfolder {
NSString *folderPath = [self storageFolderPathWithSubfolder:subfolder];
NSString *filePath = [folderPath stringByAppendingPathComponent:file];
return filePath;
}
- (NSString *)storageFolderPathWithSubfolder:(NSString *)subfolder {
NSString *storageFolderPath = [self storageFolderPath];
if (!subfolder.length) {
return storageFolderPath;
}
NSString *subfolderPath = [storageFolderPath stringByAppendingPathComponent:subfolder];
if (![[NSFileManager defaultManager] fileExistsAtPath:subfolderPath]) { //Does directory already exist?
[[NSFileManager defaultManager] createDirectoryAtPath:subfolderPath withIntermediateDirectories:NO attributes:@{ NSFileProtectionKey: NSFileProtectionNone } error:nil];
}
return subfolderPath;
}
- (NSString *)storageFolderPath {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
NSString *storageFolderPath = [paths firstObject];
// create folder if it doesn't exist
NSFileManager *fileManager = [NSFileManager defaultManager];
BOOL folderExists = [fileManager fileExistsAtPath:storageFolderPath];
if (!folderExists) {
[fileManager createDirectoryAtPath:storageFolderPath withIntermediateDirectories:NO attributes:@{ NSFileProtectionKey: NSFileProtectionNone } error:nil];
}
return storageFolderPath;
}