【问题标题】:Write to plist file in Swift在 Swift 中写入 plist 文件
【发布时间】:2014-09-01 18:50:12
【问题描述】:

我有一个示例 plist 文件,favCities.plist。这是我的示例代码:

 override func viewDidLoad() {
    super.viewDidLoad()


    let path = NSBundle.mainBundle().pathForResource("favCities", ofType: "plist")
    var plistArray = NSArray(contentsOfFile: path) as [Dictionary<String, String>]

    var addDic: Dictionary = ["ZMV": "TEST", "Name": "TEST", "Country": "TEST"]
    plistArray += addDic
    (plistArray as NSArray).writeToFile(path, atomically: true)

    var plistArray2 = NSArray(contentsOfFile: path)

    for tempDict1 in plistArray2 {
        var tempDict2: NSDictionary = tempDict1 as NSDictionary
        var cityName: String = tempDict2.valueForKey("Name") as String
        var cityZMV: String = tempDict2.valueForKey("ZMV") as String
        var cityCountry: String = tempDict2.valueForKey("Country") as String
        println("City: \(cityName), ZMV: \(cityZMV), Country: \(cityCountry)")
    }

乍一看,一切正常。输出如下所示:

City: Moscow, ZMV: 00000.1.27612, Country: RU
City: New York, ZMV: 10001.5.99999, Country: US
City: TEST, ZMV: TEST, Country: TEST

但是当我中断应用程序时,我看到我的文件 favCities.plist 没有改变。仍然有两个值。这些值 - City: TEST, ZMV: TEST, Country: TEST - 没有添加。如果我重新启动应用程序,我会再次看到 3 行输出,尽管应该有 4 行。

怎么了?

更新:

我把代码改成了这样:

override func viewDidLoad() {
    super.viewDidLoad()

    let fileManager = (NSFileManager.defaultManager())
    let directorys : [String]? = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory,NSSearchPathDomainMask.AllDomainsMask, true) as? [String]

    if (directorys! != nil){
        let directories:[String] = directorys!;
        let dictionary = directories[0];

        let plistfile = "favCities.plist"
        let plistpath = dictionary.stringByAppendingPathComponent(plistfile);

        println("\(plistpath)")

        var plistArray = NSArray(contentsOfFile: plistpath) as [Dictionary<String, String>]

        var addDic: Dictionary = ["ZMV": "TEST", "Name": "TEST", "Country": "TEST"]
        plistArray += addDic

        (plistArray as NSArray).writeToFile(plistpath, atomically: false)

        var plistArray2 = NSArray(contentsOfFile: plistpath)

        for tempDict1 in plistArray2 {
            var tempDict2: NSDictionary = tempDict1 as NSDictionary
            var cityName: String = tempDict2.valueForKey("Name") as String
            var cityZMV: String = tempDict2.valueForKey("ZMV") as String
            var cityCountry: String = tempDict2.valueForKey("Country") as String
            println("City: \(cityName), ZMV: \(cityZMV), Country: \(cityCountry)")
        }
    }
    else {
        println("ERROR!")
    }

}

现在,当您运行应用程序时,输出中的行数会增加:

City: Moscow, ZMV: 00000.1.27612, Country: RU
City: New York, ZMV: 10001.5.99999, Country: US
City: TEST, ZMV: TEST, Country: TEST
City: TEST, ZMV: TEST, Country: TEST
........

但是!如果查看位于项目文件夹(Xcode 中的 Project Navigator)中的文件 favCities.plist,它仍然保持不变 - 有两行!

如果沿着路径走,它存储在变量plistpath - /Users/admin/Library/Developer/CoreSimulator/Devices/55FD9B7F-78F6-47E2-9874-AF30A21CD4A6/data/Containers/Data/Application/DEE6C3C8-6A44-4255-9A87-2CEF6082A63A/Documents/

然后还有一个文件favCities.plist。它包含构成应用程序的所有更改。我究竟做错了什么?如何查看位于项目文件夹(Project Navigator)中的文件中的所有更改?

【问题讨论】:

  • 检查writeToFile的返回值,你会看到它失败了。因为主包中的文件是只读的
  • (因此,iOS 应用程序中曾经使用 Objective-C 出现的所有典型错误,现在都使用 Swift 再次出现 :-)
  • 或者项目文件夹中的plist-files只需要初始使用(比如属性等)?

标签: swift nsdictionary plist ios8


【解决方案1】:

大多数情况下,人们想要存储一些东西的列表,所以这里是我分享的如何做到这一点,另外,这里我不复制 plist 文件,我只是创建它。实际的保存/加载与 Rebeloper 的答案非常相似

xcode 7 测试版,Swift 2.0

保存

func SaveItemFavorites(items : Array<ItemFavorite>) -> Bool
{
    let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true) as NSArray
    let docuDir = paths.firstObject as! String
    let path = docuDir.stringByAppendingPathComponent(ItemFavoritesFilePath)
    let filemanager = NSFileManager.defaultManager()

    let array = NSMutableArray()        
    
    for var i = 0 ; i < items.count ; i++
    {
        let dict = NSMutableDictionary()
        let ItemCode = items[i].ItemCode as NSString
        
        dict.setObject(ItemCode, forKey: "ItemCode")
        //add any aditional..
        array[i] = dict
    }
    
    let favoritesDictionary = NSDictionary(object: array, forKey: "favorites")
    //check if file exists
    if(!filemanager.fileExistsAtPath(path))
    {
        let created = filemanager.createFileAtPath(path, contents: nil, attributes: nil)
         if(created)
         {
             let succeeded = favoritesDictionary.writeToFile(path, atomically: true)
             return succeeded
         }
         return false
    }
    else
    {
        let succeeded = notificationDictionary.writeToFile(path, atomically: true)
        return succeeded
    }
}

来自文档的小注释:

NSDictionary.writeToFile(path:atomically:)

此方法在写出文件之前递归地验证所有包含的对象都是属性列表对象(NSDataNSDateNSNumberNSStringNSArrayNSDictionary 的实例),如果所有对象都不是属性列表对象,则返回 NO,因为结果文件不是有效的属性列表。

所以无论您在dict.SetObject() 设置什么,都应该是上述类型之一。

加载中

private let ItemFavoritesFilePath = "ItemFavorites.plist"

func LoadItemFavorites() -> Array<ItemFavorite>
{
    let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true) as NSArray
    let docuDir = paths.firstObject as! String
    let path = docuDir.stringByAppendingPathComponent(ItemFavoritesFilePath)
    let dict = NSDictionary(contentsOfFile: path)
    let dictitems : AnyObject? = dict?.objectForKey("favorites")
    
    var favoriteItemsList = Array<ItemFavorite>()
    
    if let arrayitems = dictitems as? NSArray
    {
        for var i = 0;i<arrayitems.count;i++
        {
            if let itemDict = arrayitems[i] as? NSDictionary
            {
                let ItemCode = itemDict.objectForKey("ItemCode") as? String
                //get any additional
                
                let ItemFavorite = ItemFavorite(item: ItemCode)
                favoriteItemsList.append(ItemFavorite)
            }
        }
    }
    
    return favoriteItemsList
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多