How to save apps data Xcode - objective-c

I have been searching for many days on how to save my apps data. I found some stuff but it was very complicated and badly explained. I need that when I completely close my apps all the data I entered in the text field are still there when I open my apps again. I tried a tutorial but this only let me save about 8 textfields and I need to save thousands I am starting Objective-C and Xcode so if somebody want to give me an answer please make it very precise.

Alright, what I'd suggest would be putting all the data from your text fields into an array and saving that to a file, then loading it when you re-open the app.
The first thing you need is a save file. This function will create one for you.
-(NSString*) saveFilePath{
NSString* path = [NSString stringWithFormat:#"%#%#",
[[NSBundle mainBundle] resourcePath],
#"myfilename.plist"];
return path;}
Now that that's done you need to create your saving array. Hopefully you have your thousands of textfields already fitted into an array of some sort. If not, this will be a painful process regardless of how you tackle it. But anyway... (Here, labelArray will be the array of all your text fields/labels/etc.)
NSMutableArray* myArray = [[NSMutableArray alloc]init];
int i = 0;
while(i < labelArray.count){
[myArray addObject: [labelArray objectAtIndex: i].text];
i ++;
}
[myArray writeToFile:[self saveFilePath] atomically:YES];
[myArray release];
And the loading code would be something along the lines of
NSMutableArray* myArray = [[NSMutableArray arrayWithContentsOfFile:[self saveFilePath]]retain];
Then you'd simply load the data back into your array of text fields.
Hope this helps.

It sounds like your application architecture may be unsound if you are planning on saving thousands of text fields' data in the fraction of a second you get while your app is closing. It would probably be better to save these as the user enters the data instead of waiting to save all the data at once.

To get the path you are going to write ( or read from! ) to, you do the following:
NSString *writableDBPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:#"MyFile.extension"];
And then use a method like "writeToFile:automically:" of NSString or NSDictionary etc. to write to the path.

Related

How to append NSMutable array to existing file

I am newbie in coding and trying to learn objective c, I tried searching my question on internet and stack overflow but not getting proper solution.
I am trying to save some data into array and after that I want to save that subarray into main array and after that main array into file.
below code is working properly for me but the data is not appending in file .
self.details = [[NSMutableArray alloc]init];
[self.details insertObject:self.firstName atIndex:0];
[self.details insertObject:self.lastName atIndex:1];
[self.details insertObject:[NSNumber numberWithLong:self.depositAmount] atIndex:2];
[self.details insertObject:[NSNumber numberWithInt:self.accountNumber] atIndex:3];
for (int i=0; i<self.details.count;i++) {
NSLog(#"%#",self.details[i]);
}
self.mainarray = [[NSMutableArray alloc]init];
[self.mainarray addObjectsFromArray:self.details];
NSString *path = #"/Users/testapp/data";
[self.mainarray writeToFile:path atomically:YES];
enter code here
for (int i=0; i<self.mainarray.count;i++) {
NSLog(#"%#",self.mainarray[i]);
}
writeToFile:path is actually deprecated (as you can see here https://developer.apple.com/documentation/foundation/nsdata/1408033-writetofile?language=objc)
In general to do this it depends on what you mean by append? If its literally just dump the data to end ( not necessarily making the file a legit array) then you can open a file in append mode, which you could use an output stream for (https://developer.apple.com/documentation/foundation/nsoutputstream/1564841-outputstreamtofileatpath?language=objc)
However, I am figuring that you want to append the new array objects to the file such that the file is structred. To do that you would need to read in the file and somehow decode that into an array. You would need a way to represent your data such as with JSON (https://developer.apple.com/documentation/foundation/nsjsonserialization) so that you can save the array into the file and vice versa.
But then you would need to read the file, and then add your new structred data so the file would still make sense. There are lots of ways to handle files (NSCoding, C files, etc..) but a simple way would to use NSOutputStream(https://developer.apple.com/documentation/foundation/nsoutputstream) and NSInputStream (https://developer.apple.com/documentation/foundation/nsinputstream?language=objc)

writeToFile fails when writing to desktop

I have this code snippet below. The purpose is to write the contents of an array to a plist file. When I run this I don´t get any errors and everything seems to be fine. The problem is that the file doesn´t appear on the desktop. I used writeToFile before in other projects without any problems. What is wrong with it? Greetings from Switzerland, Ronald Hofmann.
- (IBAction) doActionPlist: (NSButton *) sender
{
NSString *fileExt = #".plist";
NSArray *myResultArray = [NSArray arrayWithObjects:
#"Product Number Unlimited Desktop:",
#"4DDP120-UUS001-ANLKR-17C6B",
#"4DDP130-UUS001-ANQEI-1BC12",
#"4USE120-UUS001-80BY1-1EAB0",
#"4USE130-UUS001-6NTUE-11D64",
#"qA0iHnw4EIgOALgAAAQCmUtj",
#"qA0iHnw6EIgAALgAAPUBhByg",
#"4DDP11U00USN001",
#"4DDP13U12USN001",
#"4UCL00U00USN001",
#"4UCL00U00USN010",
#"4UCL11U00USN001",
#"4UCL11U00USN010",
#"4UCL12U11USN001",
#"4UCL12U11USN010",
#"4UCL13U12USN001",
#"4UCL13U12USN010",
#"4USE12U11USN002",
#"4USE13U12USN002",
#"4UWE13U12USN999",
nil];
NSString *thePath = [NSString stringWithFormat:#"/Users/ronny/Desktop/Testfile%#",fileExt] ;
[myResultArray writeToFile:thePath atomically:YES] ;
}
Unfortunately, it can be difficult to debug this call because it only returns YES or NO with no further information about why it succeeded or failed. The fact that it's not throwing any exceptions doesn't necessarily mean that nothing is going wrong; it just means that NSArray can't be bothered to tell you about it.
If you're really at wit's end, you might try converting your NSArray to NSData using NSPropertyListSerialization and then using writeToFile:options:error instead. If you do this, post the error message and someone should be able to offer better debugging advice.

Quickest way to load word-list dictionary into an array?

I am working on a word-based game, and I need to load my 180,000 word dictionary (1.9MB) into an array so the solving algorithm can work with it. The dictionary is simply one word per line, like this:
a
ab
abs
absolutely
etc
...
Right now I am using the following code to load that file into the array:
NSString *txtPath = [[NSBundle mainBundle] pathForResource:#"dict" ofType:#"txt"];
NSString *stringFromFile = [[NSString alloc]
initWithContentsOfFile:txtPath
encoding:NSUTF8StringEncoding
error:&error ];
for (NSString *word in [stringFromFile componentsSeparatedByString:#"\r\n"]) {
[wordsArray addObject:word];
}
This takes about 3-4 seconds on an iPhone 4. Probably even slower on older iOS devices. Is there a faster way to do this?
You can easily do this in the background, off the main thread using Grand Central Dispatch, or GCD.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0),^(void){
NSString *txtPath = [[NSBundle mainBundle] pathForResource:#"dict" ofType:#"txt"];
NSString *stringFromFile = [[NSString alloc]
initWithContentsOfFile:txtPath
encoding:NSUTF8StringEncoding
error:&error ];
for (NSString *word in [stringFromFile componentsSeparatedByString:#"\r\n"]) {
[wordsArray addObject:word];
}
});
I wrote the enclosing dispatch code from memory, but it's close (if not correct) and I think you get the idea.
EDIT: You can execute this code on the main thread, but what happens is a non-main-thread dispatch queue is where your code executes, thereby NOT blocking the UI.
You can improve the performance of your code here a little bit by replacing the for loop with just this:
[wordsArray setArray:[stringFromFile componentsSeparatedByString:#"\r\n"]];
There should be no need to iterate over the result from -componentsSeparatedByString: (an array) just to put them into another array. With 180K words, that should be a significant time saving right there.
It would probably be faster to pre-load the word list into an SQLite database, then use SQL queries to search using whatever patterns you have. You can take advantages of indexes to make it even faster.

Get EXC_BAD_ACCESS when tableview get data from URL?

My tableview is get XML data from URL,First I declare a NSMutableArray *dataArray;
and this is how I get the data in my TableviewSample.m
- (void)getDataFromURL{
NSString *theURLAsString = [NSString stringWithFormat:GetAllData];//<-EXE_BAD_ACCESS HERE
//#define stringWithFormat:GetAllData #"http://192.168.10.28/req_alldata.php"
NSURL *theURL = [NSURL URLWithString:theURLAsString];
self.dataArray = [NSMutableArray arrayWithContentsOfURL:theURL];
}
Then I just get the elements form this array to my tableview ...
But here I have to say one more thing , actually it won't crash before I add another view...
I add a bar button to go to a webView , this webView is use to load a IP Cam stream video
When I back to the tableview , It will appear EXC_BAD_ACCESS
This is odd things I cannot to solve it...because both side code are all looks normal
If I remove this webview ,no matter how I run the program ,it won't crash...
And sometimes I leave the webView I will receive memory warning :level 2
But just only one time.
or do I use a wrong way to open an ip cam stream ???
Thanks for all reply : )
OK,here is the code different I use in my webview class
This is first version I use
- (void)viewDidAppear:(BOOL)animated{
NSString *directGoToWebCam = [NSString stringWithFormat:GetAllData];
self.IPCamWebView=[[[UIWebView alloc] initWithFrame:CGRectMake(0,0,640,960)] autorelease];
[self.IPCamWebView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:directGoToWebCam]]];
[self.view addSubview:self.IPCamWebView];
}
Where does GetAllData come from? It looks like that isn't pointing to anything. More code, the exact error, and a more careful description will go a long way here.
It probably has something to do with the use of #define which does not say anything about the type of the object you are using.
If you want to define a constant string in your code the best would be to use something like this:
static NSString *GetAllData = #"192.168.10.28/req_alldata.php";
Where you need to use the string you can simply write:
NSString *GoToWebCam = [NSString stringWithString:GetAllData];

Error while attempting to output data onto console in xcode

I am trying to output general data (source code) from a website, but it just sits there. Can't figure out if its the interface or the code. Would someone double-check for me?
#import "Lockerz_RedemptionViewController.h"
#implementation Lockerz_RedemptionViewController
-(IBAction)start: (id) sender {
while (1) {
NSMutableData *mydata = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:#"http://ptzplace.lockerz.com/"]];
NSString *output = [[NSString alloc] initWithData:mydata encoding:NSASCIIStringEncoding];
NSLog(output);
}
}
The reason your NSLog doesn't work is it should use format strings.
Replace:
NSLog(output);
With:
NSLog(#"%#",output);
For more info see http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/Strings/Articles/FormatStrings.html
Why the while(1)? Are you intentionally trying to set up an infinite loop? You should just run this once, or maybe set up a periodic timer to reload it every few seconds, but certainly don't use an infinite loop for that... also it's been a while since I did anything with Cocoa networking, but you might want to look into NSURLRequest. You also may want to try NSData's dataWithContentsOfURL:options:error: and check the error parameter to better see what might be going wrong. Hope this helps you out.