how to add data string in .plist file? - ios

I want put data string (for example loop for that create many url) in plist file on xcode.
this is my code (loop)
int count = 5;
NSString *a;
NSMutableArray *b = [[NSMutableArray alloc] initWithCapacity:count];
for (int i=1; i<= count; i++ ) {
a = [NSString stringWithFormat:#"http://192.168.1.114:81/book.php?page=%d",i];
[b addObject:a];
}
now I want save any page from top code in one row of .plist file but I dont know what can I do?
you can guidance me?

I'm not sure quite what you're shooting for, but if you're trying to extract the HTML from those URL strings, you could probably do something like:
// build path for filename
NSString *docsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
NSString *filename = [docsPath stringByAppendingPathComponent:#"test.plist"];
// create array of html results
NSMutableArray *htmlResults = [NSMutableArray array];
for (NSString *urlString in b)
{
// get the html for this URL
NSString *html = [NSString stringWithContentsOfURL:[NSURL URLWithString:urlString] encoding:NSUTF8StringEncoding error:nil];
// add the html to our array (or zero length string if it failed)
if (html)
[htmlResults addObject:html];
else
[htmlResults addObject:#""];
}
// save the html results to plist
[htmlResults writeToFile:filename atomically:YES];
A couple of thoughts:
Depending upon how many pages there are, I'm not sure if I'm crazy about loading all of the pages into a plist. I'd either
use some persistent storage like Core Data so I didn't have to hold all of the pages in memory, or
do some lazy loading of the HTML (load it as I need it))
Also, if I was going to load all of the pages, given that it could take a little time, I might have a progress view that I update with my progress, so the user wouldn't be looking at a frozen screen while the download was in progress.
If you just want to retrieve a single html file, then storing that in a plist might not make sense. I'd just write the html to a file (a HTML file, not a plist).
I wouldn't generally like to load the html in the main queue. I'd do a dispatch_async to perform this in a background queue. But I hesitate to go to far until you clarify precisely what you're looking for.
But hopefully this points you in the right direction, showing you how to retrieve data from the web pages.
If you wanted to save the individual html files to some local file (say X.html where X is the zero-based index number), you could do something like:
// identify the documents folder
NSString *docsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
// save the html results to local files
[b enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
NSString *html = [NSString stringWithContentsOfURL:[NSURL URLWithString:obj] encoding:NSUTF8StringEncoding error:nil];
if (html)
{
NSString *filename = [docsPath stringByAppendingPathComponent:[NSString stringWithFormat:#"%d.html", idx]];
[html writeToFile:filename atomically:YES encoding:NSUTF8StringEncoding error:nil];
}
}];

Try [b writeToFile:#"myFile.plist" atomically:YES];, but make sure all the data in your array are representable in a plist.

Related

How to upload .xml file in IOS app using Objective-C?

In my IOS app I have one abc.xml file through which I get data and display it on screen (I have already done with that, no issue for doing this), my problem is,on button click I want to upload any .xml file to my app (I have some .xml file in my ipad) and want to replace that .xml file with abc.xml file, (then i will fetch data through that newly uploaded file)
It is just like "choose file" option in web
can we do this in iOS app using Objective-C?
iOS uses .plist setting configuration files. I don't know how well this would work, but you could try something a little like this...
NSMutableDictionary *abcDict = [NSMutableDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"abc" fileType:#"xml"]];
NSString *someString = (NSString*)[abcDict valueForKey:#"someString"];
NSNumber *someNumber = (NSNumber*)[abcDict valueForKey:#"someNumber"];
NSDictionary *someDictionary = (NSDictionary*)[abcDict valueForKey:#"someDict"];
NSArray *someArray = (NSArray*)[abcDict valueForKey:#"someArray"];
BOOL *someBoolean = [((NSNumber*)[abcDict valueForKey:#"someBool"]) booleanValue]
Just change your code depending on your data type. BOOL is a bit weird, but everything else is written just like that. Use the right key names, and if XML doesn't work, try plugging a .plist file into your app!
If i understood what you want, this should make the trick.
NSURL *url = [NSURL URLWithString:linkURL];
NSData *urlData = [NSData dataWithContentsOfURL:url];
if ( urlData )
{
BOOL success = [db writeToFile:#"locationOfTheFile" atomically:YES];
if (success) {
//all went well
}else{
//error
}
}
edit:
if the file is at the root of your app, you can get the path with this.
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex:0];
BOOL success = [db writeToFile:[documentsDir stringByAppendingPathComponent:#"fileName"];

Loading files from disk to NSMutableArray removes NSMutableArray from memory

I'm loading a file to a NSMutableArray. I'm doing it like this:
if(!self.dataArray){
self.dataArray = [[NSMutableArray alloc] init];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES);
NSString *arrayPath = [[paths objectAtIndex:0]
stringByAppendingPathComponent:#"array.out"];
self.dataArray = [NSMutableArray arrayWithContentsOfFile:arrayPath];
}
The array that is loaded into the file consists of multiple NSDictionaries.
However, this somehow deallocates the array in the memory because when I log dataArray after doing this, it logs nil. How come?
Update
I've figured out that [NSMutableArray arrayWithContentsOfFile:arrayPath] is logging nil because the code in which I'm uploading the content to the file, doesn't create the file:
// write data to disk
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *arrayPath = [[paths objectAtIndex:0]stringByAppendingPathComponent:#"array.out"];
[self.dataArray writeToFile:arrayPath atomically:YES];
NSLog(#"uploaded file: %#", arrayPath); // logs an arrayPath, but one that doesn't exists.
Check the following,
Check the dataArray is a weak property ? If so, change to strong.
Check the file exists at path, using
[[NSFileManager defaultManager] fileExistsAtPath:arrayPath];
Verify the file have expected content, by logging it.
Confirm the File content is organized as a property list (plist). Verify it in plist editor/Xcode.
If you dynamically creating it, check the path you are writing to.
Confirm the method of writing NSArray to plist. Use
[array writeToFile:path atomically:YES];
Note:
If you are dynamically creating the file and you are testing on Simulator; you can
find the file by logging file path and following it on Finder.
Property List Reference
Apple documentation
Per Apple documentation, the array returns nil if the file can’t be opened or if the contents of the file can’t be parsed into an array.
Did you use the [writeToFile:atomically:] method to write the array to a file?
Also, make sure that the filePath string matches exactly on both write and read ends. I've wasted a lot of time trying to hunt down a bug when it turned out I had misspelled the name of the file or used the wrong file extension.
Another possibility: have you confirmed that this code is being executed? Sometimes I've had to change (!self.someProperty) to (self.someProperty != nil) in my if condition to get code like this to run.
Peter Segerblom and wildBillMunson are right: the array returns nil if the file can't be opened or if its content can't be parsed into an array.
You said "array.out" is an array of NSDictionaries. Whenever I have that set of data, I use the plist type of file and read it this way:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
NSString *directory = [paths objectAtIndex:0];
NSString *fullPath = [directory stringByAppendingPathComponent:#"data.plist"];
NSString *errorDesc = nil;
NSPropertyListFormat format;
NSData *plistXML = [[NSFileManager defaultManager] contentsAtPath:fullPath];
NSArray *data = (NSArray *)[NSPropertyListSerialization propertyListFromData:plistXML mutabilityOption:NSPropertyListMutableContainersAndLeaves format:&format errorDescription:&errorDesc];
Be sure to check if fullPath is not returning nil.
Hope this helps!

local memory as well as webservice

even after so many research i haven't found a solution for this question. I am currently working on a app which uses 3 view controllers for Registration with a log out button. the last view controller has the Register button which saves all the details of registration in a web service. But if the user has filled the two view forms and logs out. The two view filled forms field should be saved in the local memory and wen the user logs it again the pre filled forms should load the fields saved in internal memory just to continue the Registration for webservice. Any idea how to implement this sort of functionality
As others have said, NSUserDefaults will suffice for what you need.
NSUserDefaults *registrationInfo = [NSUserDefaults standardUserDefaults];
Guessing you have text fields with the info you need. So pull out the text and save to a key like this.
[registrationInfo setObject:self.someTextFieldName.text forKey#"firstTextField"];
After repeating this for every text field(use different key names though), call this [registrationInfo synchronize];
To pull the data out, you open the defaults again just like the first line. And to retrieve a specific key: NSString *firstTextField = [registrationInfo objectForKey:#"firstTextField"];
To make this easier, you can also put all of your strings in an array or dictionary, and then add that as an object in your defaults. Then you only have to set/get once.
If you have large amount of data to save use CoreData else you NSUserDefaults to save it.
I suggest you to use PLIST There are mainly three steps to do this.
1) Generate .plist file.
NSError *error1;
BOOL resourcesAlreadyInDocumentsDirectory;
BOOL copied1;
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath1 = [documentsDirectory stringByAppendingString:#"/epub.plist"];
resourcesAlreadyInDocumentsDirectory = [fileManager fileExistsAtPath:filePath1];
if(resourcesAlreadyInDocumentsDirectory == YES) {
} else {
NSString *path1 = [[[NSBundle mainBundle] resourcePath] stringByAppendingFormat:#"/epub.plist"];
copied1 = [fileManager copyItemAtPath:path1 toPath:filePath1 error:&error1];
if (!copied1) {
NSAssert1(0, #"Failed to copy epub.plist. Error %#", [error1 localizedDescription]);
}
}
2) Try to read(open) it.
NSMutableDictionary* dict = [[NSMutableDictionary alloc] initWithContentsOfFile:filePath1];
3) write data to plist file.
[dict setObject:[NSNumber numberWithInt:value] forKey:#"value"];
[dict writeToFile:path atomically:YES];
This is a simple way to use it. I suggest to use .plist file in place of NSUserDefaults.

Convert a plist file to text

This is not a question, but a solution i was puzzled with.
The solution might also help other guys visiting SO having the same problem.
In a iOS game I made I used the plist format to store the level game data.
Now I am into making a level editor for this game, with the purpose to share the game data with close friends or the rest off the world.
It took me a couple of hours to find a solution and i like to share it with you now.
The solution was so simple that i have overlooked a possible solution.
Here it is,
Just open the plist file as a text file and you are good to go, So simple!
See example below, hope this will help some one else.
-(NSString *) levelFilePath{
NSArray *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentDirectory = [NSString stringWithFormat:#"%#%#%#", [path objectAtIndex:0],mm_HomeDirectory,mm_SubDirectory];
NSString *levelName = [levelnameStr stringByAppendingString:#".plist"];
return [documentDirectory stringByAppendingPathComponent:levelName];
NSLog(#"Level-Document %#",levelName);
}
-(void) ReadLevelFileAsText{
NSString *LevfilePath = [self levelFilePath];
NSString *textFile;
if ([[NSFileManager defaultManager] fileExistsAtPath:LevfilePath]) {
textFile = [NSString stringWithContentsOfFile:LevfilePath
encoding:NSUTF8StringEncoding
error:NULL];
} else {
NSLog(#"filePath does not exists: %#",LevfilePath);
}
NSLog(#"Content of File: %#", textFile);
}
Greetings,
J Sneek

how to store an image path in a plist?

I know this is probably a silly question but I'm storing most of my game data in a plist - with that I'd like to include references to images used within my game - same hierarchal level as 'supporting files'. I have different types of images stored in 3 separate folders. One folder for example is called imageclue. How could I store the path in my plist, I'm stuck because I can't just store the path in my plist as string - filename.jpg. I've tried getting the path of the file but when I log it out it .
Sorry if I'm not explaining well and thank you in advance for any help :)
EDIT**
I have a plist file added to my program I don't want to programatically add to it as the images are constants - the screenshots below show a tutorial instead of the filename.jpg (because that won't work seen as my images are stored in a file) I wondered what path name do I use as a string.
The image is from a tutorial off of appcoda.com - where it says thumbnails are the image path files. If you look at where the images are stored on the left - they are stored with the program files. My images are in a folder in there so I'm confused as to what to enter in my plist for the image file.
Hope this clears up what I meant, sorry :)
Store three variables in .h file
#interface YourViewController : UIViewController
{
NSString *folder1;
NSString *folder2;
NSString *folder3;
}
in viewdidload:
-(void) viewdidLoad
{
//get the documents directory:
NSArray *paths = NSSearchPathForDirectoriesInDomains
(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
//getting the folder name:
folder1 = [NSString stringWithFormat:#"%#/imageclue",
documentsDirectory];
folder2 = [NSString stringWithFormat:#"%#/folder2",
documentsDirectory];
folder3 = [NSString stringWithFormat:#"%#/folder3",
documentsDirectory];
}
-(NSArray*) getPlistFromFolder:(NSString*)folder imageName:(NSString*)image
{
NSString *imageTitle = [NSString stringWithFormat:#"%#/image",
folder];
NSArray *data = [[NSArray alloc] initWithContentsOfFile:plistName];
return data;
}
So in the plist file, just store the image name.
Hope this helps...
Do it like this,
NSDictionary *imagePaths = #{#"image 1": [NSHomeDirectory() stringByAppendingPathComponent:#"image 1"]};
[self writeToPlist:imagePaths];
- (void)writeToPlist:imagePaths:(id)plist{
NSError *error;
NSData *data = [NSPropertyListSerialization dataWithPropertyList:plist format:kCFPropertyListXMLFormat_v1_0 options:0 error:&error];
if(error){
NSLog(#"Could not write to file");
return;
}
[data writeToFile:[self plistPath] atomically:YES];
}
Like wise loading is simple as this;
[self loadImagePathForImageNamed:#"image 1"];
- (NSString*)loadImagePathForImageNamed:(NSString*)imageName{
}
- (NSString*)loadImagePathForImageNamed:(NSString*)imageName{
NSData *data = [NSData dataWithContentsOfFile:[self plistPath]];
NSString *error;
NSPropertyListFormat format;
NSDictionary *dictionary = [NSPropertyListSerialization propertyListFromData:data mutabilityOption:NSPropertyListImmutable format:&format errorDescription:&error];
if(error){
NSLog(#"Could not open plist %#", error);
return nil;
}
return dictionary[imageName];
}
You may have to handle the error when the file is not there by creating a new one, otherwise this should work.
You are storing path right way, just need to store filename of image with extension in plist when your images are in your Application Bundle, for more reference you can define key name Instead "item1", "item2" in your plist.
Now coming to actual Question, how to access image from plist
Step 1 : Read your recipes.plist from Application Bundle
NSString *bundlePath = [[NSBundle mainBundle] pathForResource:#"recipes" ofType:#"plist"];
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:bundlePath];
Step 2 : Now Get Image/Thumbnails name out of it, which you want to load
Step 3 : Define following Function in your Controller, which returns image from name
- (UIImage *)getImageWithName:(NSString *)imageFileName
{
NSString *ext = [imageFileName pathExtension];
NSString *imagePath = [[NSBundle mainBundle] pathForResource:[imageFileName stringByDeletingPathExtension] ofType:ext];
return [UIImage imageWithContentsOfFile:imagePath];
}
HOW TO USE
Suppose you want to load Image with key "Item2" then write following code
NSString *imageFileName = [[dict objectForKey:#"Thumbnail"] valueForKey:#"Item2"];
UIImage *item2Image = [self getImageWithName:imageFileName];
For "Item6"
NSString *imageFileName1 = [[dict objectForKey:#"Thumbnail"] valueForKey:#"Item6"];
UIImage *item6Image = [self getImageWithName:imageFileName1];

Resources