読者です 読者をやめる 読者になる 読者になる

Cocoa API解説(macOS/iOS)

iOS , Mac アプリケーション開発のために使われる主要フレームワークの日本語情報です。

目次

NSKeyedArchiverクラス

INDEX>Foundation>
更新時OS Ver.OS X 10.8,iOS 6.1
apple(mac)
apple(iOS)

解説

継承 NSCoder : NSObject
準拠 NSObject (NSObject)
フレームワーク /System/Library/Frameworks/Foundation.framework
使用可能 OS X 10.2以降
使用可能 iOS 2.0以降
定義 NSKeyedArchiver.h

概要

オブジェクトをファイルに保存するためにエンコードするクラスです。以前からオブジェクトをシリアル化(ファイルに保存するためにバイト列化)するクラスとしてNSArchiverクラスが存在しましたが、キーが付いていないために順序が固定されてきました。キー付きのクラス(NSKeyedArchiver、NSKeyedUnArchiver)が提供されたことで、順序を問わずにシリアル化、逆シリアル化ができるようになり、クラスのバージョンが上がりプロパティが増減した場合でも対応しやすくなりました。

オペレーションオブジェクトの初期化

– initForWritingWithMutableData

アーカイブする

オブジェクトをシリアライズしてデータオブジェクト(NSData)にするには(+ archivedDataWithRootObject)メソッドを使用します。
オブジェクトをシリアライズしてファイルに書き込むには(+ archiveRootObject:toFile: )メソッドを使用します。

独自に作成したクラスをエンコードする際に最後のデータであることを示すために(– finishEncoding)メソッドを使用します。
出力フォーマットを取得するには(– outputFormat)メソッドを使用します。セットするには(– setOutputFormat:)メソッドを使用します。NSPropertyListXMLFormat_v1_0とNSPropertyListBinaryFormat_v1_0が利用可能です。

データとオブジェクトエンコーディング

キーを設定してBOOL値をエンコードするには(– encodeBool:forKey)メソッドを使用します。
キーを設定してバイト列をエンコードするには(– encodeBytes:length:forKey)メソッドを使用します。
キーを設定しコンディショナルオブジェクトとしてエンコードするには(– encodeConditionalObject:forKey)メソッドを使用します。参照関係のなかで関係性を保持したい場合に使用します。
キーを設定しfloat値をエンコードするには(– encodeFloat:forKey: )メソッドを使用します。
キーを設定しint値をエンコードするには(– encodeInt:forKey)メソッドを使用します。
キーを設定しint32値をエンコードするには(– encodeInt32:forKey)メソッドを使用します。
キーを設定しint64値をエンコードするには(– encodeInt64:forKey)メソッドを使用します。
キーを設定しオブジェクトをエンコードするには(– encodeObject:forKey)メソッドを使用します。

デリゲートの管理

デリゲートをセットするには(– setDelegate: )メソッドを使用します。デリゲートNSKeyedArchiverDelegateプロトコルに準拠することが必要です。デリゲートオブジェクトを取得するには(– delegate)メソッドを使用します。


クラスとクラス名の管理

実際のクラスの代わりに別のクラス名でマッピングして使用するために(+ setClassName:forClass:)メソッドを使用します。クラス名を変更した場合などに使用します。実際のクラスの代わりのクラス名を取得するには(+ classNameForClass)メソッドを使用します。上記のクラスメソッドの他にインスタンスメソッド(– setClassName:forClass)(– classNameForClass)もあります。

いろいろなアーカイブのサンプル

