How to Save, Retrieve, Delete & Update My Data in Plist File in iOS

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 can i update plist file which has many group item in Objective-C?

First of all, When you retrieve the .plist file, store it as NSMutableDictionary.

NSString *filePath = [[NSBundle mainBundle] pathForResource:@"your plist name" ofType:@"plist"];
NSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithContentsOfFile:filePath];
NSMutableArray *filmsPlaying = [[NSMutableArray alloc] iniWithArray:[dict objectForKey:@"FilmsPlaying"]];
NSMutableDictionary *filmToEdit = [filmsPlaying objectAtIndex:1];// IRL run a loop to get your desired film
NSString *newSeats = @"1-2-9";
[filmToEdit setObject:newSeats forKey:@"ZFILMSEAT"];
[filmsPlaying replaceObjectAtIndex:1 withObject:filmsToEdit];
[dict setObject:filmsPlaying forKey:@"FilmsPlaying"];

Here you have the film you want to edit. After you have made your edition to that dictionary, you need to write it back to App's document dir. (NOTE: You CANNOT save it back to your main bundle but you can write it to Documents instead).

NSString *pathForPlist = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
pathForPlist = [savingPath stringByAppendingPathComponent:@"your plist name.plist"];
[dict writeToFile:savingPath automically:YES];

To edit it in the main bundle without any programming, you can simply open it in any text editor or xcode itself and make your edition. Nothing techie about that.

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)

Updating and saving data in plist

The easiest way to create a dictionary from a plist is to use the method dictionaryWithContentsOfFile:,

For example, to load a plist from your resources:

NSString *filePath = [[NSBundle mainBundle] pathForResource:@"playerData" ofType:@"plist"];
NSMutableDictionary *plistdict = [NSMutableDictionary dictionaryWithContentsOfFile:filePath];

Writing a plistdict is equally simple:

[plistdict writeToFile:filePath atomically:YES];

Note that you can't write into your app's resources, so you'll have to create a different path, e.g. in your Documents directory for your plist.

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
NSString *docfilePath = [basePath stringByAppendingPathComponent:@"playerData.plist"];
[plistdict writeToFile:docfilePath atomically:YES];

Now retrieve data from plist again.

 NSMutableDictionary *plistdict = [NSMutableDictionary dictionaryWithContentsOfFile:docfilePath];

Add your content in plistDict and write it again.

Updating plist file via code


  1. Yes. Writing a file is permanent, as long as you obviously don't delete/move the file somewhere else.

  2. That is a valid option

  3. Yes. If you need a blank file, you don't need it from the bundle. A better idea would be to create it when you need it (when there is something to write). Usually file creations are managed like so

    • Check if file exists
    • If not, create it.
    • Use the file.

If you need a template file (with already some stuff written in it), then a copy from the bundle is more appropriate. But even then, a lot of developers will like to do everything from code, it's not that heavy of a task, and it forces you to create/prepare the right objects and methods from the get-go.

Like Rooe N said, the NSUserDefaults IS a property list, so if you're talking about very simple data, say, like a username and a last-time-I-logged-In-date, you could store it there.

Note that NSUserDefaults are loaded all the way, every time you load the app, so you don't wanna use it as a database. But since you're going for .plist, I'll assume you've already ruled DBs out.

How to read and save data from a remote plist file

No, there isn't a native way to read and write to an external .plist using just Swift without downloading the file, making changes and re-uploading it. Alternatively, you'd need to set up your own API on a server in order to carry out the read / write actions for you.

As @Scott H stated in the comments, theres a better way to do this:

If you want to go this route, download the file locally, change it
locally, and then upload to the server. However, there are many
alternatives available to you for remote configuration like CloudKit,
Parse, or similar.

Learn more about 3rd party options:

  • CloudKit
  • Parse

How do I clear the data in a plist created in Xcode?

The simplest thing would be to delete the file using NSFileManager, like this:

[[NSFileManager defaultManager] removeItemAtPath:plistPath error:NULL];

Or if you don't want to do that, assuming the plist is a dictionary, just load the one from your application bundle and then overwrite the one in your documents, like this:

NSDictionary *originalPlist = [NSDictionary dictionaryWithContentsOfFile:bundleFile];
[originalPlist writeToFile:documentsFile atomically:YES];

Which will overwrite the saved file with the original file.

iOS -- NSCoding -- storing data in PList vs Documents Directory

See Archives and Serializations Programming Guide: Serializing Property Lists for a discussion of why, when you're capturing a hierarchical object graph, why "coding (as implemented by NSCoder and its subclasses) is the preferred way to make object graphs persistent":

Serialization converts Objective-C types to and from an architecture-independent byte stream. In contrast to archiving, basic serialization does not record the data type of the values nor the relationships between them; only the values themselves are recorded. It is your responsibility to deserialize the data in the proper order.

Property list serialization does not preserve the full class identity of the objects, only its general kind—a dictionary, an array, and so on. As a result, if a property list is serialized and then deserialized, the objects in the resulting property list might not be of the same class as the objects in the original property list. In particular, when a property list is serialized, the mutability of the container objects (NSDictionary and NSArray objects) is not preserved. When deserializing, though, you can choose to have all container objects created mutable or immutable.

Serialization also does not track the presence of objects referenced multiple times. Each reference to an object within the property list is serialized separately, resulting in multiple instances when deserialized.

Because serialization does not preserve class information or mutability, nor handles multiple references, coding (as implemented by NSCoder and its subclasses) is the preferred way to make object graphs persistent.

Bottom line, you'd generally prefer to use NSKeyedArchiver (or in Swift 4, PropertyListEncoder) because it captures information about the classes that are encoded and can capture richer types.

Having said that, plists are very simple and are often rendered in text formats that make it easy to visually inspect the resulting data and you can see what was captured. And often, if you're dealing with a nice simple list, plists are a nice, slightly simplified solution.

On updating iOS app, force plist in Documents to be overwritten/deleted?

You can append the bundle version (CFBundleVersion) to the plist you want updated and dynamically load a depending on the bundle version stored in the apps info.plist.

So for version 1.3, you'd load your_plist.1.3.plist

NSString *plistString = [NSString stringWithFormat:@"your_plist_%@", [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"]];

[[NSBundle mainBundle] pathForResource:plistString ofType:@"plist"];


Related Topics



Leave a reply



Submit