Sqlite on IOS dataconnection - ios

He Guys,
Should I open the data connection to Sqlite every time I make a query? or is it possible to open the sqlite connection when the app opens and the connection stays open until the app exists?
Is this even a solution?

You shouldn't really be using SQLite directly at all. At least use FMDB. Given your apparent new-ness to development, I would recommend Core Data as it is extremely well supported in the OS and will lead to the fewest lines of code (when used correctly).
To answer your concrete question; no, generally, you do not open / close a connection with every single query.

Related

Sync SQLite database between two iPhones

I'm currently finishing up a project for IOS in Swift in which I've used an SQLite database to store data with SQLite.swift.
At the time of coding I didn't know that SQLite files are stored locally on the device/simulator and I need a way to run the app and have the database synced between two devices, as soon as possible. I tried swapping over to Firebase since I heard that would be a solution but I'm not at all familiar with it and am worried it might be risky given all my functions are written for SQL tables. I also thought of keeping the SQL and adding on a firebase database to fetch the data from but I'm not sure how to execute that.
The solution doesn't have to be 100% reliable for all cases- I just need to simulate running the app on more than one device with synchronised data.
Does anyone have any suggestion for a way to do this? Or a way to store the data on a computer so that it can be accessed by both devices?
Any advice is appreciated!
There are no elegant solution with pure SQLite database. Just few offers:
Moving to CoreData (You will get all what you want with sharing data between devices)
Uploading database file to iCloud from one device and download it from another device
Build up classic client-server communication
Let iOS do the synchronisation via iCloud, e.g. use Core Data with CloudKit: https://developer.apple.com/documentation/coredata/mirroring_a_core_data_store_with_cloudkit/setting_up_core_data_with_cloudkit?changes=_1

Is a SQLite database is something that exist on my computer when developing an app with core data or each iPhone have an SQLite instalment?

I know, this is a super beginner question, but i'm a super beginner so please be kind and help me to get this right.
for the past 4 months i'v learned some c and java to get my programming of the ground, then started to learn objective-c and im learning to develop simple apps currently with the apple documentation guids, so I built a simple app and leaning now how to persist its data and save it to a database (which is probably the same thing :/).
Now, i'v never used a database before, and i'm wondering, when I build an app that use SQLite database (i guess it's the default database in core data), is the database is something that is created on the machine that developed the app, or each iPhone have a database instalment that is on the device to persist it's data..?
Would love to have any information possible, thanks a bunch!
I am working on some Core Data stuff and yes, there is a SQLite database on my development machine. When you create the DB (you are really creating a Managed Document that holds the database) you specify a file name and path within the app's file space. You have to find where that sits in the development machine file system. Here's where one of mine sits - obviously yours will not be in the same place but it gives you an idea...
/Users/leecea/Library/Application Support/iPhone Simulator/7.1/Applications/F4AC4CDC-4726-4D0E-B6C6-55F0F5C63BB4/Documents/CMDatabaseDir/CMDatabase/StoreContent/persistentStore
I am running SQLite Manager and can examine or update the database to help debug my app.
When you push the app out to a device, it will create an instance of the DB on each device, in a file in the app's sandbox. They are not connected back to the one on your machine.
Maybe there are more technically correct answers, but this visualization works for me :)

XCode: SQLite3: Leaving connection open

I am writing an iPhone app that makes many calls to a sqlite database. My question is, is it best to leave open and close the database connection for every query, or to leave it open and just close it when the app closes.
There are times in my app where I may loop through many iterations and in each I am adding a row to the db, but as I have it now, for each iteration I open the db, perform the operation, then close the db.
I would leave it open all the time the app is in the foreground and only close it when it goes into the background or when I get a memory warning. It might be expensive to open the connection, so I like to do it as little as possible, however it might consume resources which could be better used elsewhere.
You need to write all your db access code to open the connection if it's not already open; so you can close it whenever you like.
Personally, if you are making lots of calls to update the database, then I would try and keep it open. If there are 'chunks' of logic that you can keep the db open for then that would good, maybe having it open for all the time the app is running might not be the best thing - but this is really dependent on the architecture of your app.

Syncing a local sqlite file to iCloud

