Swift Remove Item plist - swift

in my progect i add a item on plist in this mode
//Get path of Documents directory
var paths = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)
var documentsDirectory:AnyObject = paths[0]
var path = documentsDirectory.stringByAppendingPathComponent("samplePlist.plist")
var fileManager = NSFileManager.defaultManager()
var fileExists:Bool = fileManager.fileExistsAtPath(path)
var data : NSMutableDictionary?
//Check if plist file exists at path specified
if fileExists == false {
//File does not exists
data = NSMutableDictionary () //Create data dictionary for storing in plist
} else {
//File exists – retrieve data from plist inside data dictionary
data = NSMutableDictionary(contentsOfFile: path)
}
data?.setValue("hi", forKey: "NameButton")
my plist is this
<dict>
<key>NameButton</key>
<string>1</string>
</dict>
</plist>
and if i want remove NameButton from my plist ?

Related

Swift: pList with "complex" data

As I read and tried out :-) I can only save some simple data types on pList files. Nevertheless I like to use structs, classes etc to represent my data. This should be saved as easily as possible to a pList file and gets reloaded.
I see, that NSData is a valid type for pLists. And also, that this is a general data type. So it is a good idea to move/convert/force a struct or class variable into a NSData object to be saved and reloaded? How would that be done?
Till now I'm using something like this for saving:
let dict: NSMutableDictionary = ["XYZ": "XYZ"]
// saving values
dict.setObject(myBasicArray, forKey: "BasicArray")
dict.writeToFile(path, atomically: false)
Updated:
I used the offered code and extended it to handle a struct:
import Cocoa
struct SteeringItem {
var ext = String() // extension including dot e.g. ".JPG"
var bitmap = Int() // flag for grouping file types, e.g. photos
init?(ext: String, bitmap: Int) {
// Initialize stored properties.
self.ext = ext
self.bitmap = bitmap
}
}
class Foo {
let one: Int
let two: SteeringItem
init(one:Int, two: SteeringItem) {
self.one = one
self.two = two
}
init?(dict:[String: AnyObject]) {
guard let
one = dict["one"] as? Int,
two = dict["two"] as? SteeringItem else { return nil }
self.one = one
self.two = two
}
func toDictionary() -> [String: AnyObject] {
var retval = [String: AnyObject]()
if let
one = self.one as? AnyObject,
two = self.two as? AnyObject {
retval["one"] = one
retval["two"] = two
}
return retval
}
}
// create struct
let writeStruct = Foo(one: 1, two: SteeringItem(ext: "one",bitmap: 1)!)
print(writeStruct, "\n")
// write to plist
let writeDict = writeStruct.toDictionary() as NSDictionary
let path = ("~/test.plist" as NSString).stringByExpandingTildeInPath
writeDict.writeToFile(path, atomically: true)
// print contents of file
print(try NSString(contentsOfFile: path, encoding: NSUTF8StringEncoding))
// read plist and recreate struct
if let
readDict = NSDictionary(contentsOfFile: path) as? [String:AnyObject],
readStruct = Foo(dict: readDict) {
print(readStruct)
}
but this does not write anymore. With String it worked, with "struct SteeringItem" it doesn't!
Update 2: class instead of struct
class SteeringItem : NSObject, NSCoding {
var ext = String() // extension including dot e.g. ".JPG"
var bitmap = Int() // flag for grouping file types, e.g. photos
func encodeWithCoder(aCoder: NSCoder) {
aCoder.encodeObject(ext, forKey: "ext")
aCoder.encodeObject(bitmap, forKey: "bitmap")
}
required convenience init?(coder aDecoder: NSCoder) {
let ext = aDecoder.decodeObjectForKey("ext") as! String
let bitmap = aDecoder.decodeObjectForKey("bitmap") as! Int
self.init(ext: ext, bitmap: bitmap)
}
init?(ext: String, bitmap: Int) {
// Initialize stored properties.
self.ext = ext
self.bitmap = bitmap
super.init()
}
}
There's several ways to do this, you can adhere to the NSCoding protocol or you can write methods to convert your class/struct to a Dictionary and serialize from there.
Here's a good intro to using the NSCoding protocol.
As for converting to and from a Dictionary the usual way is to provide a failable init method that takes a Dictionary<String, AnyObject> which validates and copies the key:value pairs to the member variables. You also provide a method that returns a Dictionary<String, AnyObject> with the same key:value pairs as the init takes. Then you can serialize by calling the create method and serializing the resulting Dictionary, you deserialize by reading into a Dictionary and passing that in to the init method.
Here's an example of the conversion:
/// Provides conversion to and from [String: AnyObject] for use in serialization
protocol Serializable {
init?(dict:[String: AnyObject])
func toDictionary() -> [String: AnyObject]
}
struct SteeringItem {
// Changed var to let, it's a good practice with a simple struct
let ext : String // extension including dot e.g. ".JPG"
let bitmap : Int // flag for grouping file types, e.g. photos
}
struct Foo {
let one: Int
let two: SteeringItem
}
// Add serialization to structs
extension SteeringItem: Serializable {
init?(dict:[String: AnyObject]) {
guard let
ext = dict["ext"] as? String,
bitmap = dict["bitmap"] as? Int else { return nil }
self.ext = ext
self.bitmap = bitmap
}
func toDictionary() -> [String: AnyObject] {
var retval = [String: AnyObject]()
if let
ext = self.ext as? AnyObject,
bitmap = self.bitmap as? AnyObject {
retval["ext"] = ext
retval["bitmap"] = bitmap
}
return retval
}
}
extension Foo: Serializable {
init?(dict:[String: AnyObject]) {
guard let
one = dict["one"] as? Int,
twoDict = dict["two"] as? [String: AnyObject],
two = SteeringItem(dict: twoDict) else { return nil }
self.one = one
self.two = two
}
func toDictionary() -> [String: AnyObject] {
var retval = [String: AnyObject]()
let twoDict = self.two.toDictionary()
if let
one = self.one as? AnyObject,
two = twoDict as? AnyObject {
retval["one"] = one
retval["two"] = two
}
return retval
}
}
Here's how to test it (in a playground):
import Foundation
// create struct
let writeStruct = Foo(one: 1, two: SteeringItem(ext: "jpg", bitmap: 1))
print(writeStruct, "\n")
// write to plist
let writeDict = writeStruct.toDictionary() as NSDictionary
let path = ("~/test.plist" as NSString).stringByExpandingTildeInPath
writeDict.writeToFile(path, atomically: true)
// print contents of file
print(try NSString(contentsOfFile: path, encoding: NSUTF8StringEncoding))
// read plist and recreate struct
if let
readDict = NSDictionary(contentsOfFile: path) as? [String:AnyObject],
readStruct = Foo(dict: readDict) {
print(readStruct)
}
Results:
Foo(one: 1, two: SteeringItem(ext: "jpg", bitmap: 1))
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>one</key>
<integer>1</integer>
<key>two</key>
<dict>
<key>bitmap</key>
<integer>1</integer>
<key>ext</key>
<string>jpg</string>
</dict>
</dict>
</plist>
Foo(one: 1, two: SteeringItem(ext: "jpg", bitmap: 1))

