Запись скоростного словаря в файл

Существуют ограничения при написании NSDictionaries в файлах в swift. Основываясь на том, что я узнал из api docs и qaru.site/info/496506/..., типы ключей должны быть NSString, а типы значений также должны быть типа NSx, а Int, String и другие Быстрые типы могут не работать. Вопрос в том, что если у меня есть словарь вроде: Dictionary<Int, Dictionary<Int, MyOwnType>>, как я могу писать/читать его в/из файла plist в swift?

Ответ 1

В любом случае, когда вы хотите сохранить MyOwnType в файл, MyOwnType должен быть подклассом NSObject и соответствовать протоколу NSCoding. например:

class MyOwnType: NSObject, NSCoding {

    var name: String

    init(name: String) {
        self.name = name
    }

    required init(coder aDecoder: NSCoder) {
        name = aDecoder.decodeObjectForKey("name") as? String ?? ""
    }

    func encodeWithCoder(aCoder: NSCoder) {
        aCoder.encodeObject(name, forKey: "name")
    }
}

Тогда вот Dictionary:

var dict = [Int : [Int : MyOwnType]]()
dict[1] = [
    1: MyOwnType(name: "foobar"),
    2: MyOwnType(name: "bazqux")
]

Итак, вот ваш вопрос:

Запись скоростного словаря в файл

Вы можете использовать NSKeyedArchiver для записи и NSKeyedUnarchiver для чтения:

func getFileURL(fileName: String) -> NSURL {
    let manager = NSFileManager.defaultManager()
    let dirURL = manager.URLForDirectory(.DocumentDirectory, inDomain: .UserDomainMask, appropriateForURL: nil, create: false, error: nil)
    return dirURL!.URLByAppendingPathComponent(fileName)
}

let filePath = getFileURL("data.dat").path!

// write to file
NSKeyedArchiver.archiveRootObject(dict, toFile: filePath)

// read from file
let dict2 = NSKeyedUnarchiver.unarchiveObjectWithFile(filePath) as [Int : [Int : MyOwnType]]

// here `dict2` is a copy of `dict`

Но в теле вашего вопроса:

как я могу записать/прочитать его в/из файла plist в swift?

Фактически, формат NSKeyedArchiver является двоичным plist. Но если вам нужен этот словарь как значение plist, вы можете сериализовать Dictionary на NSData с помощью NSKeyedArchiver:

// archive to data
let dat:NSData = NSKeyedArchiver.archivedDataWithRootObject(dict)

// unarchive from data
let dict2 = NSKeyedUnarchiver.unarchiveObjectWithData(data) as [Int : [Int : MyOwnType]]