I have an app that generates some static data by importing from a json file into a sqlitedb, When running the app the DB file has data in it and is loaded properly, I usually go to the build folder "usually under
/Library/Application Support/iPhone Simulator/7.0.3-64/Applications/
and inspect the sqlite file and verify that it does have data.
Now I copy that same folder and paste it on the desktop, and open it in the same sqlite browser, and the data is gone?? why I don't know!!
I notice that for every sqlite file there is a -shm and -wal file generated.
Why is this happening?
Ok so I tried a little bit more investigating, I have two scenarios :
1 : I put a break point right after I finished generating the SQLite file, and then go the build folder, In the build folder the DB has data in it, if I copy that file to the desktop the db loses its data.
2 : I don;t put a break point, let the app finish normally ( gracefully ) and then go to the build folder, the db file has data, and when I copy and paste it to the desktop it still retains the data.
So I assume there's something that happens when xcode exits ( or the app closes normally ) that I am missing out on when I put a breakpoint !!
Starting with iOS 7 the sqlite database is used in Journaling mode by default - which means that all changes to the database are written to "update files", not to the database directly. You can change the behaviour back to the "old" way - have a look here for a complete explanation
:
Core Data and iOS 7: Different behavior of persistent store
Related
My current application only copying .sqlite file (WAL MODE = DELETE).
Everything went smoothly , the new copied myfile.sqlite also contain data perfectly.
When I execute a fetch request , the execution has no error , and BOOL (success) is 1 . BUT the returned array always EMPTY.
https://www.appcoda.com/core-data-preload-sqlite-database/
This tutorial told me I neeed to copy 3 files (.sqlite , .sqlite-wal , .sqlite-shm) in to Document directory .
Does this mean I need to Enable WAL mode and re-do everything from the start? In Xcode 10 we still cannot copy just 1 .sqlite file? Can someone clarify this?
Assuming that you mean journal mode, and not WAL MODE (and that you mean Xcode 8.x, since Xcode 10 doesn't exist yet), no you do not need to copy any additional files or change modes. With journal mode set to DELETE there's only the one file. You don't need to create extra files to make copying work.
But there are several other problems you might be having, which you should check on, and if necessary post additional questions about:
Maybe the copy phase isn't actually working as perfectly as you think.
Maybe you're not adding the SQLite file to the persistent store coordinator-- so it's not available when you do the fetch.
Maybe your fetch is misconfigured and is trying to fetch data that isn't present.
As for your question though, no you do not need to copy other files, or change the journal mode to force those other files to exist.
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
How to store database from one sqlite file (which is in our bundle) to sqlite file (which is created while we using core data) while we launching application first time.
Should we copy each entity, each row in loop or Is there any other way to do this.
You can put sqlite file directly in your bundle, for example you can create sqlite file with SQLite manager in firefox. Then when start your app you can check if file exist in the document directory, if not you need to create it. This only the first time.
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.
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.