目的
NSKeyedArchiver
/ NSKeyedUnarchiver
でデータを保存する際のキーをenumで管理するため。
Protocolつけるだけで利用できるようにしたい。
使い方
// 保存先のパス指定
private let path = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] + "/foo.cache"
// enumの定義
enum Key: String, EnumKeyedArchivable {
case Bar = "Bar"
}
// Archive
var dictionary: [Key: AnyObject] = [:]
dictionary[.Bar] = "This is Bar"
NSKeyedArchiver.archive(dictionary, toFile: path)
// Unarchive
let unarchivedDictionary = NSKeyedUnarchiver.unarchive(Key.self, file: path)
print(unarchivedDictionary) // Optional([Key.Bar: This is Bar])
実装
protocol EnumKeyedArchivable: RawRepresentable {
func keyValue() -> String
init?(stringValue: String)
}
extension EnumKeyedArchivable where Self: RawRepresentable, Self.RawValue == String {
func keyValue() -> String {
return self.rawValue
}
init?(stringValue: String) {
self.init(rawValue: stringValue)
}
}
extension NSKeyedArchiver {
class func archive<T: EnumKeyedArchivable>(dictionary: [T: AnyObject], toFile file: String) {
var archivableDictionary: [String: AnyObject] = [:]
for (key, value) in dictionary {
archivableDictionary[key.keyValue()] = value
}
self.archiveRootObject(archivableDictionary, toFile: file)
}
}
extension NSKeyedUnarchiver {
class func unarchive<T: EnumKeyedArchivable>(key: T.Type, file: String) -> [T: AnyObject]? {
guard let archivedDictionary = self.unarchiveObjectWithFile(file) as? [String: AnyObject] else {
return nil
}
var dictonary: [T: AnyObject] = [:]
for (key, value) in archivedDictionary {
if let enumKey = T(stringValue: key) {
dictonary[enumKey] = value
}
}
return dictonary
}
}