I store some data in my iOS app directly in a local .sqlite file.  I chose to do this instead of CoreData because the data will need to be compatible with non-Apple platforms.
Now, I'm trying to come up with the best way to sync this file over iCloud.  I know you can't sync it directly, for many reasons.  I know CoreData is able to sync its DBs, but even ignoring that using CD would essentially lock this file into Apple platforms (I think? I've only looked into CD a bit), I need the iCloud syncing of this file to work across ALL of iCloud's supported platforms - which is supposed to include Windows.  I have to assume that there won't be any compatibility for the CoreData files in the Windows API.  Planning out the best way to accomplish this would be a lot easier if Apple would tell us any more than "There will be a Windows API [eventually?]"
In addition, I'll eventually need to implement at least one more sync service to support platforms that iCloud does not.  It would be helpful, though not required, if the method I use for iCloud can be mostly reused for future services.
For these reasons, I don't think CoreData can help me with this.  Am I correct in thinking this?
Moving on from there, I need to devise an algorithm for this, or find an existing one or an existing 3rd party solution.  I haven't stumbled across anything yet. However, I have been mulling over a couple possible methods I could implement:
Method 1:
Do something similar to how CoreData syncs sqlite DBs: send "transaction logs" to iCloud instead and build each local sqlite file off of those.
I'm thinking each device would send a (uniquely named) text file listing all the sql commands that that device executed, with timestamps.  The device would store how far along in each list of commands it has executed, and continue from that point each time the file is updated. If it received updates to multiple log files at once, it would execute each command in timestamp order.
Things could get 'interesting' efficiency-wise once these files get large, but it seems like a solvable problem.  
Method 2:
Periodically sync a copy of the working database to iCloud.  Have a modification timestamp field in every record.  When an updated copy of the DB comes through, query all the records with newer timestamps than some reference time and update the record in the local DB from the new data.
I see many potential problems with this method:
-Have to implement something further to recognize record deletion.
-The DB file could get conflicts. It might be possible to deal with them by handling each conflict version in timestamp order.
-Determining the date to check each update from could be tricky, as it depends on which device the update is coming from.
There are a lot of potential problems with method 2, but method 1 seems doable to me...
Does anyone have any suggestions as to what might be the best course of action? Any better ideas than my "Method 1" (or reasons why it wouldn't work)?
Try those two solutions from Ray Wenderlich:
Exporting/Importing data through mail:
http://www.raywenderlich.com/1980/how-to-import-and-export-app-data-via-email-in-your-ios-app
File Sharing with iTunes:
http://www.raywenderlich.com/1948/how-integrate-itunes-file-sharing-with-your-ios-app
I found it quite complex but helped me a lot.
Both method 1 and method 2 seem doable. Perhaps a combination of the two in fact - use iCloud to send a separate database file that is a subset of data - i.e. just changed items. Or maybe another file format instead of sqlite db - XML/JSON/CSV etc.
Another alternative is to do it outside of iCloud - i.e. a simple custom web service for syncing. So each change gets submitted to a central server via JSON/XML over HTTP, and then other devices pull updates from that.
Obviously it depends how much data and how many devices you want to sync across, and whether you have access to an appropriate server and/or budget to cover running such a server. iCloud will do that for "free" but all it really does is transfer files. A custom solution allows you to define your syncing model as you wish, but you have to develop and manage it and pay for it.
I've considered the possibility of transferring a database file through iCloud but I think that I would run into classic problems of timing - slow start for the user - and corrupted databases if the app is run on multiple devices simultaneously. (iPad/iPhone for example).
Sooo. I've had to use the transaction logs method. It really is difficult to implement, but once in place, seems ok.
I am using Apple's SharedCoreData sample as the base for this work. This link requires an Apple Developer Account.
I did find a much much better solution from Tim Roadley however this only works for IOS and I needed both IOS and MacOS.
rant> iCloud development really has to get easier and more stable! /rant

SQLite Persistence throughout app lifecycle on iOS

I've been reading up on SQLite3 included in the iOS firmware which might serve my needs for the app i'm writiung.
What I can't figure out is if it is persistent or goes away like some objects do.
For example if I do sqlite3_open() which appears to be a C function rather than an Objective-C object, if I open this at the start of my application, will it stay persistent until I close it no matter how many views I push/pop all over the place.
Obviously that would depend on where I put it but if I was doing a universal app and had some central functions for loading / saving data which were common to both iPhone/iPad, if, in my didFinishLoading: I put a call to open the SQLite database and then called various exec's of queries, would it remain persistent throughout the lifecycle of the application.
or
Am I better off opening and closing as needed, i'm coming from a PHP background so i'd normally open a database at the start of the script and then run many queries and then finally close it before browser output.
From the 1,000,000th i've learned over the last few months about iOS programming, I think the latter might be the better way as there's possibility of app exit prematurely or it going to background.
I'd just like a second opinion on my thinking please.
I dont know directly, but I think you are right - you only need to open it once at the start of your app.
Looking at sqlitepersistentobjects, an ORM framework for iOS, it only opens the DB when its first used, and never closes it except when there is a problem opening it :)
Single opened sqlite database used throughout the app from different places in your app is fine.
You are using word "persistent" which is confusing. What you mean is "reuse of single connection, for executing different statements in the app, possibly from different threads". Persistence has completely different meaning in context of databases - it means that the requested modification of data has been safely stored to media (disk, flash drive) and the device can even unexpectedly shut down without affecting written data.
It's recommended to keep running sqlite statements from a single, dedicated thread.
It's not recommended to connect to sqlite database from different processes for and executing parallel modifications.
A good alternative solution is to use sqlite async extension which sends all writes to a dedicated, background thread.
You can check out https://github.com/mirek/CoreSQLite3 framework if you want to use custom built (newer version) of sqlite.

Resources