Saving image and its title on plist - ios

How can I store an image and any string value in plist as dictionary.I
have created a plist file in the project,and
also how can i append the file with same dictionary of different image and name?

Use the following code to write image & title to-gather in plist-
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:#"PlistName.plist"];
NSFileManager *fileManager = [NSFileManager defaultManager];
if (![fileManager fileExistsAtPath: path])
{
path = [documentsDirectory stringByAppendingPathComponent: [NSString stringWithFormat: #"PlistName.plist"] ];
}
fileManager = [NSFileManager defaultManager];
NSMutableDictionary *dataDictionary=[NSMutableDictionary alloc] init];
[dataDictionary setObject:ImageData forKey:image];
[dataDictionary setObject:ImageTitle forKey:title];
[dataDictionary writeToFile: path atomically:YES];
And read your image & title dictionary from plist like this-
- (NSDictionary * )readDataFromPlist()
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:#"PlistName.plist"];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSMutableDictionary *dataDictionary;
if ([fileManager fileExistsAtPath: path])
{
dataDictionary = [[NSMutableDictionary alloc] initWithContentsOfFile: path];
return dataDictionary;
}else
return nil;
}

You can follow this link. It provides detail how to store image to plist
Storing image in plist
And for title to store you can add new key like below.
// Get a full path to a plist within the Documents folder for the app
NSString *titleStr = #"Title Of Image";
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask,
YES);
NSString *path = [NSString stringWithFormat:#"%#/YOURPLIST.plist",
[paths objectAtIndex:0]];
// Place an image in a dictionary that will be stored as a plist
[dictionary setObject:image forKey:#"image"];
[dictionary setObject:titleStr forKey:#"title"];
// Write the dictionary to the filesystem as a plist
[NSKeyedArchiver archiveRootObject:dictionary toFile:path];

Related

Modifying and saving plist in iPhone app

I have an iPhone app where I have to modify the plist at runtime. I am successfully able to do it on simulator but when I run it on device it retrieves the data from the old plist and modification is not done. This is the code I am using for getting the path of the plist -
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:#"Customer.plist"];
NSFileManager *fileManager = [NSFileManager defaultManager];
if (![fileManager fileExistsAtPath: path])
{
path = [[NSBundle mainBundle] pathForResource:#"Customer" ofType:#"plist"];
}
NSMutableDictionary *mainDictionary;
mainDictionary = [[NSMutableDictionary alloc] initWithContentsOfFile: path];
To write a dictionary on plist file this line may work
[dicionaryToWrite writeToFile:path atomically: TRUE];

Adding Array to PLIST

I am trying to add and array to a Root array in my plist:
And is not working. Here's my code:
-(IBAction)addName:(id)sender{
NSArray *arrayValues = [NSArray arrayWithObjects: nameLabel.text, nameDate.text, nameValue.text, nil];
NSString *plistpath = [[NSBundle mainBundle] pathForResource:#"Names" ofType:#"plist"];
NSMutableArray *namesNew = [[NSMutableArray alloc] initWithContentsOfFile:plistpath];
[namesNew addObject:arrayValues];
[namesNew writeToFile:plistpath atomically:YES];
}
What am I doing wrong? Thanks!
You need to move the file to NSDocumentDirectory. Then edit the plist file.
For example:
Moving to NSDocumentDirectory:
-(NSDictionary *)copyBundleToDocuments
{
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [documentPaths objectAtIndex:0];
NSString *documentPlistPath = [documentsDirectory stringByAppendingPathComponent:#"Names.plist"];
NSString *bundlePath = [[NSBundle mainBundle] bundlePath];
NSString *bundlePlistPath = [bundlePath stringByAppendingPathComponent:#"Names.plist"];
//if file exists in the documents directory, get it
if([fileManager fileExistsAtPath:documentPlistPath])
{
NSMutableDictionary *documentDict = [NSMutableDictionary dictionaryWithContentsOfFile:documentPlistPath];
return documentDict;
}
//if file does not exist, create it from existing plist
else
{
NSError *error;
BOOL success = [fileManager copyItemAtPath:bundlePlistPath toPath:documentPlistPath error:&error];
if (success) {
NSMutableDictionary *documentDict = [NSMutableDictionary dictionaryWithContentsOfFile:documentPlistPath];
return documentDict;
}
return nil;
}
}
Then get the plist:
-(void)plistArray:(NSArray*)array
{
//get the documents directory:
NSArray *paths = NSSearchPathForDirectoriesInDomains
(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
//getting the plist file name:
NSString *plistName = [NSString stringWithFormat:#"%#/Names.plist",
documentsDirectory];
NSMutableArray *namesNew = [[NSMutableArray alloc] initWithContentsOfFile:plistName];
[namesNew addObject:arrayValues];
[namesNew writeToFile:plistName atomically:YES];
return nil;
}
The plist should be a dictionary as the base object instead of an array.
NSMutableDictionary *namesNew = [NSMutableDictionary dictionaryWithContentsOfFile:plistpath];
[namesNew setObject: arrayValues forKey: #"Root"];
[namesNew writeToFile:plistpath atomically:YES];
You cant write your plist to the bundle you need to use NSDocumentDirectory or NSCachesDirectory
Just copy your plist to bundle the overwrite it.
Note: learn the difference between NSCachesDirectory and NSDocumentDirectory
https://developer.apple.com/icloud/documentation/data-storage/
Copy your plist from bundle to documents(in below code caches), you need to this only one time if your plist in your bundle, I prefer using this code in appdelegate.m when - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *sourcePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"Names.plist"];
NSString *plistInDocuments=#"Names.plist";
NSString *dataPath = [documentsDirectory stringByAppendingPathComponent:plistInDocuments];
NSError *error = nil;
if (![[NSFileManager defaultManager] fileExistsAtPath:dataPath]){
[[NSFileManager defaultManager] copyItemAtPath:sourcePath
toPath:dataPath
error:&error];
}
NSLog(#"Error description-%# \n", [error localizedDescription]);
NSLog(#"Error reason-%#", [error localizedFailureReason]);
Get your file and overwrite it
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *plistInDocuments=#"Names.plist";
NSString *dataPath = [documentsDirectory stringByAppendingPathComponent:plistInDocuments];
//add object here
NSMutableArray *namesNew = [[NSMutableArray alloc] initWithContentsOfFile:dataPath];
[namesNew addObject:arrayValues];
NSError *error = nil;
if ([myFile writeToFile:dataPath options:NSDataWritingAtomic error:&error]) {
// file saved
} else {
// error writing file
NSLog(#"Unable to write plist to %#. Error: %#", dataPath, error);
}

writeToFile:atomically: not saving new plist data

I am using writeToFile:atomically: to update the value of a key in my plist by 1 every time the app is launched. I put this code in viewDidLoad, which reads the string value of the key, gets the numeric value of that string, increases it by 1, converts it back to a string, and writes that as the new string for that key, but when I read it again it seems to have not updated. I can't figure out what I'm doing wrong. I don't need a special framework for writeToFile:atomically:, do I?
Here is the code:
NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:#"DaysLaunched.plist"];
NSFileManager *fileManager = [NSFileManager defaultManager];
if (![fileManager fileExistsAtPath: path])
{
NSString *bundle = [[NSBundle mainBundle] pathForResource:#"DaysLaunched" ofType:#"plist"];
[fileManager copyItemAtPath:bundle toPath:path error:&error];
}
NSMutableDictionary *plistDict = [[NSMutableDictionary alloc] initWithContentsOfFile: path];
NSMutableDictionary *data1 = [[NSMutableDictionary alloc] initWithContentsOfFile: path];
NSString *currentNumberOfDays = [NSString stringWithFormat:#"%#",[plistDict objectForKey:#"numberOfDays"]];
NSLog(#"currentNumberOfDays = %#", currentNumberOfDays); //0
int days = [currentNumberOfDays intValue];
days ++;
currentNumberOfDays = [NSString stringWithFormat:#"%d", days];
[data1 setObject:[NSString stringWithFormat:#"numberOfDays"] forKey:currentNumberOfDays];
NSLog(#"currentNumberOfDays = %#", currentNumberOfDays); //1
[data1 writeToFile: path atomically:YES];
currentNumberOfDays = [NSString stringWithFormat:#"%#",[plistDict objectForKey:#"numberOfDays"]];
NSLog(#"currentNumberOfDays = %#", currentNumberOfDays); //0 ??????? writeToFile isn't working?
And here is a screenshot of "DaysLaunched.plist" in my 'Supporting Files' folder, (I've also verified that the plist file name is spelled exactly the same way I spelled it in my code, via Copy-Paste)
The original plist file is also in my 'Copy Bundle Resources' in targets.
Try
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:#"DaysLaunched.plist"];
NSFileManager *fileManager = [NSFileManager defaultManager];
if (![fileManager fileExistsAtPath: path])
{
NSString *bundle = [[NSBundle mainBundle] pathForResource:#"DaysLaunched"
ofType:#"plist"];
[fileManager copyItemAtPath:bundle toPath:path error:&error];
}
NSMutableDictionary *plistDict = [NSMutableDictionary dictionaryWithContentsOfFile:path];
NSInteger days = [plistDict[#"numberOfDays"] integerValue];
plistDict[#"numberOfDays"] = [#(++days) stringValue];
[plistDict writeToFile: path atomically:YES];
You have made a mistake while setting your data.
You should do:
[data1 setObject:currentNumberOfDays forKey:#"numberOfDays"];
instead of:
[data1 setObject:[NSString stringWithFormat:#"numberOfDays"] forKey:currentNumberOfDays];

How to retrieve an array of images from a plist file which is shown in an imageview?

How do I retrieve image data from plist and display to that data to an image view?
- (void)getImages {
// Look in Documents for an existing plist file
NSArray *paths = NSSearchPathForDirectoriesInDomains(
NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
myPlistPath = [documentsDirectory stringByAppendingPathComponent:
[NSString stringWithFormat: #"%#.plist", plistName] ];
[myPlistPath retain];
// If it's not there, copy it from the bundle
NSFileManager *fileManger = [NSFileManager defaultManager];
if ( ![fileManger fileExistsAtPath:myPlistPath] ) {
NSString *pathToSettingsInBundle = [[NSBundle mainBundle]
pathForResource:plistName ofType:#"plist"];
}
NSArray *paths = NSSearchPathForDirectoriesInDomains(
NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectoryPath = [paths objectAtIndex:0];
NSString *path = [documentsDirectoryPath
stringByAppendingPathComponent:#"myApp.plist"];
NSMutableDictionary *plist = [NSDictionary dictionaryWithContentsOfFile: path];
NSArray *imageArray = [plist objectForKey:#"imageArray"];
for (NSString *imageString in imageArray) {
DLog(#"Image Name: %#", imageString);
}
}
Get plist code from www.iphoneexamples.com

unable to save plist ios

I m able to save the plist file in Simulator but I m not able to save the Plist file in the device. Any suggestion.
I m using
NSString* dictPath = [[NSBundle mainBundle] pathForResource:#"Dictionary" ofType:#"plist"];
NSDictionary * dict = [[NSDictionary alloc] initWithContentsOfFile:dictPath];
to read the files
and
[dict writeToFile:dictPath atomically: YES];
to write to file.
You can not write in to main bundle. You only can read from main bundle. If you want to write an file you need to place it in to the documents directory of your app.
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"%#.plist",plistName]];
If you need the plist from the main bundle you can copy it first in to the documents directory then modify it. It is advised to have a check to ensure it is copied only once.
NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"%#.plist",plistName]];
NSFileManager *fileManager = [NSFileManager defaultManager];
if (![fileManager fileExistsAtPath: path]){
NSLog(#"File don't exists at path %#", path);
NSString *plistPathBundle = [[NSBundle mainBundle] pathForResource:plistName ofType:#"plist"];
[fileManager copyItemAtPath:plistPathBundle toPath: path error:&error];
}else{
NSLog(#"File exists at path:%#", path);
}
Generally you would store these in ~/Documents or in ~/Library depending on the file. The question What is the documents directory (NSDocumentDirectory)? includes the documentation links and sample code you need to understand this.
You need to save the plist in Documents directory
to write
NSString *mainBundlePath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *dictPath = [mainBundlePath stringByAppendingPathComponent:#"Dictionary"];
NSDictionary * dict = ...; //Construct your dictionary
[dict writeToFile:dictPath atomically: YES];
to read
NSDictionary * dict = [[NSDictionary alloc] initWithContentsOfFile:dictPath];

Resources