FMDB SQLite doesn't show up in my device - ios

Again, I need someone's help. I am following the below tutorial for SQLite connection with FMDB wrapper:
http://www.icodeblog.com/2011/11/04/simple-sqlite-database-interaction-using-fmdb/
In the above tutorial, everything (creating a database and table, inserting, deleting) is done programmatically but everything works fine in simulator but when I use SQLite Manager add-on to make any insertion on the database (that was programmatically created in iOS), it doesn't show up in my testing device. Is there something that I am missing (like copying the file to my bundle) on my side? This is really driving me crazy. I am completely new to these.. Can anyone help me with this?
PS: I know I can use Core Data but for certain reasons I have to live with SQLite for this app. Any help would be greatly appreciated.
Thank you in advance.

Make sure to (a) include the db in the bundle (see here for screen snapshot of where the "copy bundle resources" can be found); and (b) programmatically copy db from bundle to documents. You can then open it from there.
Why it works on your simulator and not the device is a little curious. I can only imagine that you're reading from some fixed path, rather than programmatically retrieving the app's Documents folder?
Update:
I'd suggest checking your various return codes and make sure everything is ok.
I've taken your code sample and have (a) checked result of creation of FMDatabase; (b) checked result of open; (c) checked the result of FMResultSet, including the display of the sqlite error message; and (d) closed the result set:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docsPath = [paths objectAtIndex:0];
NSString *path = [docsPath stringByAppendingPathComponent:#"DADatabase.sqlite"];
FMDatabase *database = [FMDatabase databaseWithPath:path];
NSAssert(database, #"Unable to create FMDatabase object");
NSLog(#"%#", database);
BOOL success = [database open];
NSAssert(success, #"Unable to open database");
FMResultSet *results = [database executeQuery:#"SELECT * FROM DrugList"];
NSAssert(results, #"Unable to create result set: %#", [database lastErrorMessage]);
while([results next]) {
NSString *name = [results stringForColumn:#"Drugname"];
[arrayToLoadDiseases addObject:name];
}
[results close];
[database close];
If you're running this in your simulator, you can go ahead and inspect the simulator's 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. Anyway, you can open up the simulator's database using Mac OS X's sqlite3 command and make sure your table is ok.
A common mistake is to fail to programmatically copy the database properly, thus the open method will create a blank database, and executeQuery will fail saying that the table was not found.
Let me know what you find.

Related

Writing big file on IOS [duplicate]

I save some run-time generated files inside the .app bundle of my iOS app. In the simulator it works fine, in the device it crashes:
Could create output files in the given shader cache path
'/var/mobile/Applications/CB064997-B40E-4FE3-9834-B3217CE33489/SimedTest.app/Ogre3D/assets/RTShaderLib/cache/
Is there a good overview of where I should and shouldn't put files - how to use Documents, Library and tmp, etc?
To clarify, these are files created at startup which pre-calculate some data to save time. IF they are not present they get created so it's fine they are deleted, but not while the app is running.
The bundle is read-only. You don't want to mess around with it for two reasons:
Code Signing: the signature is verified by against the contents of the bundle; if you mess around with the bundle, you break the signature.
App Updates: updates work by replacing the entire app bundle with a newly downloaded one; any changes you make will get lost.
Where you should save stuff:
Documents: if you want it to persist and be backed up
Library/Caches: if you just want to cache downloaded data, like profile pics; will be auto deleted by the system if it is low on room unless you specify with a special do-not-delete flag.
tmp: temporary files, deleted when your app is not running
For a full explanation check out File System Programming Guide and QA1719.
No, every time you change your bundle you invalidate your signature.
If you want to write files you`l need to write in the best folder depending on what you want to do with that file.
Documents folder for long duration files
Cache for small operations
and so on
EDIT
To get the path you`ll need something like this:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:#"filename.ext"];
With this path you can write or read like this:
write:
NSString *content = #"One\nTwo\nThree\nFour\nFive";
[content writeToFile:fileName atomically:NO encoding:NSStringEncodingConversionAllowLossy error:nil];
read:
NSString *content = [[NSString alloc] initWithContentsOfFile:fileName usedEncoding:nil error:nil];

iOS Simulator recreates sql database/table

I'm using XCode 6.4 and iOS Si,mulator iPhone 6. Every run of my app database or table is recreated so i lost all previously inserted data. I have 1 database with 1 table inside. Database file is located in Supporing Files directory of the project. Here is the code for database initialization:
BOOL success;
NSString *databasePath = [[NSBundle mainBundle] pathForResource:#"signals" ofType:#"sql"];
NSFileManager *fileManager = [NSFileManager defaultManager];
success = [fileManager fileExistsAtPath:databasePath];
if (success) {
NSLog(#"exists");
return;
} else {
NSLog(#"No file found");
[fileManager copyItemAtPath:databasePath toPath:databasePath error:nil];
}
On run - success variable is YES - so i see in logs "exists". After that i insert one item to my table and do select query that returns this one inserted raw. On next run i should see two rows, but there is only one row again - so i assume the table was recreated. I need help with this problem.
Not got enough reputations to comment, but if you're not getting any No file found messages in your log, then I don't think this is the block of code that is causing the problem. Are you definitely doing an Insert query into the database and not an Update? Also, is your Select query returning all rows and not just one. Are you running through XCode or directly in the Simulator? XCode might overwrite the files if you're running it just through there - try re-running the app in the Simulator (CMD + Shift + H to get to the home screen), and seeing if that makes any difference.
This is not a bug in the simulator or in Xcode. There is a bug in your app and not in the simulator itself. You should not be modifying the database at this location:
[[NSBundle mainBundle] pathForResource:#"signals" ofType:#"sql"];
That is not persistent across updates of the application. You will see the same issue when updating your app on device.
Instead, use a persistent location, like:
NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documents = [directories firstObject];

How to Open data(saved using core data model) saved in my in pad

Im new to core data, Created one model and saved some data in my simulator and opened the .sqlite folder which will contain my data.
Now i done the same thing in my iPad with different data
How to see that .Sqlite file, where its stored… in iPad
Can I copy Same data in another iPad, I mean with out entering all data again ….
Thanks …
You can get your app's container when you attach you device to Xcode.
Windows->Devices->Your App->Click the small setting button->Select download container.
Show the content of your appdata you saved, you will see the .sqlite file in the folder.
In terms of browsing the data, you have several choices.
Here is a discussion about good tool for browsing core data.
Is there a good Core Data browsing tool out there?
In this case I use DB Browser, it works fine.
Could you explain more why you want to do that?
Hope it helps :)
Yes, you can by storing your data files in "Documents" folder, whose path is:
- (NSString *)pathToDocumentFolder
{
NSArray *paths = NSSearchPathForDirectoriesInDomains( NSDocumentDirectory, NSUserDomainMask, YES);
if( [paths count] < 1 )
return nil;
return [paths objectAtIndex:0];
}

How can I save document files to the SQLite Database in iOS to view them later in the program?

I'm having a problem with the code I'm writing.
I'm writing an iOS program (I'm an iOS rookie) which basically requires me to use quick look framework to view some documents on the iPhone (*.doc, *.ppt, *.pdf etc..) which are stored in the database (Core Data - SQLite, nothing external). I need to add the files somehow, but since iOS isn't really allowing me to browse through its file system I can't find and save the documents i need in database. Which kinda blocks everything else i need to do until I can get those documents from the database. (to set up table views that list the files and the details about the files etc.)
This is for a class project so it doesn't need to be perfect condition, I just need to be able to browse through a few documents while I'm presenting the project. I can add all the documents I'm going to use at one time while I'm coding and I won't need to be able to add any new files when I'm using the program during the presentation. And I don't want it to make it more complicated if i don't have to. Like connecting to an external database with the files already saved in and use a php buffer-page to connect to that database or anything like that. I don't have the necessary server system to execute that php file. I want this operation to be done inside the phone.
The solutions I was able to think of so far:
Grab some random office files from the internet and save them into the database. Then use them later.
Create image scans of some office files and "cheat" by using the scanned image instead of actual documents.
I would really appreciate it if someone can tell me another and much easier way to handle this. Please just keep in mind that while I have a programming background with Java and C#, I'm still an iOS rookie and just barely moving on from scratching the surface. So it is likely that I don't know about something iOS provides by default and I'm just pulling my hair out for nothing.
I think thats it, I hope I didn't forget anything. If you need more details I'm going to be here and I can provide them almost instantly. Thanks everyone in advance for your help.
It sounds like NSFileManager will help you.
If you place your documents into your project tree, they will be available to your app. Use NSFileManager to copy them into the app's Documents folder using something like:
- (void)placeBundleFileInDocuments:(NSString *)filename
{
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *bundlePath = [[NSBundle mainBundle] pathForResource:[[filename lastPathComponent] stringByDeletingPathExtension] ofType:[filename pathExtension]];
NSString *documentsFolderPath = [NSString stringWithFormat:#"%#/", [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]];
NSString *path = [documentsFolderPath stringByAppendingPathComponent:[NSString stringWithFormat:#"%#", filename]];
if ([fileManager fileExistsAtPath:path])
return;
NSError *error = nil;
[fileManager copyItemAtPath:bundlePath toPath:path error:&error];
if (error) {
NSLog(#"Unable to copy file (%#).", error.localizedDescription);
}
}
Then, you can use NSFileManager to retrieve details about the files. You might find this method useful:
- (NSDictionary *)attributesOfItemAtPath:(NSString *)path error:(NSError **)error
I hope this helps!

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