Swift:带有“复杂”数据的pList

彼得71

当我阅读并尝试:-)时,我只能在pList文件上保存一些简单的数据类型。尽管如此,我还是喜欢使用结构,类等来表示我的数据。这应该尽可能容易地保存到pList文件并重新加载。

我知道,NSData是pList的有效类型。而且,这是一种通用的数据类型。因此,将结构或类变量移动/转换/强制放入要保存和重新加载的NSData对象中是一个好主意吗?怎么办?

到现在为止,我正在使用类似的方式进行保存:

let dict: NSMutableDictionary = ["XYZ": "XYZ"]

// saving values
dict.setObject(myBasicArray, forKey: "BasicArray")

dict.writeToFile(path, atomically: false)

更新:我使用提供的代码并将其扩展为处理结构:

import Cocoa

struct SteeringItem {
    var ext    = String()   // extension including dot e.g. ".JPG"
    var bitmap = Int()      // flag for grouping file types, e.g. photos

    init?(ext: String, bitmap: Int) {
        // Initialize stored properties.
        self.ext    = ext
        self.bitmap = bitmap
    }
}

class Foo {
    let one: Int
    let two: SteeringItem


    init(one:Int, two: SteeringItem) {
        self.one = one
        self.two = two
    }

    init?(dict:[String: AnyObject]) {
        guard let
            one = dict["one"] as? Int,
            two = dict["two"] as? SteeringItem else { return nil }

        self.one = one
        self.two = two
    }

    func toDictionary() -> [String: AnyObject] {
        var retval = [String: AnyObject]()
        if let
            one = self.one as? AnyObject,
            two = self.two as? AnyObject {
            retval["one"] = one
            retval["two"] = two
        }
        return retval
    }
}

// create struct
let writeStruct = Foo(one: 1, two: SteeringItem(ext: "one",bitmap: 1)!)
print(writeStruct, "\n")

// write to plist
let writeDict = writeStruct.toDictionary() as NSDictionary
let path = ("~/test.plist" as NSString).stringByExpandingTildeInPath
writeDict.writeToFile(path, atomically: true)

// print contents of file
print(try NSString(contentsOfFile: path, encoding: NSUTF8StringEncoding))

// read plist and recreate struct
if let
    readDict = NSDictionary(contentsOfFile: path) as? [String:AnyObject],
    readStruct = Foo(dict: readDict) {
    print(readStruct)
}

但这不再写了。使用String可以工作,而使用“ struct SteeringItem”则行不通!

更新2:类而不是结构

    class SteeringItem : NSObject, NSCoding {
    var ext    = String()   // extension including dot e.g. ".JPG"
    var bitmap = Int()      // flag for grouping file types, e.g. photos

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

    required convenience init?(coder aDecoder: NSCoder) {
        let ext    = aDecoder.decodeObjectForKey("ext")    as! String
        let bitmap = aDecoder.decodeObjectForKey("bitmap") as! Int

        self.init(ext: ext, bitmap: bitmap)
    }

    init?(ext: String, bitmap: Int) {
        // Initialize stored properties.
        self.ext    = ext
        self.bitmap = bitmap

        super.init()
    }
}
用户名

有多种方法可以执行此操作,您可以遵循NSCoding协议,也可以编写方法将类/结构转换为Dictionary并从中进行序列化。

这是使用NSCoding协议的一个很好的介绍

至于与字典之间的相互转换,通常的方法是提供一种失败的init方法,Dictionary<String, AnyObject>方法采用a来验证key:value对并​​将其复制到成员变量。您还提供了一种方法,该方法返回Dictionary<String, AnyObject>与take相同的key:value对init然后,您可以通过调用create方法并序列化结果来进行序列化,然后Dictionary通过读入aDictionary并将其传递给init方法序列化

这是转换的示例:

/// Provides conversion to and from [String: AnyObject] for use in serialization
protocol Serializable {
  init?(dict:[String: AnyObject])
  func toDictionary() -> [String: AnyObject]
}

struct SteeringItem {
  // Changed var to let, it's a good practice with a simple struct
  let ext    : String   // extension including dot e.g. ".JPG"
  let bitmap : Int      // flag for grouping file types, e.g. photos
}

