Unique Realm container objects - ios

I implemented real time sync following Realm's tasks demo app.
There a dummy container is used, to hold a List with the models.
The demo app doesn't seem to support offline usage.
I wondered what happens when, given this setup, I start the app on an online as well as an offline device and then go online with the offline device.
My initial expectation was that I'd end with 2 containers (which would be an invalid state), but when I tested surprisingly there was only 1 container at the end.
But sometimes I get 2 containers and haven't been able to identify what causes this.
The question then is, how does this exactly work? I assume the reason that the container is normally not duplicated when I sync the offline device for the first time is that it's handled as the same object, maybe because it doesn't have a primary key or something? But then why is it sometimes duplicated? And what would be the best practice here? Do I maybe have to use a primary key or check after connecting if there's duplication and if yes do a manual merge of the containers?

At the moment, Realm Tasks merely checks if the default Realm is empty before it tries to add a new base list container object. If the synchronization process hasn't completed by the time this check occurs, it's reasonable that a second container would be created. When testing the app on a local network, this usually isn't a problem since the download speeds are so fast, but we definitely should test this a bit more thoroughly.
Adding a primary key will definitely help since it means that if a second list is created locally, it will get merged with the version that comes down from the server.
We've recently been focusing on the 'on-boarding' process when a second device connects to a user's Realm Mobile Platform account via the new progress notification system. A more logical approach would be to wait for the synchronization to complete the initial download after logging in, and then checking for the presence of the objects. Once the documentation is complete, we'll most likely be revamping how Realm Tasks handles this.
The demo app (as well as the Realm Mobile Platform) does support offline, but only after the user has logged in for the first time (which is when these container objects are initially generated). After that time, the apps can be used offline, and any changes done in that interim are synchronized the next time it comes online.
We're planning on building 'anonymous user' feature where a user can start using the app straight away (even offline) and then any changes they made before they log in (due to them being offline) are then transferred to the user account after they do so.

Related

Firebase Remote Config when to load on iOS to receive A/B test variant

It seems that all examples from Firebase suggest reloading the Remote Config in didFinishLaunching. It looks like a great idea, BUT I see an issue with it. When I run this setup in the simulator, the first fetch arrives with the default values set in the console. Seems reasonable, but the problem is that I have a running A/B testing experiment — actually, several of them. And I do see that on the second launch, I receive new values coming from those experiments.
The experiments target all users of my app, and it worries me that from the first launch, I do not receive those values. In a real-world, Firebase will cache the obtained values for 12 hours. However, as the docs do not mention when a user is counted towards a particular variant in my experiment, I worry that for these 12 hours some of my users will be attributed to non-default modification even though their app does not know that they should receive a non-default experience.
Another issue which I have is the fact that for Remote Config fetch to execute in didFinishLaunching, the app needs to be terminated. What if my users use it regularly and the system doesn't kill it? It means that they may never receive updated config values.
My question boils down to these:
Isn't it better to reload the Remote Config in didBecomeActive?
When does Firebase attribute a user to a particular variant in my A/B test? Does it happen silently at some point in app lifecycle, or do they make sure that it only happens when my user received corresponding Remote Config values? It may be a silly question as it SHOULD be obvious that a user should only be counted if they received new values, but the docs do not mention this.
Is there a way to reload Remote Config and be confident that I
receive the latest values, taking all ongoing A/B testing
experiments into account? Imagine if I want to run a test to determine the ideal price point for my in-app purchase. I would want to reload the Remote Config and load all the latest values before I fetch my in-app products. I wouldn't want to receive default values on the first launch, present my store screen with low price level to user, only to load a more expensive version on the second launch when new values arrive from Remote Config.
It alls comes down to the criteria of your A/B test. A user will not be able to receive A/B variants UNTIL it satisfies all the test requirements. You can refetch these values at a point in your app that you know the user will have satisfied these requirements.
You can use the DebugView to see whether a specific A/B test has been activate for a user.

