import csv to coredata sqlite for iphone - 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];
}

Related

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

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];

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

Optimize time access to sqlite using coredata

I'm trying to use a pre-generated sqlite file containing 10 000 objects in a table.
I've created and added objects, with iPhone simulator, in the sqlite using coredata.
I've copy and past the sqlite contained in iPhone Simulator ressource folder (containing 10 000 objects), into my ressource folder in my project directory.
What i do at first launch of my app, is copy this generated database into my app document directory on the iphone using :
NSBundle * mainBundle = [NSBundle mainBundle];
NSString *oldPath = [mainBundle pathForResource:#"MyBase" ofType:#"sqlite"];
NSString *newPath = [[app_delegate applicationDocumentsDirectory] stringByAppendingPathComponent: #"MyBase.sqlite"];
BOOL copied = [[NSFileManager defaultManager] copyItemAtPath:oldPath toPath:newPath error:&error];
if (!copied) {
NSLog(#"Moving database from %# to %#, error: %#", oldPath, newPath, error);
}
It works fine, but i have the following problem :
Comparing access to the original MyBase.sqlite (created on my device and filled with the same 10 000 objects) with the new copy, all access on tables take 3 times more time than on the normal generated MyBase.sqlite.
I wonder if when generating sqlite on simulator, indexed attribute does not exist?
I need help!
Your using a fairly common technique and it does not normally cause any issues. Core Data cannot tell the difference between a store just created and an old one if both stores use the same data model.
The only explanation I can think of is that you are using two different system/API versions such that the store file is subtly different. If the version on device is older/newer than the version on simulator you might have problems.
That's just a wild guess.

Including Core Data in app bundle

I'm not sure that I completely understand how Core Data works on iOS.
I have a large JSON file which I have parsed and imported into core data. This generates an sqlite file. I need this file to be included with the app but every time I delete the app from the device - I have to run the JSON parse script again to create a new sqlite file on the device. I want to be able to exclude the JSON file from the application bundle and dont want to run the parsing script on first use.
How do I go about doing this? Am I doing something wrong?
You will need to create the sqlite file (using your app if you like), then copy it into your project and deploy it with the app. You will also need to add some code to move the file into your documents directory when your app runs for the first time. It can be a simple if file doesn't exist then copy it script.
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *DB = [[paths lastObject] stringByAppendingPathComponent:#"myDB.sqlite"];
if (![fileManager fileExistsAtPath:DB]) {
NSString *shippedDB = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"myDB.sqlite"];
[fileManager copyItemAtPath:shippedDB toPath:DB error:&error];
}
I use this method to ship out pre-built sqlite files, although I haven't used it when CoreData is managing the sqlite file.

Is possible to read plist from application bundle and documents folder at the same time?

Is it possible?to read from my local bundle and at the same time also read from documents folder into UItableview?
thanks thanks
yes.simultaneously
No — as in the iPhone isn't multicore, you can't have "simultaneous" :p
Yes — as in you can open multiple files in the same period of time. There's no conflicts as long as the files are different (if the files are the same then it depends on how others are using and locking the file etc.)
on viewDidLoad or some similar event when you would be populating your table data, you would simply just aggregate the two files together... that is you are are likely populating an array or dictionary with the contents of the file in question... so use the mutable version of array/dictionary, initialize it empty, then read in the first file from whatever location you choose, populating into your mutable array/dictionary, then do the the same for the next file. after you are done, reloadData as you normally would as if you had read form one file.
As far as simultaneous goes, technically no. However, one could have two different active threads each one reading required files and parsing the data.
Regarding the files you want to access...
Here is a quick and dirty method I use in one project (which I just happen to be working on at the moment):
NSFileManager* fileManager = [NSFileManager defaultManager];
NSError* error;
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
self.documentsDirectory = [paths objectAtIndex:0];
self.blahDBPath = [self.documentsDirectory stringByAppendingPathComponent: #"blah.db"];
NSLog(#"Mainbundle Resourcepath: %#", [[NSBundle mainBundle] resourcePath]);
NSString* defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"blah.db"];
NSLog(#"Default DB Path: %#", defaultDBPath);
success = [fileManager copyItemAtPath:defaultDBPath toPath:self.blahDBPath error:&error];
if (!success) {
NSAssert1(0, #"blah blah blah '%#'.", [error localizedDescription]);
}
It is ugly but effective. I'll rewrite it when I refactor the application.
The point here is that I ask the operating system for the path to certain directories. Then I add file names or subdirectories as required. This allows the operating system to manage paths (like in the simulator where each successive build gets a new unique id as part of its path) and I just worry about the final directories and file names in the application.
One I have the paths, I copy the required file from the bundle directory and put them somewhere, the Documents directory in this case. Then I can do whatever I need to with them.
If I just wanted to access them as they are in the bundle directory, then I I just refer to them by using [[NSBundle mainBundle] resourcePath].
I think something along the lines of the above snippet is what you are looking for.
-isdi-