#pragma mark 
//
-(void)method003
{
    NSMutableData *data = [NSMutableData data];
    NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc]
                                 initForWritingWithMutableData:data];
    NSString *string = @"string";
    
    //NewObjectとして読み込む場合はこちら
    //[NSKeyedArchiver setClassName:@"NewObject" forClass:[MyObject class]];
    //NSLog(@"-----%@",[NSKeyedArchiver classNameForClass:[MyObject class]]);
    
    //NewObjectとして読み込む場合はこちら
    //[archiver setClassName:@"NewObject" forClass:[MyObject class]];
    //NSLog(@"-----%@",[archiver classNameForClass:[MyObject class]]);
    
    [archiver setOutputFormat:NSPropertyListBinaryFormat_v1_0];
    [archiver setDelegate:self];
    switch ([archiver outputFormat]) {
        case NSPropertyListXMLFormat_v1_0:
                NSLog(@"NSPropertyListXMLFormat_v1_0");
            break;
        case NSPropertyListBinaryFormat_v1_0:
            NSLog(@"NSPropertyListBinaryFormat_v1_0");
            break;
            
        default:
            break;
    }
             
    [archiver encodeObject:string forKey:@"stringKey"];
    [archiver encodeBool:YES forKey:@"boolKey"];
    
    unsigned char aBuffer[200];
    NSString *str = @"This is a pen.";
    NSData *dat1 = [NSData dataWithBytes:[str cStringUsingEncoding:NSUTF8StringEncoding] length:[str lengthOfBytesUsingEncoding:NSUTF8StringEncoding]];
    [dat1 getBytes:aBuffer length:[str length]];
    [archiver encodeBytes:aBuffer length:[str length] forKey:@"bytesKey"];
    
    MyObject *string1 = [[MyObject alloc] init];
    [string1 setValue:@"string1" forKey:@"string"];
    MyObject *string2 = [[MyObject alloc] init];
    MyObject *string3 = [[MyObject alloc] init];
    NSMutableArray *mArray = [NSMutableArray arrayWithCapacity:5];
    [mArray addObject:string1];
    [mArray addObject:string2];
    [mArray addObject:string3];
    [archiver encodeObject:mArray forKey:@"conditionalObjectKey"];
    //[archiver encodeConditionalObject:mArray forKey:@"conditionalObjectKey"];
    [archiver finishEncoding];
    
    NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    NSString *filename = @"testWrite.archive";
    NSURL *aURL = [NSURL fileURLWithPathComponents:[NSArray arrayWithObjects:documentsDirectory, filename, nil]];
    
    if ([data writeToURL:aURL atomically:YES]){
        NSLog(@"write YES");
    }else{
        NSLog(@"write NO");
    }
    
    //------------------読み込み------------------
    NSMutableData *readData = [NSMutableData dataWithContentsOfURL:aURL];
    NSLog(@"%@",[readData description]);
    //アンアーカイブ
    NSKeyedUnarchiver *unArchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:readData];
    
    
    NSLog(@"%s unArchivedObj = %@",__FUNCTION__,[unArchiver decodeObjectForKey:@"stringKey"]);
    NSLog(@"%s unArchivedObj = %@",__FUNCTION__,([unArchiver decodeObjectForKey:@"boolKey"])?@"YES":@"NO");
    
    const uint8_t *mPointer;
    NSUInteger lengthInteger = 0;
    mPointer = [unArchiver decodeBytesForKey:@"bytesKey" returnedLength:&lengthInteger ];
    NSString *output = [[NSString alloc] initWithBytes:mPointer
                                                length:lengthInteger
                                              encoding:NSUTF8StringEncoding];
    NSLog(@"%s unArchivedObj = %@",__FUNCTION__,output);
    
    //MyObjectのエンコード
    //[encoder encodeConditionalObject:string forKey:@"string"];
    //になっていると内容は保持されない。
    id mArray2 = [unArchiver decodeObjectForKey:@"conditionalObjectKey"];
    
    NSLog(@"%s unArchivedObj = %@",__FUNCTION__,[mArray2 objectAtIndex:0]);
    NSLog(@"%s unArchivedObj = %@",__FUNCTION__,[[mArray2 objectAtIndex:0] class]);
}

適合するプロトコル