Has Apple fixed the CoreData + iCloud sync issues? [closed]

There has been a lot of discussion lately about the issues with iCloud and Core Data and how Apple's APIs are currently broken in iOS 5 and possibly iOS 6.
Is it possible, given the current state of Apple's Core Data API, to reliably sync across multiple devices using iCloud?
If so, how would you do this? If not, please recommend an alternative approach.
This blog post will lead you to a chain of recent articles about the travails of developers attempting this approach.
From my own understanding and experience, I believe it is doable, but don't buy into the idea that you will get anything "for free". Depending on your data model, you may be better off syncing your whole persistent store as a document rather than using the documented core data / iCloud approach.
You may have better luck if you're already comfortable with Core Data. Just be sure you think through how to handle several important cases.
One is what to do if the user signs out of their iCloud account. When this happens, the local ubiquitous persistent store is deleted. If it makes sense for the user to still have access to their data, you'll need to manage a copy in local storage, and then manage resynchronizing when they sign back in.
Another is that changes can apparently be quite slow to propagate by default, so you may want to consider an alternative mechanism, such as the key value store, to quickly propagate sufficient information to avoid a bad user experience.
Conflict management is perhaps the most challenging (depending on your model). While the framework provides a mechanism to inform you of conflicts, you are on your own for providing a mechanism to resolve them, and there are reports that the conflict notifications may not be reliable (see linked articles), which seems strongly linked to the lag in updating.
In short, if you go into this understanding that the actual support is pretty bare bones and that you'll need to code very defensively, you may have a chance. There aren't any good recipes out there, so if you do make it work, please come back and tell us what works!
It depends on what you want to do. There are two types of Core Data-iCloud integration, as described here: http://developer.apple.com/library/ios/#releasenotes/DataManagement/RN-iCloudCoreData/_index.html
There are broadly speaking two types of Core Data-based application that integrate with iCloud:
Library-style applications, where the application usually has a single persistent store, and data from the store is used throughout the application.
Examples of this style of application are Music and Photos.
Document-based applications, where different documents may be opened at different times during the lifetime of the application.
Examples of this style of application are Keynote and Numbers.
If you're using the library-type, this article is the first of a series that goes into a lot of the problems that will come up: http://mentalfaculty.tumblr.com/post/23163747823/under-the-sheets-with-icloud-and-core-data-the-basics.
You can also check out sessions 218 (for document-based) or 227 (for library-style) of this year's wwdc.
As of iOS 7, the best solution is probably the Ensembles framework: https://github.com/drewmccormack/ensembles
Additionally, there is a promising project which will essentially allow you to do the same thing using a different cloud service.
Here is a link to the repository: https://github.com/nothirst/TICoreDataSync
Project description:
TICoreDataSync is a collection of classes to enable synchronization via the Cloud (including Dropbox) of Core Data-based applications (including document-based apps) between any number of clients running under Mac OS X or iOS. It's designed to be easy to extend if you need to synchronize via an option that isn't already supported.
Reasons for why iCloud is not currently reliable:
"Sometimes, iCloud simply fails to move data from one computer to another."
"Corrupted baselines are [a] common obstacle.... There is no recovery from a corrupted baseline, short of digging in to the innards of your local iCloud storage and scraping everything out, and there is no visible indication that corruption has occurred — syncing simply stops."
"Sometimes, when initializing the iCloud application subsystem, it will simply return an opaque internal error. When it fails, there’s no option to recover — all you can do is try again (and again…) until it finally works."
"[W]hen you turn off the “Documents & Data” syncing option in the iCloud system preferences, the iCloud system deletes all of your locally stored iCloud data[.]"
When you sign out of iCloud, the system moves your iCloud data to a location outside of your application’s sandbox container, and the application can no longer use it.
"In some circumstances (and we haven’t been able to figure out which, yet), iCloud actually changes the object class of an item when synchronizing it. Loosely described, the object class determines the type of the object in the database[.]"
"In some cases (again, not all the time), iCloud may do one of the following:
Owner relationships in an item’s data will point to the wrong owner;
Owner items get lost in synchronization and never appear on computers other than the one on which they were created. (This leads to the item never appearing in the UI on any other machine.) When this happens, bogus relationships get created between blob items and an arbitrary unrelated owner."
"Sometimes (without any apparent consistency or repeatability), the associated data for an object (for example, the PDF data for a PDF item, or the web archive data for a Web Archive item) would simply fail to show up on the destination machine. Sometimes it would arrive later (much later — minutes or hours)."
Quoted and paraphrased from these sources:
http://www.imore.com/debug-12-icloud-core-data-sync
http://rms2.tumblr.com/post/46505165521/the-gathering-storm-our-travails-with-icloud-sync
Note: I have seen one article where the author mentions getting it to work for iOS 6+, but they don't provide any examples: http://zaal.tumblr.com/post/46718877130/why-you-want-to-use-core-data-icloud-sync-if-only-it
As a reference, here are Apple's docs on iCloud + Core Data:
http://developer.apple.com/library/ios/#releasenotes/DataManagement/RN-iCloudCoreData/
http://developer.apple.com/library/ios/#documentation/General/Conceptual/iCloudDesignGuide/Chapters/DesignForCoreDataIniCloud.html
http://developer.apple.com/library/ios/#documentation/cocoa/Conceptual/CoreDataVersioning/vmCloud/vmCloud.html
And here is an example app:
http://developer.apple.com/library/ios/#DOCUMENTATION/General/Conceptual/iCloud101/Introduction/Introduction.html
The Apple developer tutorial on using the iCloud API to manipulate documents might be a good place to start.
Your Third iOS App introduces you to the iCloud document storage APIs. You use these APIs to store and manipulate files in a user’s iCloud storage.