Can not create UIImage and append it to array

I have string array of file names, which looks like this
["xBGEx.jpg", "OgJuM.jpg"]
This is images, which saved to documents directory. I try to create array of UIImages by appending full path in for look and then appending to array.
In my appDelegate I have code in didFinishLaunchingWithOptions it looks like
var paths:[AnyObject] = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)
var documentsDirectory = paths[0] as? String
self.documentsRoot = documentsDirectory! + "/"
Then, when Im in controller, which I need I do the following
var slider = ["xBGEx.jpg", "OgJuM.jpg"]
var UIImageArray = [UIImage]()
for element in imgArray {
var path = "\(appDelegate.documentsRoot!)" + "\(element)"
var obj:UIImage = UIImage(contentsOfFile: path)!
UIImageArray.append(obj)
}
imageArray = UIImageArray
but when I build I have nil error in the moment of appending
What am I doing wrong ?
Seems like the path doesn't lead to an image file.
You should check if the file you found a path for really is an image and not force the cast with !
for element in imgArray {
var path = "\(appDelegate.documentsRoot!)" + "\(element)"
if let obj = UIImage(contentsOfFile: path) {
UIImageArray.append(obj)
}
}
On another note PLEASE don't name your variables with a capital letter
uiImageArray would be much better.

Swift plist - Reading item 4

