2014-07-11 20 views
5

Mam przykładowy plik plist, favCities.plist. To jest mój przykładowy kod:Zapis do pliku plist w Swift

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

Na pierwszy rzut oka wszystko działa dobrze. Wyjście wygląda następująco:

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

Ale kiedy przerwać aplikację, widzę, że mój plik favCities.plist nie uległa zmianie. Nadal istnieją dwie wartości. Te wartości - City: TEST, ZMV: TEST, Country: TEST - nie zostały dodane. Jeśli ponownie uruchomię aplikację, znowu widzę 3 linie wyjściowe, chociaż powinno być 4.

Co jest nie tak?

AKTUALIZACJA:

I został zmieniony kod do tego:

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

} 

Teraz po uruchomieniu aplikacji liczbę wierszy wzrasta wyjściowych:

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

ALE! Jeśli przeglądasz plik favCities.plist, który znajduje się w folderze projektu (Project Navigator w Xcode), pozostaje on niezmieniony - są dwie linie!

Jeśli spacer wzdłuż ścieżki, która jest przechowywana w zmiennej plistpath - /Users/admin/Library/Developer/CoreSimulator/Devices/55FD9B7F-78F6-47E2-9874-AF30A21CD4A6/data/Containers/Data/Application/DEE6C3C8-6A44-4255-9A87-2CEF6082A63A/Documents/

Potem jest jeszcze jeden plik favCities.plist. Zawiera wszystkie zmiany, które składają się na aplikację. Co ja robię źle? Jak mogę zobaczyć wszystkie zmiany w pliku znajdującym się w folderze projektu (Project Navigator)?

+2

wartość zwracana sprawdzenie 'writeToFile', a zobaczysz, że nie powiodła się. ponieważ pliki w głównym pakiecie są tylko do odczytu –

+1

możliwe duplikaty [pisania NSDictionary do plist w moim pakiecie aplikacji] (http://stackoverflow.com/questions/2502193/writing-nsdictionary-to-plist-in-my-app-bundle) –

+2

(Tak więc wszystkie typowe błędy w aplikacjach iOS, które były kiedyś wykonane przy użyciu Objective-C, są teraz ponownie tworzone za pomocą Swift :-) –

Odpowiedz

0

Tak, to rozwiązało problem - Swift - Read plist

Ale PLIST-pliki w folderze projektu używa tylko do sytuacji właściciela jak .....

0

Jeśli spojrzeć wstecz na to, jak szybko lub plist pisać na już istniejący klucz w 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) 
    } 
0

Głównie ludzie chcą przechowywać listę czegoś, więc tutaj jest mój udział w jaki sposób to zrobić, również tutaj nie skopiować plik plist, po prostu go utworzyć . Rzeczywiste oszczędności/ładowanie jest bardzo podobna do odpowiedzi z Rebeloper

Xcode 7 beta, Swift 2,0

oszczędność

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

liścik od docs:

NSDictionary.WriteToFile (ścieżka: atomowo :)

Metoda ta rekurencyjnie potwierdza, że ​​wszystkie zawarte obiekty są obiektami listy właściwości (przypadki NSData, NSDate, NSNumber, NSString, NSArray lub NSDictionary) przed wypisywanie pliku, a nie zwraca jeśli wszystkie obiekty nie są obiektami listy właściwości, ponieważ wynikowy plik nie byłby poprawną listą właściwości.

Cokolwiek ustawić na dict.SetObject() powinno być jednym z wyżej wymienionych typów.

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 
}