struct Foo {
  let one: Int
  let two: SteeringItem
}

// Add serialization to structs

extension SteeringItem: Serializable {
  init?(dict:[String: AnyObject]) {
    guard let
      ext = dict["ext"] as? String,
      bitmap = dict["bitmap"] as? Int else { return nil }
    self.ext = ext
    self.bitmap = bitmap
  }

  func toDictionary() -> [String: AnyObject] {
    var retval = [String: AnyObject]()
    if let
      ext = self.ext as? AnyObject,
      bitmap = self.bitmap as? AnyObject {
      retval["ext"] = ext
      retval["bitmap"] = bitmap
    }
    return retval
  }
}

extension Foo: Serializable {
  init?(dict:[String: AnyObject]) {
    guard let
      one = dict["one"] as? Int,
      twoDict = dict["two"] as? [String: AnyObject],
      two = SteeringItem(dict: twoDict) else { return nil }

    self.one = one
    self.two = two
  }

  func toDictionary() -> [String: AnyObject] {
    var retval = [String: AnyObject]()
    let twoDict = self.two.toDictionary()
    if let
      one = self.one as? AnyObject,
      two = twoDict as? AnyObject {
      retval["one"] = one
      retval["two"] = two
    }
    return retval
  }
}

这是在操场上进行测试的方法:

import Foundation

// create struct
let writeStruct = Foo(one: 1, two: SteeringItem(ext: "jpg", bitmap: 1))
print(writeStruct, "\n")

// write to plist
let writeDict = writeStruct.toDictionary() as NSDictionary
let path = ("~/test.plist" as NSString).stringByExpandingTildeInPath
writeDict.writeToFile(path, atomically: true)

// print contents of file
print(try NSString(contentsOfFile: path, encoding: NSUTF8StringEncoding))

// read plist and recreate struct
if let
  readDict = NSDictionary(contentsOfFile: path) as? [String:AnyObject],
  readStruct = Foo(dict: readDict) {
  print(readStruct)
}

结果:

Foo(one: 1, two: SteeringItem(ext: "jpg", bitmap: 1)) 

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>one</key>
    <integer>1</integer>
    <key>two</key>
    <dict>
        <key>bitmap</key>
        <integer>1</integer>
        <key>ext</key>
        <string>jpg</string>
    </dict>
</dict>
</plist>

Foo(one: 1, two: SteeringItem(ext: "jpg", bitmap: 1))

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

带有复杂初始化的Swift静态var

来自分类Dev

带有复杂条件的python pandas重复数据删除

来自分类Dev

iOS从更复杂的.plist中读取数据

来自分类Dev

带有Swift和Core数据的NSPredicate

来自分类Dev

带有列表信息的json数据的Swift

来自分类Dev

带有大量数据的 CollectionView Swift

来自分类Dev

带有MVC的复杂UI

来自分类Dev

带有复杂评估的对象

来自分类Dev

带有dict元素的Plist XPath查询

来自分类Dev

如何从带有条件的复杂字符串内容中捕获特定数据?

来自分类Dev

iOS Swift-具有复杂数据关系的核心数据示例

来自分类Dev

在Swift中将数据保存到.plist文件

来自分类Dev

如何在Swift中从PLIST读取数据?

来自分类Dev

如何在Swift中从PLIST读取数据?

来自分类Dev

iOS Swift + Alamofire上传带有exif数据的照片

来自分类Dev

数据到带有字体属性Swift的attributedString

来自分类Dev

数据到带有字体属性Swift的attributedString

来自分类Dev

带有不同表数据的ios swift uitableview部分

来自分类Dev

带有数据URI的Swift shardApplication()。openURL()

来自分类Dev

Swift中带有核心数据的KVO通知

来自分类Dev

带有复杂 where 子句的复杂 LINQ 查询

来自分类Dev

带有枢轴的复杂SQL查询

来自分类Dev

带有观测值的复杂流

来自分类Dev

带有ValidationMessage的复杂类型

来自分类Dev

带有复杂插入的SQL选择

来自分类Dev

带有expss包的复杂表

来自分类Dev

带有:not()的“复杂” JQuery选择器

来自分类Dev

带有日期的PHP PDO复杂查询

来自分类Dev

带有复杂选择器的jQuery