I want to translate my current program to Swift and I am getting hung up on the simplest things.
I am trying to read a plist
But I want to do this one at a time.
i.e. - if we are trying to call the image candy hearts.jpg (we obviously need to add the extension jpeg.
This is what I found on on the net.
var myDict: NSDictionary?
if let path = NSBundle.mainBundle().pathForResource("data", ofType: "plist") {
myDict = NSDictionary(contentsOfFile: path)
// self.data
}
if let dict = myDict {
// Use your dict here
}
This is what I originally used iOS6
NSString *pathOfDataTitle = [[NSBundle mainBundle] pathForResource:#"data" ofType:#"plist"];
NSMutableArray *arrayOfTitle = [[NSMutableArray alloc] initWithContentsOfFile:pathOfDataTitle];
self.Datalist = arrayOfTitle;
This worked
var data: NSArray?
var imagename : String!
func readlist(var filename:String) -> NSArray{
var myDict: NSArray?
let path = NSBundle.mainBundle().pathForResource(filename, ofType: "plist")
if (path != nil){
var val:String
val=path!;
myDict = NSArray(contentsOfFile: val)
var list=myDict;
}
if let dict = myDict {
return myDict!;
}
return myDict!;
}
}

Swift convert Plist(inside NSString) to NSDictionary

Hello I have a NSString that contains Plist data. I need to convert it to NSDictionary. I have found ways to do it with a file but I want to do it directly in memory. How can I do this with swift? thank you for the help.
var plist : NSMutableDictionary
let nsDocumentDirectory = NSSearchPathDirectory.DocumentDirectory
let nsUserDomainMask = NSSearchPathDomainMask.UserDomainMask
if let paths = NSSearchPathForDirectoriesInDomains(nsDocumentDirectory, nsUserDomainMask, true) {
if paths.count > 0 {
if let dirPath = paths[0] as? String {
let readPath = dirPath.stringByAppendingPathComponent("info.plist")
plist = NSMutableDictionary(contentsOfFile: readPath)!
println(plist)
}
}
}
After alot a alot of gooling and playing with it I came across
var data = stringWithPlistInside.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)
var error : NSError?
var dic: AnyObject! = NSPropertyListSerialization.propertyListWithData(data!, options: 0, format: nil, error: &error)
Just in case anyone else happens to be stuck in my situation.

Swift Save/Reload data to plist

I entered my samplePlist.plist in the project folder and I'm trying to save the data on this .....
var paths = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true) //Get Path of Documents Directory
var documentsDirectory:AnyObject = paths[0]
var path = documentsDirectory.stringByAppendingPathComponent("samplePlist.plist")
var fileManager = NSFileManager.defaultManager()
var fileExists:Bool = fileManager.fileExistsAtPath(path)
var data : NSMutableDictionary?
//Check if plist file exists at path specified
if fileExists == false {
//File does not exists
data = NSMutableDictionary () //Create data dictionary for storing in plist
} else {
//File exists – retrieve data from plist inside data dictionary
data = NSMutableDictionary(contentsOfFile: path)
}
data?.setValue("\(countButton)", forKey: "NumeroButton")
data?.writeToFile(path, atomically: true) //Write data to file permanently
and i Read to the plist
//Get path of Documents directory
var paths = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)
var documentsDirectory:AnyObject = paths[0]
var path = documentsDirectory.stringByAppendingPathComponent("samplePlist.plist")
//Retrieve contents from file at specified path
var data = NSMutableDictionary(contentsOfFile: path!)
println(path)
my problem is that ,if I try to start it on my iphone ,I do not upload the file to the My Documents folder on startup of the Application
/var/mobile/Containers/Data/Application/9CCDBD0B-FA29-4C9E-910E-9AD5F5B11E5A/Documents/samplePlist.plist
fatal error: unexpectedly found nil while unwrapping an Optional value