SWIFT 写入 plist 未更新

Posted

技术标签:

【中文标题】SWIFT 写入 plist 未更新【英文标题】:SWIFT writing to plist is not updating 【发布时间】:2020-07-07 09:23:06 【问题描述】:

我正在尝试写信给plist,我正在使用两种方法,但它们都不适合我。

但我没有收到任何错误,当我打印 paths 时,我可以看到 plist 存在,但是您可以从屏幕截图中看到 plist 它没有得到更新/填充。

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)

有人可以帮忙吗?

【问题讨论】:

无法写入应用程序包。由于显而易见的原因,它是只读的。要修改文件,请在首次启动应用程序时将其复制到 Documents 文件夹中。并且不要使用NSDictionary/NSArray API 来读取/写入属性列表。有PropertyListSerializationPropertyListDecoder。并且根本不要在 Swift 中使用 NSMutable... 集合类型。 非常感谢@vadian 我不知道。我对 Swift 和 macOS 应用程序开发非常陌生。有没有什么例子可以展示我如何实现上述目标以及你所说的? 【参考方案1】:

这是一个简短的教程。

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

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

 var employeePlistURL : URL 
     let documentsFolderURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
     return documentsFolderURL.appendingPathComponent("Employee.plist")
 

AppDelegate applicationWillFinishLaunching 中为UserDefaults 中的firstLaunch 标志注册一个键值对,如果标志为真,则将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 方式。

【讨论】:

太棒了! :) 非常感谢。你是明星。现在我需要学习如何不断添加和删除员工:)

以上是关于SWIFT 写入 plist 未更新的主要内容,如果未能解决你的问题,请参考以下文章

更新 Plist 数据而不删除旧数据

Swift 2:使用多维对象写入 plist

在 Swift 中写入 Plist

Swift 3:无法将数据写入 plist 文件

将嵌套字典写入 plist (Swift) 时的类型问题

SpriteKit Swift 2 无法写入 plist