Sqlite Copied issue - ios

I have created a SQLite file using FireFox sqliteManager and imported it to my application.
I need to copy this SQLite file from bundle to document directory. By using the below code, I am able to copy the SQLite file to document directory.
fIlMan=[NSFileManager defaultManager];
data=[fIlMan contentsAtPath:[[NSBundle mainBundle]pathForResource:#"mydatabase" ofType:#"sqlite"]];
pAth=[[[NSBundle mainBundle]resourcePath]stringByAppendingPathComponent:#"localDBFile"];
NSLog(#"%.2f",(float)data.length/1024.0f/1024.0f);
if ([fIlMan fileExistsAtPath:pAth]==NO) {
[fIlMan createFileAtPath:pAth contents:data attributes:Nil];
}
if (sqlite3_open([pAth UTF8String], &newDB)==SQLITE_OK) {
NSLog(#"DataBase successfully Created");
}
else{
NSLog(#"DataBase Failed to Create");
}
sqlite3_close(newDB);
Now if I run it in simulator its fine(nicely working). When I run this same on device, the application will terminate and show the warning as
Terminated due to memory pressure
Guidance needed on this. Thanks.

Use the copyItemAtPath:toPath:error: method of the file manager so that the file isn't loaded into memory.
Also, be careful about the destination path as [[[NSBundle mainBundle]resourcePath]stringByAppendingPathComponent:#"localDBFile"] is not a suitable way to get the document directory. Instead you should be using NSSearchPathForDirectoriesInDomains or URLsForDirectory:inDomains:.

Related

SQLite3 db on iOS 9: read only error, how to write to the db? [duplicate]

i deployed my App to my iPhone and get
Unknown error calling sqlite3_step (8: attempt to write a readonly database) eu
on Insert / Update Statements.
On the Simulator it all works like it should.
My sqlite Database is placed in the Resource Folder (Xcode).
Thanks for help!
Your application bundle is not writable on the iPhone. You MUST copy the file somewhere else, like your documents folder. It works in the simulator because the Mac does not enforce all the sandboxing restrictions the iPhone does.
You can copy your database from the application bundle directory to the Documents directory in viewDidLoad. You can read/write from/to your database in the Documents directory after this. Of course, you need to check if the database in the Documents directory exist before you do the copy in order not to overwrite it the next time you bring up the app.
Assuming you have defined your database name '#define kFilename #"yourdatabase.db"' in the .m file.
In viewDidLoad add:
// Get the path to the main bundle resource directory.
NSString *pathsToReources = [[NSBundle mainBundle] resourcePath];
NSString *yourOriginalDatabasePath = [pathsToResources stringByAppendingPathComponent:kFilename];
// Create the path to the database in the Documents directory.
NSArray *pathsToDocuments = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [pathsToDocuments objectAtIndex:0];
NSString *yourNewDatabasePath = [documentsDirectory stringByAppendingPathComponent:kFilename];
if (![[NSFileManager defaultManager] isReadableFileAtPath:yourNewDatabasePath]) {
if ([[NSFileManager defaultManager] copyItemAtPath:yourOriginalDatabasePath toPath:yourNewDatabasePath error:NULL] != YES)
NSAssert2(0, #"Fail to copy database from %# to %#", yourOriginalDatabasePath, yourNewDatabasePath);
}
Good luck!
aobs

Error while deleting the file

While deleting existing the file with this command:
[[NSFileManager defaultManager] removeItemAtPath:self.sourceFileName error:&error];
I got the following error
Error: ImageIO: CGImageReadCreateDataWithMappedFile 'open' failed '/Users/asdasd/Library/Application Support/iPhone Simulator/7.1/Applications/DD251D7D-F0AF-40E1-A033-F221623D589D/Library/ScanSession/Source/page3.jpeg
error = 2 (No such file or directory)'
This happens while I copied pic from album into app folder. The most interesting thing is that file exists, but not fully copied. Is there a way to check wether file is file operation completed?
check weather your file & Directory available
for (NSString *filename in files) {
NSString *path = [yourPath stringByAppendingPathComponent:yourFileName];
BOOL isDir;
if([[NSFileManager defaultManager] fileExistsAtPath:yourPath isDirectory:&isAvilDir] && isAvilDir){
NSLog(#"%# Check is a directory", your path file);
}
else {
NSLog (#"%# Check is a file",your path file);
}
}
I have a similar problem right now, and it seems as though when you delete a file that certain other methods you may have called immediately prior may actually not have completed yet. I'm considering delaying the actual deletion of files to allow for background processes to complete.
Solved it 2 yars ago. Forgot to post & close the question. It was caused by another thread, where the file was deleted first. I think its one of the standart mutlithreading issues while working with CoreData

Load data into my app xcdatamodel

My app must start for end users with data already in the database so that info is displayed to them when they use the app.
My problem: how can I load the data into the app database?
There's an "import..." option on xcode (on Editor when selecting xcdatamodeld) but I cannot understand what is the file type required - I've tried .xls, .csv and .sqlite and none is "importable".
Help!
Add the database to your bundle when you ship your app. On initial startup, you look to see if the database lives in the local file system. If not (and it won't be the first time you start up), you copy the database from the bundle to the local file system, open it, and use it from there. Don't try to use it from the bundle, that's set to read only.
I'm assuming you're using a SQLite database or some other type of file. You can add a file to your bundle using these instructions: How do I add files to the resources folder in XCode?
If the data is already in the .sqlite format (see note below), copy that file to the project (move the file to the Xcode project directory, and then from Xcode choose File -> Add files to "Project name", and find the file in your computer directory.
In the main AppDelegate.m file under the persistentStoreCoordinator function (see this tutorial for setting up sqlite/Core Data in your project), write the code to copy from the main bundle resources to the app resources directory, if the file doesn't exist:
NSURL *dbUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory]
stringByAppendingPathComponent: #"yourDBName.sqlite"]];
if (![[NSFileManager defaultManager] fileExistsAtPath:[dbUrl path]]) {
NSURL *bundleURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"yourDBName" ofType:#"sqlite"]];
NSError* err = nil;
if (![[NSFileManager defaultManager] copyItemAtURL:bundleURL toURL:dbUrl error:&err]) {
NSLog(#"Could not copy main bundle data");
}
else { NSLog(#"Main bundle data successfully copied"); }
}
It is important that your preloaded .sqlite database from the main bundle have been created properly from within an Xcode project (iOS apps only recognize specially-formatted .sqlite files).
Once this is loaded, it will be recognized as the app's database as long as the Core Data managed object context has its persistent store coordinator set to this .sqlite file, and that its structure matches that of the core data model.

How to add a .sql file to sqlite db in Xcode [duplicate]

This question already has answers here:
How should I specify the path for an sqlite db in an iPhone project?
(3 answers)
Closed 9 years ago.
I am writing a offline iPhone app in which I need to read and display from a database which consists of a few number of tables. The tables have over 100k entries in it, so it is almost impossible to enter it all individually. I have downloaded the .sql file of the entire db. Now how can I import the db as such into sqlite/Xcode so that I can readily start accessing the data in it??
Edit: I have seen that when using a database, the file extension that is used is a .db file. Is there anyway I can convert the .sql file to a .db file. And if I can do that, can I simply access the .db file by placing it in the project directory?
If you have created the .sqlite file and have the tables in it,Then add the .sqlite file into xcode like just drag from desktop into your bundle(Resources).And then use NSFileManager to access the sqlite file.You need to write methods for createdatabase and initialize database and also you can see the sqlite file in your documents folder/simulator folder.
- (void)createEditableCopyOfDatabaseIfNeeded {
NSLog(#"Checking for database file");
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
NSString *dbPath = [self getDBPath];
NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"ihaikudb.sql"];
BOOL success = [fileManager fileExistsAtPath:dbPath];
NSLog(#"If needed, bundled default DB is at: %#",defaultDBPath);
if(!success) {
NSLog(#"Database didn't exist... Copying default from resource dir");
success = [fileManager copyItemAtPath:defaultDBPath toPath:dbPath error:&error];
if (!success)
NSAssert1(0, #"Failed to create writable database file with message '%#'.", [error localizedDescription]);
} else {
NSLog(#"Database must have existed at the following path: %#", dbPath);
}
NSLog(#"Done checking for db file");
}

Unable to connect SQLite Database in iOS

I am completely new to SQLite and iOS. I am following a basic tutorial on how to use SQLite in iOS:
http://www.switchonthecode.com/tutorials/using-sqlite-on-the-iphone#comment-11617
In the above link, they have specified the database as:
sqlite3 *database;
int result = sqlite3_open("/myExampleDatabase.db", &database);
but when I use the above code with replacing my database name, I get an error as specified in the subsequent alertview.
My question here is, do I have to add the database file into my resource folder? If not, do I have to have my database file somewhere that is accessible to iOS?
I suggest using FMDB wrapper for SQLite:
https://github.com/ccgus/fmdb
If you want to open a sqlite database, you might want to:
Make sure you're including your database in your bundle.
Programmatically copy the database from your bundle to your documents (esp important if user will be modifying the database; if you're only reading, you could go ahead an just open the version in the bundle).
If you're running this in your simulator, you can go ahead and inspect the bundle and Documents folders if things don't go right, just to make sure everything is where it should be. You simulator's folder is something like "~/Library/Application Support/iPhone Simulator/5.1/Applications/" (replace the 5.1 with whatever version of your simulator you are using). You might have to unhide your Library folder, if you haven't already, by running the chflags nohidden ~/Library in a Terminal command-line window.
So, the code for getting the path of the database (and copying it to the Documents if it's not there yet), might look like:
NSString *databaseName = kDatabaseName; // obviously, replace this with your database filename, e.g., #"myExampleDatabase.db"
NSString *documentsFolder = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *databaseFullDocumentPath = [documentsFolder stringByAppendingPathComponent:databaseName];
NSString *databaseFullBundlePath = [[NSBundle mainBundle] pathForResource:databaseName ofType:#""];
NSFileManager *fileManager = [NSFileManager defaultManager];
if (![fileManager fileExistsAtPath:databaseFullDocumentPath])
{
NSAssert([fileManager fileExistsAtPath:databaseFullBundlePath], #"Database not found in bundle");
NSError *error;
if (![fileManager copyItemAtPath:databaseFullBundlePath toPath:databaseFullDocumentPath error:&error])
NSLog(#"Unable to copy database from '%#' to '%#': error = %#", databaseFullBundlePath, databaseFullDocumentPath, error);
}
Then, if you're doing your own sqlite calls, it would be something like:
sqlite3 *database;
if (sqlite3_open_v2([databaseFullDocumentPath UTF8String], &database, SQLITE_OPEN_READWRITE, NULL) == SQLITE_OK)
{
// do whatever you want to do
}
Or, alternatively, if you're using FMDB, it would be something like:
FMDatabase *db = [[FMDatabase alloc] initWithPath:databaseFullDocumentPath];
NSAssert(db, #"Unable to open create FMDatabase");
BOOL success = [db open];
NSAssert(success, #"Unable to open database");
if (success)
{
// do whatever you want to do
}
I fully support the previous answer in most cases, however:
Are you sure you have to use sqlite3 instead of Core Data?
There are several discussion where you can get information when to use a database wrapper (like fmdb) and when to use Core Data. (Speaking personally, I love to use fmdb, but it always results in more code, complexity and most of the time a worse performance)
Core Data vs SQLite 3
Use CoreData or SQLite on iPhone?
Core Data vs Sqlite and performance
Core Data vs SQLite 3
is it worth using core data for a simple sqlite app on the iphone with one table and no relationships or complicated subtable/views?
Core Data vs. SQLite for SQL experienced developers
Some links to get started with Core Data:
Core Data Programming Guide (Apple)
Core Data Tutorial for iOS (Apple)

Resources