What is the best way to sync data among a small number of users in swift? - ios

As the header indicates, I am looking for the simplest way to sync user-generated data (Integers, Booleans, NSDates, etc) among a small number of individuals (at this point, I am just thinking of sharing data between two people). Within the app, users can populate an array with instances of a custom object and this data is used to populate a UITableview. Assuming all users in the select group have synced their devices they should all see the same data in the tableview.
My original idea was to write to a json file in a shared Dropbox or Google Drive folder. After looking around online, however, I found that this method is likely to lead to data corruption. Cloudkit only allows public or private (single account) syncing, nothing in between. I have seen some posts that recommend using Parse, but that service is now on its way out.
Does anyone know of a (preferably free) way to do this?

You have several options:
CloudKit databases - CloudKit's database system has the concept of a public database which does exactly what you want. It's fairly easy to use as well, and is "free" with an Apple developer account. The only downside is that it's for Apple devices only (AFAIK).
Firebase - Google's Firebase is basically identical to CloudKit in concept and features, but runs on multiple platforms. It is tied to the Google ecosystem, so your uses all need to provide a Google account to use it, but that's a small issue these days.
Realm - from a pure usability perspective, Realm is BY FAR the easiest data storage solution I've seen on iOS. However, it's sharing functionality is currently limited, CloudKit support is scheduled but currently all there is is this. If you only need local storage for now, then definitely keep this on your list.
No matter which engine you choose, users would be limited to certain views of the data through your own code. I would suggest that you save every record with a username of the creator, and then have another table containing read/write permissions, so for instance, the entry for "maurymarkowitz" has "bobsmith,ronsmith,jonsmith". You can retrieve these entries on login and then use them as the inputs to the query-by-example both systems use for getting records.

Thanks for all of the helpful responses. I ended up using cloudkit/coredata and it serves my purpose just fine. I simply used the public option and gave each set of users who are sharing data with each other a unique identifier, which is appended to any records they upload. When a user syncs their data with the cloud the application performs a query for only those records that contain the user's identifier. This way, multiple users can sync data among themselves even though they do not share an iCloud account.

Related

What type of database should I use in diary app in ios?

It is also the first time to develop,
I want to make a diary app, but I don't know which database to use because I don't have basic knowledge of the database.
When I click on the calendar, I would like to post on that date
And I also need a picture that needs to be imported.
I can look for it even if I post this. I think it would be the fastest to ask. Thank you for reading my POST and hope everyone who reads has a nice day
Quick Answer: I would recommend persisting data on the users device instead of a cloud based database by using Core Data for the following reasons:
The content may be private or sensitive in nature, keeping it on the device is safer
Media attachments can become costly at scale, saving to device removes that burden from the developer
some cons of this route include the following:
Potential loss of Analytics by not using a cloud database such as Google Firebase
Cloud storage can be backed up in case the user loses their device (assuming they are not backed up via iCloud)
For a more thorough answer I recommend you provide more in terms of your objectives and audience.

Core Data Sync With Multiple Users

I would like to sync a core data app with a user with a different iCloud ID and I am trying to figure out the most graceful way to do this. I do not want the data to sync with all users, but want to be able to sync among family members for instance. From the research I have done, I do not think I can do that using iCloud Core Data sync because it only syncs between devices with the same iCloud ID. I have looked at this stackoverflow answer and read a little bit about Ensembles, Parcelkit and TICoreDataSync, Parse etc., but it is not clear to me if any of those options will allow me to sync with multiple users. Does anyone have a good method for syncing a Core Data app with multiple users?
Ensembles and TiCoreDataSync might work. They can use Dropbox file syncing, so in principle they should work with Dropbox shared folders. I don't think these are the main intended uses, so I suggest contacting the developers and/or doing some good testing yourself before assuming this would actually work.
You'll need to think about the user experience, though. At a minimum, your users would both need Dropbox accounts and would have to set up a shared folder before beginning to sync data this way.
Parcelkit probably won't work. It uses Dropbox's data store API which, unlike other Dropbox services, doesn't appear to support shared data.
Services that do support this kind of sharing exist-- for example, Parse and Firebase-- but make sure to review their pricing carefully before using them. Also of course, there have been any number of projects that have their own custom server back end, but that obviously requires having someone on the team who can do that kind of work.
You need to think about other device types (Android at least) if you want your application to be reaching more users.
I'm doing the same now by the following way:
Setup an online database with proper web services (careful with implementation for security matters - DB should NEVER be exposed by anything other than the web services).
Create a Class for your communication with the server (using Class methods with security handling like authentication and authorisation).
Use the class in your app to communicate with the server (SQL operations are done on the server).
To integrate with CoreData you need to create the model in your app similar to the structure in the backend database. Then you need to create a similar class for the app that deals with only local CoreData.
A higher level class might be required if you want to make sure that operations done on both server and local data storage.
Besides, you have to implement a lot of conditions to make sure that data written in local ONLY after making sure that it is stored online (or create an engine for differed operations to run later).
Another Way if you are familiar with notifications:
Use structured notifications between devices for data operations in order to keep everything in sync with other users. The problem with this is the "Autonomy" of the operations. If two operations were done in approximately the same time, you have to find a way to make sure the order of the operations is done properly (maybe timestamp or something).
I'm looking into the same thing for my app and I 'think' you can do a fairly unsecured version of what you are after using using the public folder in cloud kit as mentioned in this question (no accepted answer at time of posting) : Private data sharing using CloudKit
You would need to find a way to differentiate between data that is truly public and those shared among the users you need and some level of authentication.
I'm going to try exporting a permission file with access permission in it to whomever I want to share with combined with a unique identifier located in that permission file.
Keep in mind, as mentioned in the comments of the linked answer, my implementation will be security by obscurity (thanks for that phrase) unless you find a way of adding proper validation to it but my data is relatively insensitive.
Hope this, or any ridicule in the comments, points you in the right direction : )

