How can I write data from an NSDictionary to a SQLite database? [duplicate] - iphone

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
separating keys and objects from NSMutable dictionary and use the values in insert command of sqlite
I have an NSDictionary containing parsed JSON data. How can I push these data to a database so that I can extract them from database for further use?
I am using SBJSON for parsing.

If your design requirements specify sqlite, then I would recommend using Gus Mueller's FMDB so that you do not have to work directly with raw sqlite.
NSString $title = [jsonDictionary objectForKey:#"title"];
// other keys, values, etc...
NSString $query = [NSString stringWithFormat:#"INSERT INTO myTable t (t.some_column) VALUES ('%#'),$title];
FMResultSet *results = [_db executeQuery:$query];
That said, as Chris said above, Core Data is often a better solution than sqlite. Brent Simmons (NetNewsWire developer) has a series of posts about this subject, like this one.
The exception to the "Core Data is better than sqlite" mantra for me is the situation where you want to provide initial data but do not want to perform an initial import into Core Data.

Use core data for this matter. Here is a good tutorial to start with:
http://mobile.tutsplus.com/tutorials/iphone/iphone-core-data/

Following code goes to create the dynamic plist file and that file stores into the bundle and that data can be access and the insert the data into the .plist file.
NSString *strPathToAudioCache=[NSString stringWithFormat:#"%#/%#",
[(NSArray*)NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0],
#"data.plist"];
NSMutableDictionary *dOfAudios=[NSMutableDictionary dictionaryWithContentsOfFile:strPathToAudioCache];
NSLog([dOfAudios allKeys].count>0?#"Value is exist":#"Value is not exist");
if([dOfAudios allKeys].count>0) {
[dOfAudios setValue:#"Key_for_value" forKey:#"value_for_key"];
} else {
dOfAudios=[NSMutableDictionary dictionary];
[dOfAudios setValue:#"Key_for_value" forKey:#"value_for_key"];
}
[dOfAudios writeToFile:strPathToAudioCache atomically:YES];

Related

iOS - plist file, nsuserdefaults or text data file

I am working on a mobile app which needs a lot of data. Simply put, the data will be for multiple languages and consist of all the words possible for that language. The app would start with only the English language and a lot of it's words. Then the user can choose to download more languages and their data.
I am trying to figure out the best way to read/save/update this data. Should I create a plist file with English data to start with and just keep adding more data as user downloads new languages? Or should I save all the data in nsuserdefaults? Or, should I just include a text file with all the data and parse it on the fly?
Suggestions?
ps: i understand that as this is a mobile app, file space and parsing time have to be considered
Please read my answer here: https://stackoverflow.com/a/7215501/832065
As said in that answer, all NSUserDefaults are stored together in one plist.
A plist and NSUserDefaults are basically the same, however NSUserDefaults should ONLY be used for saving preferences and not a big amount of data. So don't use NSUserDefaults!
I would consider saving this in a plist (NSDictionary). Like this you can have all data sorted in that file. Simply set the "words" (NSString I assume) as object, and the language as key.
NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithContentsOfFile:filePath];
[dict setObject:words forKey:language];
[dict writeToFile:filePath atomically:YES];
same for reading:
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:filePath];
NSString *words = [dict objectForKey:language];
EDIT:
If each word is assigned to a number (you can just use NSArray) it doesn't differ much:
NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithContentsOfFile:filePath];
NSArray *words = [NSArray arrayWithObjects:allTheWords,nil];
[dict setObject:words forKey:language];
[dict writeToFile:filePath atomically:YES];
same for reading:
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:filePath];
NSArray *words = [dict objectForKey:language];
NSString *word = [words objectAtIndex:numberAssignedToWord];
I hope this helps! :)
I would recommend using either an SQL database directly or Core Data. If you have a lot of data, you don't want to load that data completely into memory all the time. It is also easier to handle updates, changes or additions of data.
But your question is so general, and doesn't tell anything on what you actually want to do with the data, how large the data is in KByte or MByte, it is hard to give any good answer.
Writing a lot of data into a text file, user defaults, plist or something similar, doesn't seem the right choice. Using Core Data would be the default way to do such things on iOS.
I thing the easiest way would be to handle the data in a NSMutableArray and store it within the application using NSUserDefaults.
You can handle your data within a NSMutableArray, like so:
NSMutableArray *yourDataStuff = [[NSMutableArray alloc] init];
[yourDataStuff addObject:#"Your data 1"];
[yourDataStuff addObject:#"Your data 2"];
[yourDataStuff addObject:#"Your data 3, etc.."];
Then you can store it using NSUserDefaults, like so:
[[NSUserDefaults standardUserDefaults] setObject:yourDataStuff forKey:#"myData"];
And read your data, like so:
yourDataStuff = [[NSUserDefaults standardUserDefaults] objectForKey:#"myData"];
I think you cannot save large data in the NSUserDefault , and you maybe can not do IO with plist , i had done this , when you read or save , you must read in the whole .plist , and you may reveive memory warning , or crash. you can use C (fread,fwrite) write the data in a .txt , and you may read and write with data stream.

Saving a NSArray that contains a NSDictionary that contains an NSArray of UIImages (and others)

I've seen various questions here pertaining to saving NSArrays/NSDictionaries, but I'm a bit confused about what to do when some of the subelements are UIImages.
To give a little context, the app is essentially a blog-type app. When the user is composing a new entry, their post can contain the following:
Up to 3 images from their photo album
Text
Location
In essence, I'm trying to implement a "Save Draft" functionality to the app if the user decides to temporarily cancel their blog post. When the user cancels the blog post, they will be asked in a UIActionSheet if they would like to save their draft. When the user wants to post again, they can begin from where they left off with their saved draft.
At this point, I would need to save these following objects:
1) NSArray of selected photos
---> contains NSDictionaries (up to 3)
--------> UIImage (large sized version)
--------> UIImage (thumbnail sized version)
2) NSDictionary of NSValues (just some view x,y position data)
3) Text -- NSString data of the blog text they have written
4) Location text -- NString data of their current location
Given that I need to save the above 1~4 data in order to make the "Save Draft" functinality, what is the best way to do this? Should I make a special class to hold all of this data? Also, do I first need to make the UIImages into NSData before I can save them to disk?
Thank you!!
Yes a class/model like structure make more sense and easier to handle as well.
Something like-
Interface Blogdata
NSArray *selectedPhoto;
NSDictionary *positionValues;
NSString *blogText;
NSString *locationText;
and then you can make one more model for photo data;
Interface Photodata
NSDictionary *photo;
UIImage *largeImage;
UIImage *thumbImage;
All of the properties that you mentioned seem like they would belong in a Blog class. Are they already grouped together? A Blog object could capture the state of the draft with variables (properties) of the object being the four things you mentioned. You can then save the Blog object as NSData and read it when the user wants the draft again.
The advantage of this is that you only have to worry about saving one object, instead of having to think about saving four each time (and retrieving them).
The easiest way would be to save the images to the apps documents folder and save the NSArray of filenames and other data that can be represented as text in a drafts.plist.
filenameStr = [NSString stringWithFormat:#"image1.png"];
fileManager = [NSFileManager defaultManager];
paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
documentsDirectory = [paths objectAtIndex:0];
imagePath = [documentsDirectory stringByAppendingString:#"/"];
imagePath = [imagePath stringByAppendingString:filenameStr];
NSData *imageData = UIImagePNGRepresentation(myImage);
[imageData writeToFile:imagePath atomically:YES];

How to cache or store parsed xml file?

My app parses an xml file from my server, but I want to store parsed xml file and next start of my app, controller initially should load stored xml file, then controller should parse it again to check that there may be an update I did on xml file, if there is, new elements parsed should also be stored again.
I am referring to those app such as magazines, newspaper apps. When you open those kind of apps, it loads stored data that was downloaded previous session. Yet, after it loads, it starts to update the data, and it stores new update again.
Where do I start? What do you guys suggest?
Thanks in advance...
You can use CoreData or SQLite (use Objective-C wrapper FMDB https://github.com/ccgus/fmdb) to persist your XML. Then update the database everytime you see a unique id. Depends on how your XML data is.
It's actually quite easy to store to the documents directory. For example:
NSData *data; //this is your xml file
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docs = [paths objectAtIndex:0];
NSString *filename = [NSString stringWithFormat:#"test.xml"];
NSString *path = [docs stringByAppendingPathComponent:filename];
[data writeToFile:path atomically:YES];
Then to retrieve it later, you can get the path like above, but retrieve the file instead of writing it:
NSData *data = [NSData dataWithContentsOfFile:path];
either CoreData or SQLite can do the trick

Basics Introduction To Using CHCSVParser

I'm implementing CHCSVParser into my iPhone app (thanks Dave!) however I'm really confused on how to use it. I've read the read-me and searched some questions on SO but still not 100% sure what to do.
I have a .CSV file with maybe 5000 rows of data and 3-4 columns.
I want this data to in return, load my UITableView along with its corresponding detailViewController.
So I'm assuming I need to somehow implement the API's array method but can anyone help get me started?
I'm glad you like it :)
Basically, CHCSVParser only parses CSV files. You give it a path to a CSV file, and it'll give you back a whole bunch of NSStrings. What you do beyond that point is entirely up to you.
So let's say you've included a CSV file in your iOS app called "Data.csv". Here's how you'd use CHCSVParser to parse it:
NSString *path = [[NSBundle mainBundle] pathForResource:#"Data" ofType:#"csv"];
NSError *error = nil;
NSArray *rows = [NSArray arrayWithContentsOfCSVFile:path encoding:NSUTF8StringEncoding error:&error];
if (rows == nil) {
//something went wrong; log the error and exit
NSLog(#"error parsing file: %#", error);
return;
}
At this point, rows is an array. Each element in rows is itself an array representing a single row in the CSV file. And each element of that array is an NSString.
So let's say your CSV file looks like this:
Barringer,Arizona,United States,Earth
"Chicxulub, Extinction Event Crater",,Mexico,Earth
Tycho,,,Moon
Lonar,Maharashtra,India,Earth
If you run it through the parser, you'll get back the equivalent of this:
[NSArray arrayWithObjects:
[NSArray arrayWithObjects:#"Barringer",#"Arizona",#"United States",#"Earth",nil],
[NSArray arrayWithObjects:#"Chicxulub, Extinction Event Crater",#"",#"Mexico",#"Earth",nil],
[NSArray arrayWithObjects:#"Tycho",#"",#"",#"Moon",nil],
[NSArray arrayWithObjects:#"Lonar",#"Maharashtra",#"India",#"Earth",nil],
nil];
What you do with it then is your business. The CSV parser doesn't know anything about UITableView, so you get to take this data and re-structure it in a way that you're comfortable dealing with and that fits in to your data model.
Also, remember that by using CHCSVParser, you agree to abide the terms under which it is made available. :)

import csv to coredata sqlite for iphone

how can I import csv to sqlite (core data for iphopne)
I have tried using SQLite manager, but it imports the csv to a new table, also I need to import some dates,
so how to import the data to my sqlite database? I have 3 entitys with different properties, and in the csv I have all the values in one csv (so I could format it or change it as needed), but how to impor it?
also what is the date format that coredata likes?
thanks in advance!
I assume you have setup your CoreData and that one is running fine. You don't really want to work directly with the sqlite DB of core-data. It is possible, but also a bit messy.
Use one of the CSV scanners floating around to read your CSV data into fields.
Map the CSV fields to your entities and to their attributes as needed.
You might want to use the CSV header to verify that your mapping CSV-column-to-attribute is ok.
Loop through the rows of the CSV and update your entities row by row.
Depending on data volume you might want to save your context at regular intervals.
Core-Data likes NSDate. Whatever the CSV file uses in the data column you are best off converting the CSV value into a NSDate. Using NSDate in your App will reduce the number of headaches later.
I would suggest, first create sqlite Database inside application using Core Data, then use database created by Core data to import csv data.
you can use the command line commands for importing data in the sqlite file.
Add the sqlite file to project.
replace and add this code inside the persistentStoreCoordinator method..
NSString *storePath = [[self applicationDocumentsDirectory] stringByAppendingPathComponent: #"yourDatabase.sqlite"];
/*
Set up the store.
For the sake of illustration, provide a pre-populated default store.
*/
NSFileManager *fileManager = [NSFileManager defaultManager];
// If the expected store doesn’t exist, copy the default store.
if (![fileManager fileExistsAtPath:storePath]) {
NSString *defaultStorePath = [[NSBundle mainBundle] pathForResource:#"yourDatabase" ofType:#"sqlite"];
if (defaultStorePath) {
[fileManager copyItemAtPath:defaultStorePath toPath:storePath error:NULL];
}
}
Change the method
- (NSString *)applicationDocumentsDirectory {
return [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
}