使い方は簡単で LKCodingObject を派生しておいて、普通にプロパティを定義するだけ。
#import "LKCodingObject.h" @interface UserInfo : LKCodingObject @property (strong, nonatomic) NSString* name; @property (strong, nonatomic) NSString* email; @end
アーカイブ
UserInfo* userInfo = UserInfo.new; userInfo.name = @"Hoge"; userInfo.email = @"hoge@xcatsan.com"; [NSKeyedArchiver archiveRootObject:userInfo toFile:@"user_info.dat"];
アンアーカイブ
UeserInfo* userInfo = [NSKeyedUnarchiver unarchiveObjectWithFile:@"user_info.dat"];
通常だと NSCodingプロトコルのメソッド initWithCoder: encodeWithCoder: を実装する必要があるが、このライブラリを使うとサブクラス化するだけでメソッドを書かずにアーカイブ・アンアーカイブできる。
ライブラリのコードは簡単で initWithCoder: encodeWithCoder: を実装しているだけ。
- (id)initWithCoder:(NSCoder*)decoder { self = [super init]; if (self) { for (NSString* name in self._propertyNames) { id value = [decoder decodeObjectForKey:name]; [self setValue:value forKey:name]; } } return self; } - (void)encodeWithCoder:(NSCoder *)coder { for (NSString* name in self._propertyNames) { id value = [self valueForKey:name]; if ([value conformsToProtocol:@protocol(NSCoding)]) { [coder encodeObject:value forKey:name]; } } }
プロパティ名をランタイム関数から取得してきて KVCでセット・ゲットしてる。intやfloatのプロパティも適当にラップしてくれてうまく動く。
プロパティ名取得
- (NSArray*)_propertyNames { NSMutableArray* propertyNames = @[].mutableCopy; unsigned int count, i; objc_property_t *objc_properties = class_copyPropertyList(self.class, &count); for(i = 0; i < count; i++) { objc_property_t objc_property = objc_properties[i]; propertyNames[i] = [NSString stringWithUTF8String:property_getName(objc_property)]; } free(objc_properties); return propertyNames; }
注意点としては、NCodingに準拠していないクラスのプロパティは無視すること。エラーにならないので注意。
ここは例外を飛ばすとかしたほうがいいのかもしれない。
- - - -
CocoaPods 便利だわ。諦めてた自作コードの再利用が進む進む。特に小さなコードはコピペしてしまうのが常だったが CocoaPodsだと管理が苦にならない。ただ CocoaPods対応が若干面倒なのでこの辺りの自動化がもう少しできると良さそう。
Responses
Leave a Response