在Swift中写入plist文件

时间:2023-01-24 08:21:12

I have a sample plist-file, favCities.plist. This is my sample code:

我有一个样本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)")
    }

At first glance, everything works well. The output looks like this:

乍一看,一切都运作良好。输出如下:

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

But when I interrupt the app, I see that my file favCities.plist has not changed. There are still two values. These values ​​- City: TEST, ZMV: TEST, Country: TEST - were not added. If I restarted the application, then again I see 3 lines of output, although there should be 4.

但是当我打断应用程序时,我发现我的文件favCities.plist没有改变。还有两个值。这些值 - 城市:TEST,ZMV:TEST,国家:TEST - 未添加。如果我重新启动应用程序,那么我再次看到3行输出,尽管应该有4行。

What is wrong?

怎么了?

UPDATED:

I was changed code to this:

我把代码更改为:

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!")
    }

}

Now when you run the application the number of rows in the output increases:

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

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
........

BUT! If view the file favCities.plist, which is located in the project folder (Project Navigator in Xcode), it still remains unchanged - there are two lines!

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

If walk along the path, which is stored in the variable plistpath - /Users/admin/Library/Developer/CoreSimulator/Devices/55FD9B7F-78F6-47E2-9874-AF30A21CD4A6/data/Containers/Data/Application/DEE6C3C8-6A44-4255-9A87-2CEF6082A63A/Documents/

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

Then there is one more file favCities.plist. It contains all the changes that make the application. What am I doing wrong? How can I see all the changes in a file that is located in the project folder (Project Navigator)?

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

3 个解决方案

#1


0  

Yes, this solved the problem - Swift - Read plist

是的,这解决了问题 - Swift - Read plist

But plist-files in project folder uses only for property-like situation.....

但项目文件夹中的plist文件仅用于类似属性的情况.....

#2


0  

If you look back at how quickly or plist write on already existing key in plist

如果你回顾一下plist中现有密钥的写入速度或plist的速度

    var path = NSBundle.mainBundle().pathForResource("GameParam", ofType: "plist")
    if var dict = NSMutableDictionary(contentsOfFile: path!) {
        ToolKit.log(dict)
        dict.setValue("blablabla", forKey: "keyInPlist")

        dict.writeToFile(path!, atomically: false)
    }

#3


0  

Mostly, people want to store a list of something, so here is my share on how to do this, also, here I don't copy the plist file, I just create it. The actual saving/loading is quite similar to the answer from Rebeloper

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

xcode 7 beta, Swift 2.0

xcode 7 beta,Swift 2.0

saving

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
    }
}

Little note from the docs:

来自文档的小记录:

NSDictionary.writeToFile(path:atomically:)

This method recursively validates that all the contained objects are property list objects (instances of NSData, NSDate, NSNumber, NSString, NSArray, or NSDictionary) before writing out the file, and returns NO if all the objects are not property list objects, since the resultant file would not be a valid property list.

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

So whatever you set at dict.SetObject() should be one of the above mentioned types.

所以无论你在dict.SetObject()设置什么,都应该是上面提到的类型之一。

loading

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
}

#1


0  

Yes, this solved the problem - Swift - Read plist

是的,这解决了问题 - Swift - Read plist

But plist-files in project folder uses only for property-like situation.....

但项目文件夹中的plist文件仅用于类似属性的情况.....

#2


0  

If you look back at how quickly or plist write on already existing key in plist

如果你回顾一下plist中现有密钥的写入速度或plist的速度

    var path = NSBundle.mainBundle().pathForResource("GameParam", ofType: "plist")
    if var dict = NSMutableDictionary(contentsOfFile: path!) {
        ToolKit.log(dict)
        dict.setValue("blablabla", forKey: "keyInPlist")

        dict.writeToFile(path!, atomically: false)
    }

#3


0  

Mostly, people want to store a list of something, so here is my share on how to do this, also, here I don't copy the plist file, I just create it. The actual saving/loading is quite similar to the answer from Rebeloper

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

xcode 7 beta, Swift 2.0

xcode 7 beta,Swift 2.0

saving

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
    }
}

Little note from the docs:

来自文档的小记录:

NSDictionary.writeToFile(path:atomically:)

This method recursively validates that all the contained objects are property list objects (instances of NSData, NSDate, NSNumber, NSString, NSArray, or NSDictionary) before writing out the file, and returns NO if all the objects are not property list objects, since the resultant file would not be a valid property list.

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

So whatever you set at dict.SetObject() should be one of the above mentioned types.

所以无论你在dict.SetObject()设置什么,都应该是上面提到的类型之一。

loading

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
}