SWIFT 写入 plist 未更新

SWIFT writing to plist is not updating

我正在尝试写信给 plist,我使用了两种方法,但其中 none 对我有用。

我没有收到任何错误,当我打印 paths 时,我可以看到 plist 存在,但是你可以从屏幕截图中看到 plist 它是没有得到 updated/populated.

let path = Bundle.main.path(forResource: "Employee", ofType: "plist")!
let data : NSDictionary = 
["A": [["userid":"1","username":"AAA","usergroupid":"2"], ["userid":"33","username":"ABB","usergroupid":"8"]],
"B": [["userid":"2","username":"BBB","usergroupid":"8"], ["userid":"43","username":"ABC","usergroupid":"8"]] ]

 //first approach
let favoritesDictionary = NSDictionary(object: data, forKey: ("Favorites" as NSString?)!)
print(path)
let succeeded = favoritesDictionary.write(toFile: path, atomically: true)

                
//second approach
let bundlePath = Bundle.main.path(forResource: "Employee", ofType: "plist")!
print(bundlePath)
let dictionary = NSMutableDictionary(contentsOfFile: bundlePath)
dictionary?.setObject(data, forKey: ("Locations" as NSString?)!)
dictionary?.write(toFile: bundlePath, atomically: true)

有人可以帮忙吗?

这是一个简短的教程。

  • 创建您的 plist 文件并将其放入应用程序包中。

  • AppDelegate 中创建计算 属性 以获取当前 Documents 文件夹并附加文件路径

     var employeePlistURL : URL {
         let documentsFolderURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
         return documentsFolderURL.appendingPathComponent("Employee.plist")
     }
    
  • AppDelegateapplicationWillFinishLaunching中为firstLaunch标志注册一个键值对UserDefaults并复制plist到文档文件夹如果旗帜为真

    func applicationWillFinishLaunching(_ aNotification: Notification) {
         let defaults = UserDefaults.standard
         defaults.register(defaults: ["firstLaunch":true])
         if defaults.bool(forKey: "firstLaunch") {
             let sourceFile = Bundle.main.url(forResource: "Employee", withExtension: "plist")!
             try? FileManager.default.copyItem(at: sourceFile, to: employeePlistURL)
             defaults.set(false, forKey: "firstLaunch")
         }
     }
    
  • 无论你在哪里需要读取和写入 属性 列表,也创建计算的 属性 并为字典添加一个 属性

    var employees = [String:Any]()
    

    以及加载和保存数据的两种方法

     func loadEmployees() {
         do {
             let data = try Data(contentsOf: employeePlistURL)
             guard let plist = try PropertyListSerialization.propertyList(from: data, format: nil) as? [String:Any] else { return }
             employees = plist
         } catch { print(error) }
     }
    
     func saveEmployees() {
         do {
             let data = try PropertyListSerialization.data(fromPropertyList: employees, format: .binary, options: 0)
             try data.write(to: employeePlistURL)
         } catch { print(error) }
     }
    

更好的方法是使用结构和 PropertyListEncoder/-Decoder 但由于文字字典和问题中的屏幕截图有很大不同,我提供了常见的 Dictionary / PropertyListSerialization 方式。