I'm developing my first iOS application .
In this application , I am using Storyboard and it got some Views and TableViews use information captured from a SQLite file.
This file SQLite suffers updates constantly , so I created a PHP system that always updates and offers that SQLite file through a URL of my site .
In my application I've created a View configuration , which checks for a new SQLite file to download, and if you have , download this file and replace the existing database with the new. With that my application is always updated .
My problem is right there. When the user opens the application , it goes straight to a view that captures the information from the database and list in a table .
If, then, you go to the View configuration and update the database, that my first view will be updated only when the user restarting application.
Do not know if has to understand what is happening, but it seems like after reading the SQLite first, my application writes a kind of Cache.
I need it as soon as you download and replace the database, I can force the application to update the information, even though the other Views have already been accessed or not.
Now appreciate the patience and help of all.
hugs
Related
I am working with sqlite in iOS app. I have created login and register screens and tables successfully. Now, I am creating another table to save data. The table has been created but when I run the query to insert values, I get following error --- "no such table: proposalInfo". Can somebody help me in this ?
If you created database on terminal, then the problem is likely how you got the database you accessed from the terminal to your iOS device. Usually you would include it in the bundle (and make sure you have a checkmark against the appropriate target), and then you'd have code that looks for the database in “Application Support” directory, and if it does not find it, copy it from bundle to there. (Note, in the past, we would have recommended the “Documents” folder, but nowadays that is for user-facing files; we use “Application Support” directory nowadays for files used internally within the app.) The typical problem is simple bug in that logic (perhaps in previous iteration of development), which failed to copy it properly and then subsequently called sqlite3_open which created blank database.
Likely, somewhere in this process, there was insufficient error detection/reporting, so some error went undetected and blank database was created. So, I would recommend:
remove app from device (to get rid of any blank database in “Application Support” folder, if any);
double check error detection/reporting (e.g. check all NSFileManager method return codes and NSError objects);
do not use sqlite3_open, but rather use sqlite3_open_v2 so that it will never create blank database (namely, with SQLITE_OPEN_READWRITE option, but not SQLITE_OPEN_CREATE); and
run app again and see if you can identify where in the process it went awry.
By the way, if you do not believe us that the table is really missing from the database, I would suggest you open the simulator’s database from macOS SQLite tool, and simply confirm. So
navigate to the simulator’s “Application Support” folder:
~/Library/Developer/CoreSimulator/Devices/[GUID]/data/Containers/Data/Application/[GUID]/Library/Application Support
And
Open that database in your SQLite terminal interface, and confirm existence or absence of the table in question.
Please create table using SQLite browser. Which is you can download from here.
Then follow below step
1) Open your project db by clicking.
2) Create table Query or using UI.
3) Execute query whatever you want.
I have an app that uses a database of about 5000 entries.
This database is bundled in the app as a realm file.
I want to be able to update/add entries to this database regulary using REST and I think I have done it correctly - I just want to make sure.
This is how I have done it:
When the app is installed I copy the bundled database from the mainBundle to the Documents directory for read/write access. I then delete the database from the mainBundle.
When I update/add new entries to the database, they are pushed to the user using REST and inserted into the database located in the Documents directory.
When an update is released of the app, I make a check to see if the database already exists in the Documents folder - if it does I automatically remove the database in the mainBundle as it is not needed.
Am I on the right track with this? Is there a better way of doing it?
Appreciate any input!
Regards,
Erik
When I update/add new entries to the database, they are pushed to the user using REST and inserted into the database located in the Documents directory.
Technically, you can't push via REST. So I guess, you're either sending a background push notification to all installations or you're checking at application launch, whether there is a new version of the database available. That's at least what I would propose, but your requirements for getting new data out may vary.
When an update is released of the app, I make a check to see if the database already exists in the Documents folder - if it does I automatically remove the database in the mainBundle as it is not needed.
This doesn't work. The main bundle is the signed app bundle. If you would tamper the contents, that would prevent your app from launching. For that reason the access to it is limited by the OS to read-only. So this operation will always fail with an error. Instead you might properly just want to skip seeding the database from the main bundle.
I am updating an old iOS app which used sqlite database. I changed the database structure adding columns to existing tables. Now, I am testing it on my device. If I clear my old app from iPad and then run this new updated version on it, it is working fine. But if I have the old version installed on ipad already and test this updated version, it is somehow using the old database instead of the one updated. Can some one help me why it is doing this?
My guess and to try and make a simple answer for you is this. It's likely you updated the database in the project file - which means when you run it, your new db will exist in the bundle. files in the bundle cannot be updated, so its common practice to copy the database out of the bundle and store it somewhere in the ios sandbox. I usually use the documents directory to keep it simple.
Most likely what is happening is that when you run it over a pervious install, it see's that the file is already copied over to the device so it does not touch it, however on new installs, it probably sees the database is missing so it copies it there and that is why on new installs it works fine but existing ones it does not.
Look in the app delegate or your root view controller for code that checks for the existing database and copies the database over if needed on startup.
If you need to update the database on existing installs, you would need to force the copy.
Beware though if you have data in the existing database not to overwrite it if its important. If important data is stored there, you have to either do a little shell game of getting the data and importing into the new database, or maybe a simpler way, is to run the database schema modification commands on the existing database so it is the same.
again, beware and make a copy of the local database file before you run those commands, just in case.
best of luck
In iOS, a SQLLite database is really just a file. When you used the old app, it created the schema in the database file. When you load the new app, the data remains, untouched. If you want to use the new schema, you will have to detect the old schema and update the existing data. I believe that there are documented ways to deal with this. Bryanmac's question reference seems to be a good place to start.
When you install a new version of your app, iOS actually installs it in a new directory and then copies the contents of the documents folder from the older version to the one in the newer version. If you want to just use your new db, the best way is to have this db renamed or stored in a different directory inside your app's document store.
Here's a relevant article on updating An sqlite CoreData backing store on iOS:
http://www.musicalgeometry.com/?p=1736
I have a SQlite database file with records which comes with my app.
I just used the file I added to my project to make my INSERT and UPDATE statements.
After uploading it to my test device I got the exception that the file is read only.
After a bit of research I found out, that I have to copy the db file to the users directory to make an insert. This works for now. But I have a view questions about it, which i didn't get answered through google:
Where should I put my copy process?
I implemented it in the AppDelegates FinishedLaunching, where I check if it already exists.
Where should I copy the file to?
I used the MyDocuments folder for now, is this ok?
Since the file cannot be encrypted, can another app access the database file?
When the user decides to delete the app from the device. Will the database file get deleted,too?
Thanks!
Where should I put my copy process? I implemented it in the AppDelegates FinishedLaunching, where I check if it already exists.
That really depends, but finishedLaunching is OK from my point of view.
Where should I copy the file to? I used the MyDocuments folder for now, is this ok?
I'm not sure what you mean by "MyDocuments" folder. Each Application has a dedicated Document directory. That's where you should copy it.
Since the file cannot be encrypted, can another app access the database file?
No, they run sand-boxed (unless the device is jailbroken)
When the user decides to delete the app from the device. Will the database file get deleted,too?
Yes, since the whole document directory will be deleted.
Where should I put my copy process? I implemented it in the AppDelegates FinishedLaunching
Keep in mind that you have a limited amount of time to complete FinishedLaunching execution (around 15 seconds) before the iOS watchdog kills your application.
Depending on the size of your database, the speed of device and other processing you need to do then you might want to consider only checking if it already exists (that should be quick) then do the copy (if required) from to another thread.
I used the MyDocuments folder for now, is this ok?
Yes, using Environment.GetFolderPath (Environment.SpecialFolder.MyDocuments) is correct.
Everything else from #Lightforce answer covers the rest.
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.