I am new to ios development. I am planning to use public database of cloudkit to store user's data.
I want to set security roles such that only creator of the record can access it. No other user (even authenticated) can access (not read/write) the record. Suppose, I deploy the application and users are using it and creating records.
Now In future, while giving update to this application, if I want to change the security roles, and give authenticated users, the permission to read the records created by other users.
Is this possible? and If Yes then the records which are created earlier (before the updated version ) can now be accessed (read )by authenticated users?
Thanks in advance,
Krishna
Krishna, CloudKit doesn't work quite that way. The public zone is always public - everyone using your app can access these. If they are logged in it is possible to set it so anyone can write to the public database. The private database is where you store user specific records that only they can see. If you later want to share with other users you then use use the shared database.
This thread is on a similar topic
Designing for CloudKit is a helpful overview
This WWDC video goes into the specifics of sharing using Cloudkit
Related
I've just spent hours evaluating CloudKit's sharing features for a potential multi-tenancy app and, while I think I know the answer, I felt I should ask the community.
The use case: an app that supports multiple companies, each with its own users that can access shared data (records) within that company only. Imagine Slack's separate workspaces: a user of Company A should be able to see all of Company A's data, and maybe eventually Company A hires a new employee (user), who also should see that same data. Company B has completely separate users/data and is never seen by anyone from Company A.
The question: from my understanding so far of CloudKit, records are associated to a user, not a company/team/group. If User A (of Company A) shares a record with User B, that's totally doable and User B will see everything (including child records). But now let's suppose User A leaves the company. How does another user then take ownership of those records so that User B can continue to access the company's data?
It almost seems like each company would need to have its own iCloud account to serve as a master "owner", which feels unprofessional or challenging for non-techies to understand (and thereafter complicated for sharing with future users).
Am I thinking about this wrong? Am I already barking up the wrong tree by considering CloudKit as the backend for this app?
I think the most suitable setup for what you've described is to use a Public database in a CloudKit container. A CKRecord can be shared and "owned" however you want. The record remains available to all who can access the database.
Sharing a CKRecord via the CKShare functionality is much more limited. When sharing that way, you are simply providing a shared view into someone's Private database. If that user vanishes, the shared record goes with them and the sharing stops. Only the Public database can preserve a record independent of user status.
One caveat is that a Public database has to be owned by a single Apple Developer account. You can't share ownership across companies at the business level. But for the purposes of your app, your dev account can own the database and you can share the data with as many tenants as you want.
Let me know if you have any follow-up questions.
I'm working on an iOS app that connects with Firebase. I was wondering, if it's possible to have data that a user uploads only be accessible to him/her. The docs explained how to do this for Firebase storage, but I'm not sure how to create a similar effect for the database. Is it possible to do this, or will all data be public to all users?
Additionally, if it is possible to have the data only be accessible to the specific user, will the data still be visible to me in the database?
Thanks for your help.
What you are looking for is a concept called "security rules" with Firebase. Is it available with Realtime database and Firestore.
You can restrict access as you described and data remains available to you since you will be the administrator of the database.
The Apple docs say reads from an app's CloudKit public database can occur without an iCloud login, but writes cannot. Saving or updating records to the public database require an iCloud login.
What if you want to seed and maintain the public database as an administrator? For instance, for a map app, if you as an administrator want to populate and maintain the public database with demographic data for each country, does your flow still require an iCloud login?
If posting code snippets, Swift is preferred. Thanks.
The answer to your question is on the cloud dashboard.
This is the permissions for public database your looking at, you can make it writable as I have here for an authenticated account, so somebody logged in with their iCloud account, but there is no option to make it writable anonymously.
But I can see the confusion here, the database belongs to the app, not the user and you can make the public part writable by anybody as I have here. So in your example your maps app it would write to its public database so that other users would have access to it.
The caveat you need take care of here is the fact that the quota for the public database goes with the app's owner, you. So you don't want to put too much data there or indeed give even authenticated users the ability to upload heavy objects, cause if you do you may come unstuck with the finances. You have a quota, which gets bigger the more users you bring on board, but how that works out in the real world is a challenge to manage.
I have just gone through the cloud kit doc as in this link cloudkit but not getting clear about to modify database records for public database. As per this description in cloudkit framework.
Using Public Database, as specified in image by default data are world readable, owner writable. That means only owner can modify his data other user can only read?
Suppose, using public database, user A can access records of user B, But can user A modify records of user B in same application.
Please suggest. Thanks.
In the CloudKit dashboard you are able to change the access rights. So it would be possible to make records writable by others. You do have to be careful with this. When your app runs on a jailbroken device, then it's possible to execute methods with arbitrary arguments. This is a high security risk.
if you set your security setting within the record types on the dashboard, you can have all your public records set to be writeable by anyone without messing with the security roles.
Set Authenticated to Write
Set Creator to create.
p.s. you cannot 'world' read from the simulator, you need to be logged in on that. On the device though, you don't need to be logged in to read the public database :-) which is nice.
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.