Bootstrapping data at application startup with Simperium

As someone that experienced the pain of iCloud while trying to prototype iCloud enabling one of our CoreData apps, Simperium looks very promising, but I'm interested in seeing how it handles some of the sharp edges.
One issue I came across was how to gracefully handle bootstrapping data when the application starts up. The first time a user launches our app, we will load some default data into our CoreData database. If a user launches the app first on the iPhone and then later on the iPad, they will end up getting the bootstrap data duplicated on both devices because of syncing. With iCloud, the solution was to hook into the iCloud merge process.
How would I handle this with Simperium?
There are at least a couple ways to do this.
You can hardcode the simperiumKey for each seeded object. For example, in a notes app, if every new user gets a welcome note, you can locally create that note with the simperiumKey of welcomeNote. This will ensure that only one welcome note will ever exist in that user's account (on any device). With this approach, there can be some redundant data transfer, so it's best if there's not a large amount of seeded data. On the other hand, this approach is good if you want data to be immediately available to new users even if they're offline when they first launch your app.
With Simperium, you also have the option to use a server process. You can seed new user accounts with data by using a Python or Ruby listener that runs some code when accounts are created. This is a good approach if there's a large amount of data, but has the disadvantage that users need to be online before the seeded data will transfer (and of course the transfer itself will take some time).
There are subtleties with these approaches. With the first approach, using the welcomeNote example, if your user deletes the welcomeNote and subsequently reinstalls your app in the future, the welcomeNote will get resurrected (but never duplicated) because it's being created locally. This is often acceptable. With the second approach, the welcomeNote would be seeded once and only once, so it will never get resurrected even if your app is reinstalled.

Syncing Core Data across multiple devices using iCloud

