How to Save an Array to .Plist in the App's Mainbundle in Swift

Save Data to .plist File in Swift

Apparently the file is not in a writable location, so I created it in the documents directory.

var paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as String
var path = paths.stringByAppendingPathComponent("data.plist")
var fileManager = NSFileManager.defaultManager()
if (!(fileManager.fileExistsAtPath(path)))
{
var bundle : NSString = NSBundle.mainBundle().pathForResource("data", ofType: "plist")
fileManager.copyItemAtPath(bundle, toPath: path, error:nil)
}
data.setObject(object, forKey: "object")
data.writeToFile(path, atomically: true)

Then, it has to be read from the documents directory.

var paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as String
var path = paths.stringByAppendingPathComponent("data.plist")
let save = NSDictionary(contentsOfFile: path)

writing NSDictionary to plist in my app bundle

Johan is right -- you're not allowed to modify your app's bundle. You have two good options for where to save your dictionary: the documents directory, which is backed up by iTunes when a user syncs their device; or the caches directory, which is not backed up. If you don't need to have the data backed up, put it in caches so you don't slow down syncing. You can get the directory paths like so:

NSString *documentsDirectoryPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];

NSString *cachesDirectoryPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0];

How can i save, retrieve, delete & update my data in Plist file in ios?

I am going through with screenshot and step by step. Please follow this and you will get your answer.

First you have to create Property List through your Xcode.

Step:1

Sample Image

Step:2

Sample Image

Step:3

Save data on your save button action :

   // Take 3 array for save the data .....

-(IBAction)save_Action:(id)sender
{
NSArray *paths = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsPath = [paths objectAtIndex:0];
NSString *plistPath = [documentsPath stringByAppendingPathComponent:@"manuallyData.plist"];

[self.nameArr addObject:self.nameField.text];
[self.countryArr addObject:self.countryField.text];
[self.imageArr addObject:@"image.png"];

NSDictionary *plistDict = [[NSDictionary alloc] initWithObjects: [NSArray arrayWithObjects: self.nameArr, self.countryArr, self.imageArr, nil] forKeys:[NSArray arrayWithObjects: @"Name", @"Country",@"Image", nil]];

NSError *error = nil;
NSData *plistData = [NSPropertyListSerialization dataFromPropertyList:plistDict format:NSPropertyListXMLFormat_v1_0 errorDescription:&error];

if(plistData)
{
[plistData writeToFile:plistPath atomically:YES];
alertLbl.text = @"Data saved sucessfully";
}
else
{
alertLbl.text = @"Data not saved";
}
}
// Data is saved in your plist and plist is saved in DocumentDirectory

Step:4

Retrieve Data from plist File:

    NSArray *paths = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsPath = [paths objectAtIndex:0];
NSString *plistPath = [documentsPath stringByAppendingPathComponent:@"manuallyData.plist"];

if (![[NSFileManager defaultManager] fileExistsAtPath:plistPath])
{
plistPath = [[NSBundle mainBundle] pathForResource:@"manuallyData" ofType:@"plist"];
}

NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:plistPath];
self.nameArr = [dict objectForKey:@"Name"];
self.countryArr = [dict objectForKey:@"Country"];

Step:5

Remove data from plist file:

    NSArray *paths = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsPath = [paths objectAtIndex:0];
NSString *plistPath = [documentsPath stringByAppendingPathComponent:@"manuallyData.plist"];
NSMutableDictionary *dictionary = [NSMutableDictionary dictionaryWithContentsOfFile:(NSString *)plistPath];

self.nameArr = [dictionary objectForKey:@"Name"];
self.countryArr = [dictionary objectForKey:@"Country"];

[self.nameArr removeObjectAtIndex:indexPath.row];
[self.countryArr removeObjectAtIndex:indexPath.row];

[dictionary writeToFile:plistPath atomically:YES];

Step:6

Update your data on Update click Action:

    NSArray *paths = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsPath = [paths objectAtIndex:0];
NSString *plistPath = [documentsPath stringByAppendingPathComponent:@"manuallyData.plist"];

if (![[NSFileManager defaultManager] fileExistsAtPath:plistPath])
{
plistPath = [[NSBundle mainBundle] pathForResource:@"manuallyData" ofType:@"plist"];
}

self.plistDic = [[NSDictionary alloc] initWithContentsOfFile:plistPath];

[[self.plistDic objectForKey:@"Name"] removeObjectAtIndex:self.indexPath];
[[self.plistDic objectForKey:@"Country"] removeObjectAtIndex:self.indexPath];
[[self.plistDic objectForKey:@"Image"] removeObjectAtIndex:self.indexPath];

[[self.plistDic objectForKey:@"Name"] insertObject:nameField.text atIndex:self.indexPath];
[[self.plistDic objectForKey:@"Country"] insertObject:countryField.text atIndex:self.indexPath];
[[self.plistDic objectForKey:@"Image"] insertObject:@"dhoni.jpg" atIndex:self.indexPath];

[self.plistDic writeToFile:plistPath atomically:YES];

How to write data in plist?

I don't know if I understand your question, but if you want to write into a .plist within your .app bundle you are probably doing something wrong. If you want to store preferences, you should consider using NSUserDefaults.

If you really want to modify a bundled .plist - here is some code:

NSString *plistPath = nil;
NSFileManager *manager = [NSFileManager defaultManager];
if (plistPath = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:@"Contents/Info.plist"])
{
if ([manager isWritableFileAtPath:plistPath])
{
NSMutableDictionary *infoDict = [NSMutableDictionary dictionaryWithContentsOfFile:plistPath];
[infoDict setObject:[NSNumber numberWithBool:hidden] forKey:@"LSUIElement"];
[infoDict writeToFile:plistPath atomically:NO];
[manager changeFileAttributes:[NSDictionary dictionaryWithObject:[NSDate date] forKey:NSFileModificationDate] atPath: [[NSBundle mainBundle] bundlePath]];
}
}

Update:
Nate Flink pointed out that some of the NSFileManager methods used above are deprecated.
He posted an answer with the replacement methods below:
https://stackoverflow.com/a/12428472/100848

How to parse certain data into an array in Swift?

Here is a solution using high order functions. Hopefully this works for you.

let text = "tj thomas jeffereson \nbf benjamin franklin\ngw george washington"

let usernames = text.characters
.split { $0 == "\n" }
.map { String($0) }
.map { String($0.characters.split(" ")[0]) }

print(usernames)

output:

["tj", "bf", "gw"]

Loop through result:

for user in usernames {
print(user)
}

Update plist - swift

You should use a mutable dictionary instead of dictionary. Update data of your dictionary and when you finish, you write your mutable dictionary into file using writeToFile method :

func writeToFile(_ path: String, atomically atomically: Bool) -> Bool

According to your code you should :

  1. Change this line : if let dict = NSDictionary(contentsOfFile: path) as? Dictionary<String, AnyObject> to make a Mutable Dictionary : let dict = NSMutableDictionary(contentsOfFile: path)
  2. Update It
  3. Write it to your file : dict?.writeToFile(path, atomically: true)


Related Topics



Leave a reply



Submit