MagicalRecord SQLite file empty - ios

I am having problem reading a file. I'm using MagicalRecord as my CoreData wrapper. I successfully save or update object. With my NSLog I can see it, everything is fine and I can use it in my database. But every time I want to see SQLite file with my application (I'm using Datum LE), file is empty. I cannot access that file directly within my Library folder in my app. I copy that file to my desktop and it is empty. What am I doing wrong? So once more, everything inside my iOS application works fine, I can see records being saved and I can fetch them normally.

You are clearly looking at the wrong file. If your app is saving (I assume, across app restarts), the date is definitely saved.
One way to find out is to NSLog the persistent store URL and check the referenced file.

I believe the issue you are encountering is the new default journaling mode that Core Data uses.
See this article
https://developer.apple.com/library/ios/qa/qa1809/_index.html
Basically your changes are not written to the .sqlite file, but are found in .sqlite-wal. HOWEVER, most SQLite reading apps I have tried blow away the -wal when you open the .sqlite, so good luck.
You could try changing the journaling mode for debugging purposes

Related

IOS (Swift) How to explore persistent file(s) during debug session?

First post on StackOverflow, after extensively using it for a long time.
I'm building a small app (just to lear swift), and I have troubles with making some data persistent. I use NSCoding to achieve that. The problem is that when saving, the function NSKeyedArchiver.archiveRootObject() return true (so apparently it worked), but when, later, I try to retrieve these saved informations, the result of NSKeyedUnarchiver.unarchiveObjectWithFile() is nil.
Without posting all my code, I was just wondering if it were possible to explore the file in which persistent data are stored during a debug session. That would allow me to check whether I have a problem with the saving or the loading part of the process, and see if the data are indeed stored in the right file.
Thanks,
Lb
Per Apple Documentation, you get a nil with unarchiveObjectWithFile when there is no file at the mentioned path. I would advise to check your file path where you are archiving and saving your object.
As for the debugging, follow this:
Print the file path when you are archiving and saving the object. So in this NSKeyedArchiver.archiveRootObject(myObject, toFile: filePath) print filePath.
Open your terminal app and execute open <filePath> command to open the file path where data is being saved.
Check out if your data file is created in there with right archiving.

Read through my app's Core Data files (.sqlite, .sqlite-wal)