There has been a lot of discussion lately about the issues with iCloud and Core Data and how Apple's APIs are currently broken in iOS 5 and possibly iOS 6.
Is it possible, given the current state of Apple's Core Data API, to reliably sync across multiple devices using iCloud?
If so, how would you do this? If not, please recommend an alternative approach.
This blog post will lead you to a chain of recent articles about the travails of developers attempting this approach.
From my own understanding and experience, I believe it is doable, but don't buy into the idea that you will get anything "for free". Depending on your data model, you may be better off syncing your whole persistent store as a document rather than using the documented core data / iCloud approach.
You may have better luck if you're already comfortable with Core Data. Just be sure you think through how to handle several important cases.
One is what to do if the user signs out of their iCloud account. When this happens, the local ubiquitous persistent store is deleted. If it makes sense for the user to still have access to their data, you'll need to manage a copy in local storage, and then manage resynchronizing when they sign back in.
Another is that changes can apparently be quite slow to propagate by default, so you may want to consider an alternative mechanism, such as the key value store, to quickly propagate sufficient information to avoid a bad user experience.
Conflict management is perhaps the most challenging (depending on your model). While the framework provides a mechanism to inform you of conflicts, you are on your own for providing a mechanism to resolve them, and there are reports that the conflict notifications may not be reliable (see linked articles), which seems strongly linked to the lag in updating.
In short, if you go into this understanding that the actual support is pretty bare bones and that you'll need to code very defensively, you may have a chance. There aren't any good recipes out there, so if you do make it work, please come back and tell us what works!
It depends on what you want to do. There are two types of Core Data-iCloud integration, as described here: http://developer.apple.com/library/ios/#releasenotes/DataManagement/RN-iCloudCoreData/_index.html
There are broadly speaking two types of Core Data-based application that integrate with iCloud:
Library-style applications, where the application usually has a single persistent store, and data from the store is used throughout the application.
Examples of this style of application are Music and Photos.
Document-based applications, where different documents may be opened at different times during the lifetime of the application.
Examples of this style of application are Keynote and Numbers.
If you're using the library-type, this article is the first of a series that goes into a lot of the problems that will come up: http://mentalfaculty.tumblr.com/post/23163747823/under-the-sheets-with-icloud-and-core-data-the-basics.
You can also check out sessions 218 (for document-based) or 227 (for library-style) of this year's wwdc.
As of iOS 7, the best solution is probably the Ensembles framework: https://github.com/drewmccormack/ensembles
Additionally, there is a promising project which will essentially allow you to do the same thing using a different cloud service.
Here is a link to the repository: https://github.com/nothirst/TICoreDataSync
Project description:
TICoreDataSync is a collection of classes to enable synchronization via the Cloud (including Dropbox) of Core Data-based applications (including document-based apps) between any number of clients running under Mac OS X or iOS. It's designed to be easy to extend if you need to synchronize via an option that isn't already supported.
Reasons for why iCloud is not currently reliable:
"Sometimes, iCloud simply fails to move data from one computer to another."
"Corrupted baselines are [a] common obstacle.... There is no recovery from a corrupted baseline, short of digging in to the innards of your local iCloud storage and scraping everything out, and there is no visible indication that corruption has occurred — syncing simply stops."
"Sometimes, when initializing the iCloud application subsystem, it will simply return an opaque internal error. When it fails, there’s no option to recover — all you can do is try again (and again…) until it finally works."
"[W]hen you turn off the “Documents & Data” syncing option in the iCloud system preferences, the iCloud system deletes all of your locally stored iCloud data[.]"
When you sign out of iCloud, the system moves your iCloud data to a location outside of your application’s sandbox container, and the application can no longer use it.
"In some circumstances (and we haven’t been able to figure out which, yet), iCloud actually changes the object class of an item when synchronizing it. Loosely described, the object class determines the type of the object in the database[.]"
"In some cases (again, not all the time), iCloud may do one of the following:
Owner relationships in an item’s data will point to the wrong owner;
Owner items get lost in synchronization and never appear on computers other than the one on which they were created. (This leads to the item never appearing in the UI on any other machine.) When this happens, bogus relationships get created between blob items and an arbitrary unrelated owner."
"Sometimes (without any apparent consistency or repeatability), the associated data for an object (for example, the PDF data for a PDF item, or the web archive data for a Web Archive item) would simply fail to show up on the destination machine. Sometimes it would arrive later (much later — minutes or hours)."
Quoted and paraphrased from these sources:
http://www.imore.com/debug-12-icloud-core-data-sync
http://rms2.tumblr.com/post/46505165521/the-gathering-storm-our-travails-with-icloud-sync
Note: I have seen one article where the author mentions getting it to work for iOS 6+, but they don't provide any examples: http://zaal.tumblr.com/post/46718877130/why-you-want-to-use-core-data-icloud-sync-if-only-it
As a reference, here are Apple's docs on iCloud + Core Data:
http://developer.apple.com/library/ios/#releasenotes/DataManagement/RN-iCloudCoreData/
http://developer.apple.com/library/ios/#documentation/General/Conceptual/iCloudDesignGuide/Chapters/DesignForCoreDataIniCloud.html
http://developer.apple.com/library/ios/#documentation/cocoa/Conceptual/CoreDataVersioning/vmCloud/vmCloud.html
And here is an example app:
http://developer.apple.com/library/ios/#DOCUMENTATION/General/Conceptual/iCloud101/Introduction/Introduction.html
The Apple developer tutorial on using the iCloud API to manipulate documents might be a good place to start.
Your Third iOS App introduces you to the iCloud document storage APIs. You use these APIs to store and manipulate files in a user’s iCloud storage.

