Couldn't read data from pList file. (Swift, iOS) - ios

Im trying to read and load data from a pList file. I have stored the data as NSArray in the file. But i couldn't read it. Below is the code that I have used.
var documentsDirectory = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as NSString
var path : NSString = documentsDirectory.stringByAppendingPathComponent("imagesPList.pList")
var data = NSMutableArray(contentsOfFile: path)
I took help from this source
Please help. Thanks in advance.

Try This.
let path = NSBundle.mainBundle().pathForResource("Property", ofType: "plist")
let dict = NSDictionary(contentsOfFile: path!)

Try this:
let settings = NSDictionary(contentsOfFile:"Root.plist")
if let preferences = settings.objectForKey("PreferenceSpecifiers"){
//do something ...
}

Related

Why does writing to plist fail in Swift?

I am trying to write the contents of an NSMutableDictionary to a plist in Swift 3. This is the structure I used in Objective-C but it does not work in Swift. When running the code below, it results in an error. Does anyone have any idea what might be wrong here?
let array1 = "\(Int(Value1))"
let array2 = "\(Int(Value2))"
let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
let plistpath = NSURL(fileURLWithPath: paths[0]).appendingPathComponent("myplist9.plist")!.absoluteString
let dictionary: NSMutableDictionary = ["String":"String"]
dictionary["Value 1"] = array1
dictionary["Value 2"] = array2
if dictionary.write(toFile: plistpath, atomically: false) {
print("Success")
}
else {
print("Error")
}
You can't get convert an NSURL to a file path using the absoluteString method. You need to use the path method.
Change:
let plistpath = NSURL(fileURLWithPath: paths[0]).appendingPathComponent("myplist9.plist")!.absoluteString
to:
let plistpath = NSURL(fileURLWithPath: paths[0]).appendingPathComponent("myplist9.plist")!.path
And since you are using Swift 3, use URL, not NSURL.
let plistpath = URL(fileURLWithPath: paths[0]).appendingPathComponent("myplist9.plist")!.path
Or you can use the NSDictionary write(to:atomically:) method that takes a URL.

plist file gets written in swift 1.2 but its not get written or works in swift 2.0, what should i do?

I had written a code when i was working with swift 1.2 which its function is loading and saving the data from plist. it was working fine with swift 1.2 but now that im working on swift 2. the code still loads the value but it doesnt save the value.
i run the application on device and not the simulator.
you can see the codes below:
func loadGameData() {
let path = NSBundle.mainBundle().pathForResource("GameData", ofType: "plist")!
let myDict = NSDictionary(contentsOfFile: path)
if let dict = myDict {
highscore = dict.objectForKey("highscore")!
} else {
print("WARNING: Couldn't create dictionary from GameData.plist! Default values will be used!")
}
}
func saveGameData() {
let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true) as NSArray
let documentsDirectory = paths.objectAtIndex(0) as! NSString
let path = documentsDirectory.stringByAppendingPathComponent("GameData.plist")
let dict: NSMutableDictionary = ["XInitializerItem": "DoNotEverChangeMe"]
dict.setObject(highscore.integerValue, forKey: "highscore")
//writing to GameData.plist
dict.writeToFile(path, atomically: true)
let resultDictionary = NSMutableDictionary(contentsOfFile: path)
print("Saved GameData.plist file is --> \(resultDictionary?.description)")
}
the console message after saving the code is:
Saved GameData.plist file is --> Optional("{\n XInitializerItem = DoNotEverChangeMe;\n highscore = 25;\n}")
does anyone know a different code which works with swift 2 ? this one worked fine with the previous versions.
Tnx for the help
Problem is you are reading from Main bundle while writing into Documents directly.
Reading Path: NSBundle.mainBundle().pathForResource("GameData", ofType: "plist")!
Writing Path: NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true) as NSArray
To fix this, change your reader code like:
func loadGameData() {
let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true) as NSArray
let documentsDirectory = paths.objectAtIndex(0) as! NSString
let path = documentsDirectory.stringByAppendingPathComponent("GameData.plist")
let myDict = NSDictionary(contentsOfFile: path)
if let dict = myDict {
highscore = dict.objectForKey("highscore")!
} else {
print("WARNING: Couldn't create dictionary from GameData.plist! Default values will be used!")
}
}

Trying to read a plist file from the Document directory using swift 2.0

Ok, Managed to put this code together, created a plist file with Xcode which I copied {using iTunes} to the app folder, it doesn't work...
import Foundation
class getBeaconConfiguration {
var myBeaconsDict: NSDictionary?
func getBeacons() {
let documentsPath : AnyObject = NSSearchPathForDirectoriesInDomains(.DocumentDirectory,.UserDomainMask,true)[0]
let sourcePath:NSString = documentsPath.stringByAppendingString("/beacons.plist")
let dict = NSDictionary(contentsOfFile: sourcePath as String)
print("dict",dict)
}
}
The path is good, and the plist is there, but the NSDictionary returned is a null pointer it seems. How do you do this in swift 2.0.
Get Create a URL to the file and then create a dictionary from it.
let filename = "beacons.plist"
guard
let fileURL = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask).first?.URLByAppendingPathComponent(filename)
else { fatalError("Unable to get file") }
let dict = NSDictionary(contentsOfURL: fileURL)
A little different in Swift 2.0, String no longer has stringByAppendingPathComponent, and you should be using this method when working with file paths.
let documentsPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as NSString
let sourcePath = documentsPath.stringByAppendingPathComponent("beacons.plist")
let dictionary = NSDictionary(contentsOfFile: sourcePath as String)
print("dict: \(dictionary)")