I am trying to browse through the data written by Core Data in an iOS app I am developing.
After the app ran for a while, and I assume collected some data, I now wish to look through the data and see what was written.
I have tried getting and browsing the .sqlite file through getting the app container from the device (Xcode > Devices > myApp > Download Container...).
I got the db files, myAppDB.sqlite, myAppDB.sqlite-shm and myAppDB.sqlite-wal.
When trying to look through them, it seems like the .sqlite is an empty table (except maybe some generic CoreData/sqlite stuff), and the -wal file has all the info.
The thing is I was only able to know that the wal has useful data when opening it with TextEdit, which din't show it in a very readable way, and when I tried to use an SQLite Manager app I an alert saying the wal is encrypted and I am asked to put a password...
For what it matters, I am writing a framework which handles the db (the model file and the code for writing data is inside the framework), then I have this framework running in an app I am developing. This is the code I use to create the store from within the framework (using MagicalRecord):
NSBundle *frameworkBundle = [NSBundle bundleForClass:[self class]];
[MagicalRecord setDefaultModelNamed:#"myAppStore.momd" inBundle:frameworkBundle];
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:#"myAppStoreDB.sqlite"];
[MagicalRecord setupCoreDataStackWithStoreAtURL:storeURL];
UPDATE: I managed to open the sqlite file with both Core-Data-Editor and CoreDataUtility but they both override and delete the contents of the .wal file, and show an empty table... It does have the model (entity names/properties etc.) but no data.
My wal file is 873KB but when I open the sqlite with one of these 2 tools it becomes 0Bytes...
tl;dr
How can I browse through the info written by Core Data of the app I am developing?
Well, for some reason I had to force not using WAL in my store (using #"journal_mode":#"DELETE" as explained here).
I then got only .sqlite file without the smh and wal files, and was able to open it and view the data using the 2 mentioned tools (Core-Data-Editor and CoreDataUtility).
My guess is that this is something to do with either the fact that I am dealing with CoreData from a framework (creating a moc, creating entities, saving etc.) and not from the application. Another guess is that it has something to do with the fact that I am using MagicalRecord.
Any insights regarding the cause would be appreciated...

Unable to open sql store file used in iOS application

I am using a sql based database in one of my application with Core Data framework. I have not enabled any file protection for persistent store (using NSFileProtectionKey). But I am unable to open my database file store in a directory under 'Caches' folder in Library.
Have you ever come across such an issue. Below is the image I am getting when I try to open the sql file. However, a difference from iOS 6 I could see in that folder is there are two additional files (-shm and -wal) present with the same name of the sql store file.
Could anyone please help me to find a solution to open the file.
The -shm and -wal are journal files created using write-ahead logging. You need all 3 files for a complete database. I haven't seen an encryption error falsely triggered by not obeying this rule, but it doesn't seem out of the question.
See https://developer.apple.com/library/mac/qa/qa1809/_index.html and http://asciiwwdc.com/2013/sessions/207.

No data in tables when copying sqlite database to ios app

I'm using core data and am pre-populating it using a SQlite database that I provide in the bundle. It's been working fine for a while, however I've just edited the database and when I copy it over there is no data displayed. So I opened the database that is on the ios simulator, in base, and I found an sqlitemaster table that contains lots of SQL statements such as CREATE TABLE..., but the tables I want don't contain any data.
What's weirder is that after a while the database is fine and all the data is in it as normal. Is this because the statements in the sqlitemaster table were executed?
Has this happened to anybody else? I don't know whether it's because I've upgraded to iOS 7 or not? If anybody could point me in the right direction that would be great
The latest iOS Core Data SQLite backend uses journaling. You should notice .shm and .wal files in the same directory as what you assumed was your main sqlite backing store for Core Data. This data eventually gets into the main file, but journaling optimizes some situations for Core Data configured with SQLite.
As a developer, you generally never care about this from within the app, but if you are trying to inspect the persisted Core Data graph via the actual file, you'll need to be aware.
I've had a look around and the journaling was causing it to go all weird. Found this post which shows the same problem I had. If anyone else has this look at that post

How can I ship my app with a pre-populated Core Data database?

My app uses Core Data and I want some default entries to be inside.
What's best practices of how to do that?
If you're already loading the pre-load data via a temporary routine for testing in your current code there's no reason you can't use the sqlite file it creates in the simulator's directory (no need to write a separate Mac app).
If you're not already filling that db you can still write an iOS app that does it. Odds are you've already written the methods for adding data to your store so you can use them to import the pre-load data as well.
Either way you'd grab the sqlite file from the simulator's directory and add it to your app's bundle; on first launch you'll copy it into the appropriate place in the app's directory before pointing Core Data to it. If it's really large the downside is that there will be a copy in the bundle and another on disk, but there's not much you can do about that other than grabbing the data over the network.
As others have suggested, if the amount of data is small you can just import it at first launch, using the methods you've already written for adding data as part of the normal app's workflow.
See the CoreDataBooks example, which has sample code for copying a database at first launch.
EDIT: I've created a Core Data framework (read about it here: http://bikepress.org/?p=1120) that includes this feature.
I would just create a database and put add it to my target so that Xcode copies it into the app bundle. At the first launch just copy it from the app bundle to eg. the documents directory or wherever your app expects the database.
There is Core Data Editor at the app store. Alternatively you could build your own simple mac app just for this particular DB and manage it from there. If the amount of default entries is small, then you're better off storing it in a plist or something and loading it into DB after the first launch.
In iOS 5, my app was rejected if I put a database file into resource bundle. So, I have to download the database from internet instead.

Resources