web-dev-qa-db-ja.com

非推奨のarchiveRootObject:toFileを使用するiOS 12.0の代替:

IOS 12では、archiveRootObject:toFile:は非推奨になりました。誰かがファイルにオブジェクトをアーカイブするための合理化された代替案を提案できますか?

//Generic example of archiver prior to iOS 12.0    
-(BOOL) archive:(id)archiveObject withFileName:(NSString*)filename
{
    NSString *path = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];
    return [NSKeyedArchiver archiveRootObject:archiveObject toFile:path];
}
8
rswayz

ヒントを提供してくれた@vadianに感謝します。iOS12でアーカイブとアーカイブ解除を行うために私が思いついたのは、次のとおりです。

NSError *error = nil;

NSString *docsDir;
NSArray *dirPaths;

//Get the device's data directory:
dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
docsDir = [dirPaths objectAtIndex:0];
NSString *databasePath = [[NSString alloc] initWithString: [docsDir stringByAppendingPathComponent:@"appData.data"]];

//Archive using iOS 12 compliant coding:
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:@"foo" requiringSecureCoding:NO error:&error];
[data writeToFile:databasePath options:NSDataWritingAtomic error:&error];
NSLog(@"Write returned error: %@", [error localizedDescription]);

//Unarchive the data:
NSData *newData = [NSData dataWithContentsOfFile:databasePath];
NSString *fooString = [NSKeyedUnarchiver unarchivedObjectOfClass:[NSString class] fromData:newData error:&error];
6
rswayz

Appleが推奨 のように、アーカイブファイルの読み取り/書き込みにはFileManagerを使用する必要があります。

guard let documentURL = FileManager().urls(for: .documentDirectory, in: .userDomainMask).first else { return }

let filePath = "MyArchive.data"
let fileURL = documentURL.appendingPathComponent(filePath)

// Archive
if let archivedData = try? NSKeyedArchiver.archivedData(withRootObject: myObject, requiringSecureCoding: true) {
    try? archivedData.write(to: fileURL)
}

// Unarchive
if let archivedData = try? Data(contentsOf: fileURL),
        let myObject = (try? NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(archivedData)) as? Object {
    ///
    ///
    ///
}
3
devolaw

代わりは archivedDataWithRootObject:requiringSecureCoding:error: です。

+ (NSData *)archivedDataWithRootObject:(id)object 
             requiringSecureCoding:(BOOL)requiresSecureCoding 
                             error:(NSError * _Nullable *)error;

さらに、データをディスクに書き込むための追加の手順。

ご覧ください Foundation iOS 11.4から12.0 APIの違い

3
vadian

安全なエンコーディングを使用していないオブジェクトをデコードしようとすると、unArchivedObjectOfClassがエラーをスローしました。多くの試行錯誤の後、これはiOS 12/13の非推奨警告をトリガーすることなく最終的に機能したものです:

// Archive the object
NSData* data = [NSKeyedArchiver archivedDataWithRootObject:theObject requiringSecureCoding:NO error:nil];

// Unarchive the object
NSKeyedUnarchiver* unarchiver = [[NSKeyedUnarchiver alloc] initForReadingFromData:data error:nil];
unarchiver.requiresSecureCoding = NO;
id theCopy = [unarchiver decodeTopLevelObjectForKey:NSKeyedArchiveRootObjectKey error:nil];
2
Chen Lim