How to check lock status and unlock if necessary for Database on Blackberry?

Since I've started developing my Blackberry app, the biggest problems I've encountered all had to do with SQLite Databases.
Right now I'm putting my app through a stress test, and when problems pop up I address them by printing out statuses to the console and taking care of things line by line. Right now (after mashing buttons on my app) I received a "Database is locked" error and I'm not sure what to do.
It seems that once the database is locked it's locked for good until it is unlocked........ my question is how can I unlock it?? First of all, how can I check to see if it's locked??
I'm sure our users won't be mashing buttons like I did, but you never know. I want to account for every possible scenario.
Thanks
EDIT: This is what happens in my application..... When I launch it starts a thread, this thread performs a cleanup on one of my tables based on how old certain pieces of data are (uses DELETE). The thread then continues to get a USER object from my DB (read only), it then uses this USER object as a parameter to call a web service. The data retrieved from the web service is INSERTED into my database. (It's a little more complex than that as a few read/write operations are performed at this time. After that, the thread fires a callback method to update my UI.
This all works fine. I can exit the app WHILE the thread is running and relaunch and a flag will prevent it from starting a new instance of the same thread (unless the other one is done of course).
Now my problem: My app's home screen is a list of buttons, when the user clicks one of these buttons another, more detailed list is loaded (this requires a READ ONLY call to the database). When I launch the app (firing the web service calling thread) and then click a button on the main screen right away, the table gets locked. (Not always, sometimes it takes 4 or 5 tries, sometimes more, sometimes less). But if I keep doing this it WILL eventually lock making it impossible to make any calls to my DB, hence no more UI (which depends on the DB).
The DB call that populates the UI on the second screen is READ ONLY, can't I have as many of these as I need?? What causes the DB to lock?? What's the difference between a DB lock and File System error (12)??
I seemed to have fixed the problem. I was under the impression that if a read/write connection was open then a read-only connection could be created safely.
This doesn't seem to be the case. If I have a read/write connection open then no other connections can open until that one is finished.
I basically created one read/write connection, set a flag to identify it as open, and during my read connection use the same Database object if the flag is open, or create a read only if it's closed.
So far so good.
Sqlite does not support concurrent modification. In practice on BlackBerry, this means you can only open the database from one part of the code at a time. To maintain this one-at-a-time access, you need to close the database when you are done with it, as #AnkitRox points out.
However you also need to guard against concurrent access. Even if your code properly closes the database, it is possible for two different threads to access the database. In that case, you will need one to wait. In Java-ME this is typically accomplished through the 'synchronized' keyword, and using the same lock object for all database access.
Check properly that, you are opening and closing database before and after execution of query respectively.
Because if Database is going to open without closing it properly, then it gives errors.

Resources