read/write to array plist with Swift

Im trying to read a plist that contains an Array of Ints .
This is my first time using them , and i can read them in fine , but the plist doesn't update when i write to it.
here's my code for the reading and writing..
class FavouritesManager {
var myArray:NSMutableArray = [0]
func loadDataPlist(){
let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true) as NSArray
let documentsDirectory = paths.objectAtIndex(0)as NSString
let path = documentsDirectory.stringByAppendingPathComponent("FavouriteIndex.plist")
let fileManager = NSFileManager.defaultManager()
if(!fileManager.fileExistsAtPath(path))
{
let bundle = NSBundle.mainBundle().pathForResource("FavouriteIndex", ofType: "plist")
fileManager.copyItemAtPath(bundle!, toPath: path, error:nil)
}
myArray = NSMutableArray(contentsOfFile: path)!
println(myArray)
}
func writeToPlist(indexValue:Int) {
if let path = NSBundle.mainBundle().pathForResource("FavouriteIndex", ofType: "plist"){
myArray.addObject(indexValue)
myArray.addObject(indexValue+5)
myArray.addObject(indexValue+10)
myArray.addObject(indexValue+15)
myArray.writeToFile(path, atomically: true)
}
}
The purpose of this code is to store the index of the tableViewCell that has been favourited so that I can display that row in my favourite tableViewControllwe
BTW - my plist looks like this...
Thanks !
Your problem is that you are loading the plist into your documents directory in loadDataPlist(), but you are still pulling the plist from it's original location in your writeToPlist(indexValue:) function. So you are trying to write to a plist at a readonly location. Change your write function to this:
func writeToPlist(indexValue:Int) {
var paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as String
var path = paths.stringByAppendingPathComponent("MyPlist.plist")
if var plistArray = NSMutableArray(contentsOfFile: path) {
plistArray.addObject(indexValue)
plistArray.addObject(indexValue+5)
plistArray.addObject(indexValue+10)
plistArray.addObject(indexValue+15)
plistArray.writeToFile(path, atomically: false)
}
}
Note that instead of adding the values to myArray I'm only writing to the plist. You'll have to decide if you want to maintain the two arrays (the local variable myArray and the array in the plist) depending on what you're using this for. Either way, this should fix your problem.

How can I read data from a PLIST in Swift?

i'm facing a problem with reading data from a plist file using swift
my code:
let Chapterpath = NSBundle.mainBundle().pathForResource("chapterMapping", ofType: "plist")
let dict2 = NSDictionary(contentsOfFile: Chapterpath!)
let chaptername = dict2?.objectForKey("chapterName")
let chapterNumber = dict2?.objectForKey("pageNumber")
next i'm trying to add plist data to an array, should i simply use
var myArray = [chapterName]
my question: is the code above correct?
or im i missing something
and when i tried to print plist data using println((chapterName))
i got an error
thank you
First, your Root object in the plist is an NSArray not a NSDictionary.
Second, if you want to use KVC on Foundation Collections (I don't believe this works with Swift's Array) you need to call valueForKeyPath.
let chapterPath = NSBundle.mainBundle().pathForResource("chapterMapping", ofType: "plist")
if let arrayOfItems: [AnyObject] = NSArray(contentsOfFile: chapterPath!) {
let chapterNames: [String] = arrayOfItems.valueForKeyPath("chapterName") as NSArray as [String]
let pageNumbers: [Int] = arrayOfItems.valueForKeyPath("pageNumber") as NSArray as [Int]
}
Third, the swift-y way of doing this would be with the map function, but arrayOfItems would need to be a strongly-defined type and it might be more work than it's worth. Example:
let array: [ChapterMetaData] = // define it here
let chapterImages = array.map { $0.chapterImage }
As you say you have an array with multiple element. objectForKey does not search the hall tree levels and gets you the first one with the name. you have multiple values a loop must be envolved. Try the following:
var Chapterpath:NSString = NSBundle.mainBundle().pathForResource("chapterMapping", ofType: "plist");
var chapters:NSArray = NSArray(contentsOfFile: Chapterpath);
for chapter in chapters {
let chaptername = chapter["chapterName"]
let chapterNumber = chapter["pageNumber"]
println(chaptername);
}
Use following code to read Plist data to NSArray:
let path = NSBundle.mainBundle().pathForResource(plistName, ofType: "plist")
var list = NSArray(contentsOfFile: path!) as [[String:String]]
Simplest way to parse the AppConfig.plist file in project:
var dictionaryObj: NSDictionary?
if let filePath = NSBundle.mainBundle().pathForResource("AppConfig", ofType: "plist")
{
dictionaryObj = NSDictionary(contentsOfFile: filePath)
}
if let dict = dictionaryObj
{
//parse it as NSDictionary
}
else
{
//dictionaryObj is nil or doesn't contain anything.
}
You can use NSArray if Plist Root is Array:
let path = NSBundle.mainBundle().pathForResource("OrderHelper", ofType: "plist")
let myArray = NSArray(contentsOfFile: path!)
You can use NSDictionary if Plist Root is Dictionary:
let path = NSBundle.mainBundle().pathForResource("OrderHelper", ofType: "plist") {
let myDict = NSDictionary(contentsOfFile: path!)

Resources