Simperium multiple users accessing data

In the Simperium documentation/help section there is the following text:
All the data that is created seems like it must be tied to a user - is
that correct? Is it possible to have data that isn't tied to a user -
say a database of locations or beers?
Yes, though this isn't very clear yet. You can create a public user
(i.e., a public namespace) with an access token you share with other
users of your app so anyone can read/write to that namespace.
It's possible to limit this to read-only access as well if you need to
authoritatively publish data from a backend service.
Is there an actual example with this?
The scenario I have is as follows
My app will have a calendar
The primary user can add and remove data from the calendar
They will want to invite other users to add and remove data, my thought is that they can give them a token, the user can use their email address and this token to sign in
Am I on the right track?
You're definitely on the right track, but a little too far ahead on that track. The scenario you described is a great fit for Simperium, but sharing and collaboration features aren't yet released.
The help text you quoted is for authoritatively pushing content, for example from a custom backend to all users of your app. An example of this would be a news stream that updates on all clients as new content is added.
This is quite different than sharing calendar data among a group of users who have different access permissions, which is actually a better use of Simperium's strengths. We have a solution for this that we've tested internally, but we're using what we've learned to build a better version of it that will be more scalable for production use.
There's no timeline for this yet, but you'll see it announced on your dashboard at simperium.com.

One way sync with Core Data

I am about to build an internal-only iOS app for storing simple business data. The data store will consist of a single entity only, with one entry per day. To start with there will be around two years worth of data (~750 entries).
I want to set the app up to do one-way syncing only. i.e. Only one person can enter data, but others can read it. iCloud is out as it only works for a single user account.
Is there a lightweight way to sync this datastore out from the single write user to the other read users? Setting up a full sync system seems overkill for this case.
Instead of iCloud, you could use one of the online backends such as Parse.com or Simperium. They would allow you to share data using a db and also provide for user accounts, authentication etc. If you want to run the server locally you can investigate DataKit.

Can I share CoreData on iCloud?

I have an iPhone app I'm writing that needs to keep an offline data store that users of a specific licensed app can access.
I need a "Cloud" account where several users with different accounts can share the data. Is this possible?
I Googled and searched SO, but can find nothing about this particular topic.
An iCloud account is tied to a single user.
If you are asking whether you can set up an iCloud account that can be shared across multiple users; there isn't such a thing.
If you don't want to be responsible for syncing and vending the data yourself, have a look at Dropbox - where users can set up shared dropbox folders to do something similar to what you are asking about.
However, just putting the CD store on a Dropbox folder won't be enough to handle merge conflicts if different users modify the same value. In which case one solution is to have a web service that updates can be sent to, merges resolved, and the data pushed back down to the devices to be stored in their own Core Data stores.
A bit more involved than just putting the store in the cloud - but this stuff is difficult.
you need to start off with icloud
one of the best tutorials on net is:
http://www.raywenderlich.com/6015/beginning-icloud-in-ios-5-tutorial-part-1
http://www.raywenderlich.com/6031/beginning-icloud-in-ios-5-tutorial-part-2
sample icloud project
http://cdn3.raywenderlich.com/downloads/dox.zip
best of luck

Resources