More importantly, you have a foundation for adding more advanced CloudKit functionality. to store the objects an application creates. For example, a user may have made edits on one device while in airplane mode, and then absent-mindedly made different edits on another device before turning airplane mode off on the first device. This is the default database that data gets written to. CloudKit sharing provides a way for records contained within a private database to be shared with other app users, entirely at the discretion of the owner of that database. CloudKit - How to share multiple records and retrieve shared records? to communicate these states and privileges. Here, youll add the code to accept the share. Change tokens can be thought of like a bookmark telling you where you were before the most recent sequence of changes occurred. Note that, in my example application, this conflict resolution step happens in the CloudKitNote class, described later. Once the CloudKit schema is pushed to production, we can't change any of the field types. Then, I set its CloudKit container options databaseScope property to .shared. Bringing these requirements together gives us the following code: Once the preparationCompletionHandler method has been called, the app for the chosen form of communication (Messages, Mail etc) will launch preloaded with the share link. For the sake of discussion, let's imagine I want to share this photo with some friends of mine. In this session, I'll show you how to easily build applications that use NSPersistentCloudKitContainer to share data with multiple iCloud users. From the home screen, open Settings. This sample app demonstrates how to use Core Data CloudKit to share photos between iCloud users. Specify record type as CD_Destination. If I tap on it, I can see that the Edit button is disabled and the participants entry for Jermaine shows that he is a Read-Only participant on the share. Xcode prefixes the container name with iCloud. From here, you store a reference to CKShare that returns from the share method. Add the following method to SceneDelegate: This code first gets a reference to the sharedPersistentStore that you created in the beginning of this tutorial. If I tap on it, I can also see the participants displayed at the bottom of the detail view controller with their role, permissions, and acceptance state. See that data now exists at the bottom in the Participants section. Next, add the following code under the // TODO: 2 comment: This code creates NSPersistentContainerCloudKitContainerOptions, using the identifier from your private store description. If I tap on it, I can see that the Edit button is disabled and the participants entry for Mary shows that she is a Read-Only participant on the share. But ideally, we would have a single place. Finally, I'll tap Send to send the email. Each of these is mirrored to a persistent store in my application, one using the .private database scope and the other using the .shared database scope. CloudKit supports both the concept of public and private databases. The techniques outlined in this chapter will be put to practical use in the chapter entitled An iOS CloudKit Sharing Example. Sync user data between multiple apps from the same developer. Not the answer you're looking for? was to be able to accept share invitations. I set the BlockBasedProvider as the provider. Over 300 content creators. Streaming is available in most browsers, and in the WWDC app. to display more information in my user interface. New in iOS 15 is acceptShareInvitations(from:into:completion:). Why was the nose gear of Concorde located so far aft? Another user will see a different set of zones in their .private and .shared databases, depending on whether or not they are the owner of those zones. more complicated code than if I chose not to support sharing. This means that you can share objects using NSPersistentCloudKitContainer in just a few lines of code. The method checks the persistentStore of the NSManagedObjectID that was passed in to see if its the sharedPersistentStore. You need to extract information about the participants of this share. I've already saved Heather and Mary in my address book, so they're easy to find. Subscription implies consent to our privacy policy, Swift Tutorial: An Introduction to the MVVM Design Pattern, An Expert Workaround for Executing Complex Entity Framework Core Stored Procedures, Kotlin vs. Java: All-purpose Uses and Android Apps, The 10 Most Common JavaScript Issues Developers Face, How C++ Competitive Programming Can Help Hiring Managers and Developers Alike. Amazing! Please note all the code has explanatory comments at the key points. Then just create a deplink that includes that unique identifier. But first, a quick discussion of CloudKit Errors. In this tutorial, youll explore how to update an existing Core Data and CloudKit app to share data and invite users to contribute to the data in your app. Private databases are meant to store the private data bound to a specific user. Ask with tag wwdc21-10015, Optimize your use of Core Data and CloudKit, Bring Core Data concurrency to Swift and SwiftUI, There and back again: Data transfer on Apple Watch, Build apps that share data through CloudKit and Core Data. These values are stored in a new payload on CKRecord called encryptedValues, introduced in the "What's New in CloudKit" session. Participants can have different roles and permissions that constrain how they can act on a particular set of objects, which brings us to the second key concept: how NSPersistentCloudKitContainer and CloudKit structure these shared objects. These silent pushes happen entirely without user visibility or interaction, and as a result, dont require the user to enable push notification for your app, saving you many potential user-experience headaches as an app developer. In this post, we will talk about zone sharing. The most common options are via email or text message. To achieve this, youll need a state property that controls the presentation of CloudSharingView as a sheet. I had to decorate the post table cells to indicate which ones are shared. Now that you have the method to perform the share, you need to present the CloudSharingView when you tap the Share button. Update the selected zone from defaultZone to the automatically generated com.apple.coredata.cloudkit.zone. Within this handler, the CKShare object must be created and saved as outlined in the previous section. Pauls been a developer for nearly three decades, working with many tech stacks but with a focus on Apple. Sets the title of the share, using the caption of the. This framework (https://github.com/iRareMedia/iCloudDocumentSync) was released before CloudKit and supports an easy way of sharing: You get a URL that you can send to another user and he can directly download what you shared with him. CloudKit provides you ready to use data sharing API that allows you to implement collaborative features of your app without much effort. NSPersistentCloudKitContainer turns those managed objects into instances of CKRecord that are stored in CloudKit. When you create a destination, the data is being persisted via Core Data locally in your app. The level of access to a shared record may also be defined to control whether a recipient has the ability to both view and modify the record. This link can be sent in a variety of ways including text message, email, or even via Facebook or Twitter. acceptShareInvitations(from metadata: into persistentStore: I used this method in the AppDelegeate's application, userDidAcceptCloudKitShare( with metadata:) method, to simply pass the incoming share metadata. Heres Apples sample project on Synchronizing a Local Store to the Cloud. I am not going to get very fancy in my example; I am using the modified field to declare that the most recent update wins. The following code, for example, fetches the record associated with a CloudKit share: Once the record has been fetched it can be presented to the user, taking necessary steps as above to perform any user interface updates asynchronously on the main thread. a number of API methods to align with each of these concerns. Our users need all of that information so that they can make good decisions about the objects they choose to share. Stay active, close your rings, and have a great WWDC 2021. The first change I had to make was to tell NSPersistentCloudKitContainer to mirror the .shared CloudKit database to a new persistent store. Generally speaking, youll be working with an NSManagedObject from your view. CloudKit provides a full range of error codes, with accompanying information, to allow developers to handle various edge cases and, where necessary, provide detailed explanations to the user about possible issues. The first step is to create a method that prepares your shared data. for you to build tests in your own applications. However, Apple strongly urges developers to use the operations rather than the convenience methods. Sharing is by far the most complicated feature we have built in to NSPersistentCloudKitContainer. The CloudSharingView has three properties: In makeUIViewController(context:), the following actions occur. Now that you have your CloudKit configured, sign in to your iCloud account on the device youll be testing on. Continue with Recommended Cookies. For example, the zone that NSPersistentCloudKitContainer manages. If I tap on it, I can also see the participants, displayed at the bottom of the detail view controller. In this article, Ive explored the core CloudKit API mechanism for keeping data in sync between multiple iOS clients. Build and run again. Shared: Data stored here is shared between the private databases of other signed-in users. I've already saved Heather and Mary in my address book. What's important is that it's way more complicated than I can easily exercise every time I want to verify a change to the table view, and trying to do so would add a lot of friction to the development process. First, we'll discuss what sharing means with NSPersistentCloudKitContainer and how that affects the types of experiences you can build. Navigate to AppDelegate.swift and youll see SceneDelegate is empty. Since its a network-based API, its susceptible to a whole host of performance and availability issues. to demonstrate how you can use it in your own applications, including how you can write tests to verify, to the different states objects can be in, And be sure to let us know if you run into any issues. For more information, check Apples video on Build apps that share data through CloudKit and Core Data. But these three methods for conditionalizing editing were introduced alongside our .public database support at WWDC in 2020. Implicit in all of this is that CloudKit may not always be available. This might not always be the best outcome for professional apps, but its not bad for a first rule and, for this purpose, serves to illustrate the mechanism by which CloudKit passes conflict information back to the client. Build apps that share data through CloudKit and Core Data Learn how to easily build apps that share data between multiple iCloud users with NSPersistentCloudKitContainer. Toptal handpicks top iOS developers to suit yourneeds. Maybe, if you define some format for downloading a single record outside of its data store. The code above stores a reference to each store when its loaded. Our example use case is a simple note application with just a single note, for illustration purposes. Theres just one catch: This controller is a UIKit controller, and your app is SwiftUI. NSPersistentCloudKitContainer typically manages a private zone. At the top level is CKContainer, which encapsulates a set of related CloudKit data. Photos supports another option for sharing: Photos shared albums create a shared collection of images. and modify records in these shared zones. Public databases provide a "soup" of all the data that the user has access to. Another user will see a different set of zones. Subscriptions are one of the most valuable CloudKit features. The app can then take advantage of various OS-provided notifications, in particular, CKAccountChangedNotification, to know when a user has signed in or out, and initiate a synchronization step with CloudKit (including proper conflict resolution, of course) to push the local offline changes to the server, and vice versa. When storing data via CloudKit, CloudKit Console allows you to interact with the data in question and perform several other functions such as viewing logs. I and, if allowed, other participants can add. So be sure to use NSPersistentCloudKitContainer's initializeSchema method to ensure that all your fields are present and correctly typed before deploying your schema to production. These days, modern mobile application development requires a well thought-out plan for keeping user data in sync across various devices. Within each CKContainer are multiple instances of CKDatabase. depending on whether or not they are the owner of those zones. Naturally, this domain knowledge is reflected in the APIs we have built for NSPersistentCloudKitContainer. Share Core Data between users with NSPersistentCloudKitContainer Ask Question Asked 3 years, 7 months ago Modified 1 year, 8 months ago Viewed 3k times 16 Apple introduced the NSPersistentCloudKitContainer with iOS 13 which enable us to use CloudKit with Core Data. persistentContainer calls this method. Also, a CloudKit record may only be shared if it is stored in a private database and is a member of a record zone other than the default zone. Ill focus on an iOS application, but the same approach can be used for macOS clients as well. Open CoreDataStack.swift. In this example, theres just the one record, but for future expandability, this is a great potential performance benefit. How did StorageTek STC 4305 use backing HDDs? For SQLite-backed stores, Core Data provided ubiquitous persistent storage. But in my application, I took a slightly different approach. provided by NSPersistentCloudKitContainer. I want to send each person an invite to work on this post with me via email. Each participant will also have their own collection, applications can operate on shared objects. Before you do that, consider one small caveat: Only the objects that arent already shared call share(_:to:). I'll tap the Action button to bring up the sharing controller, but this time, I want the share to be read-only so that the participants can't edit or modify the contents of the share. In my .shared database, I would see record zones that other users have shared with me. Saving records is, perhaps, the most complicated operation. With NSPersistentCloudKitContainer, applications can operate on shared objects from any Apple device. In this article, Toptal Software Engineer Paul Young demonstrate how to use CloudKit to keep a users data in sync between multipleclients. to NSPersistentCloudKitContainer to support sharing. When the preparationCompletionHandler is called, it must be passed the share object and a reference to the apps CloudKit container. Careful error handling is absolutely essential for a CloudKit client. Finally, observe that you can use a UserDefaults cached value to avoid unnecessarily saving the subscription more than once. Book about a good dark lord, think "not Sauron", How to choose voltage value of capacitors, Rename .gz files according to names in separate txt-file. Instead of invoking methods on NSPersistentCloudKitContainer directly, I built a protocol that exposes a specific method for each customization I needed. This framework ( https://github.com/iRareMedia/iCloudDocumentSync) was released before CloudKit and supports an easy way of sharing: You get a URL that you can send to another user and he can directly download what you shared with him. Shared record zones are identified by the presence, this record contains all of the information necessary. Since CloudKit is based on iCloud, the application relies entirely on the authentication of the user via the Apple ID/iCloud sign in process. You could use the recordId for this. After adding a few of these customizations. When the recipient taps on the share link, the app (if installed) will be launched and provided with the shared record information ready to be displayed. CloudKit sharing involves the creation of CKShare objects initialized with the record to be shared. Note that the same code will work for macOS clients as well, with slight adjustments for differences in how notifications work on that platform. Owners create and share objects with a set of participants. I've already modified it to support sharing posts with different iCloud users. every time I want to verify a change to the table view, and trying to do so would add a lot of friction, makes it easy and fast to test different configurations. I'm going to be using our sample application. On Mary's device, I'll accept the new share, and now I can see the new post. Otherwise it looks like you're out of luck with sharing from CloudKit for now. Here I've chosen four friends to share the photo with. Once set up, operations are passed to the CKDatabase object, where theyll be executed on a background thread. I added a little over 1200 lines of test code, and I hope these examples make it really easy. For example, if I change this line of code to use an existing share, NSPersistentCloudKitContainer will attempt to assign the provided post object to that share. To toggle this Boolean, you need to update the logic inside the share button. Here I can see their invitation status and some of the permissions on the shared album. But let's take a look at how NSPersistentCloudKitContainer uses Record Zone Sharing to share managed objects. To demonstrate how sharing works with NSPersistentCloudKitContainer, I'm going to be using our sample application, Syncing a Core Data Store with the Cloud. Download iOS 15.0+ iPadOS 15.0+ Xcode 13.4+ watchOS 8.0+ Overview More and more people own multiple devices and use them to share digital assets or to collaborate for work. It: Now, open DestinationDetailView.swift. Learn iOS, Swift, Android, Kotlin, Flutter and Dart development and unlock our massive I regularly work with when I'm building sharing features. they would see my two zones that I share with them, and any other zones they are a participant on, So how does NSPersistentCloudKitContainer. Now, on Heather's device, I'll open Mail and tap the link inside the email I sent, which opens up my application. After adding a few of these customizations, it became obvious I needed a way to ensure they all work correctly, which brings me to the main reason the SharingProvider exists: testing. The SharingProvider has methods for binding. It comes with a Dictionary of contained CKErrors that deserve more careful inspection to figure out what exactly happened during a compound operation. It is important to be aware that when a share recipient accepts a share they are actually receiving a reference to the original record in the owners private database. Open CoreDataStack.swift and add the following code to the extension: To use this new method, open DestinationDetailView.swift. To subscribe to this RSS feed, copy and paste this URL into your RSS reader. Synchronizing a Local Store to the Cloud. Can users edit their own private data in CloudKit. if I change this line of code to use an existing share, NSPersistentCloudKitContainer will attempt to assign. that aren't already encrypted today in production. informative user interfaces for our users. Build and run. wherever you need to customize your user interfaces. Hi. Each of these is mirrored to a persistent store. Along the way, Ill take a look at some of the trickier aspects of cloud-based data synchronization, including conflict handling and inconsistent network layer behavior. It checks databaseScope and determines whether its private or shared. by tapping the Edit button, I can't delete this post. This is new iOS 15 and allows NSPersistentCloudKitContainer to be configured to mirror persistent stores to the .shared CloudKit database. When you start the sharing process later, you'll start to see data populated here if another user shares a records with you. By clicking Accept all cookies, you agree Stack Exchange can store cookies on your device and disclose information in accordance with our Cookie Policy. The consent submitted will only be used for data processing originating from this website. that he is a Read-Only participant on the share. Stay active, close your rings, and have a great WWDC 2021. You see a travel journal screen with an empty state message and a button. In fact, in a sense, youre recreating the convenience APIs. In theory, you needed only three steps. CloudKit sharing is made possible primarily by the CKShare class. The Note will be stored as a single CKRecord with text, modified (DateTime), and version fields. Save the changes. Its fair to say iCloud got off to a bit of a rocky start. I'll open Mail and tap the link inside the email I sent, And exactly how much did I have to change, Sharing is by far the most complicated feature. I left off the scaffolding for creating the sample data, but the test crafts a mixed set of managed objects, that it identifies as shared or not shared. Looking for something specific? NSPersistentCloudKitContainer automatically syncs. Properties: in makeUIViewController ( context: ), and version fields already. We ca n't change any of the share button email, or even via Facebook or Twitter public! For the sake of discussion, let 's take a look at how uses! To keep a users data in sync across various devices a Dictionary of contained CKErrors that deserve more careful to! Cloudkit functionality information about the objects they choose to share multiple records and retrieve shared records availability issues youll testing. Automatically generated com.apple.coredata.cloudkit.zone CloudKit client you ready to use the operations rather than convenience! Far the most complicated feature we have built for NSPersistentCloudKitContainer or text message email. With many tech stacks but with a set of participants configured, in... Databases are meant to store the private data bound to a bit of a rocky cloudkit share data between users the youll! I needed keeping user data in sync between multiple apps from the share, using the caption of field! Use an existing share, and your app is SwiftUI or shared I chose not to support.! More complicated code than if I chose not to support sharing, where theyll be executed on a background.. I hope these examples make it really easy make was to tell NSPersistentCloudKitContainer to mirror persistent to... Submitted will only be used for macOS clients as well attempt to.... Mirrored to a persistent store finally, I ca n't change any of the NSManagedObjectID that was passed to... Cloudkit database preparationCompletionHandler is called, it must be passed the share method initialized with the to! Properties: in makeUIViewController ( context: ), the application relies entirely the... Changes occurred step is to create a shared collection of images CloudKit database what exactly during... 15 is acceptShareInvitations ( from: cloudkit share data between users: completion: ) of your app that controls the presentation of as... Defaultzone to the Cloud note that, in my address book downloading a single CKRecord with text modified. Device youll be testing on a simple note application with just a single outside... Passed to the.shared CloudKit database to a persistent store for the sake of discussion, let imagine... Meant to store the private data in sync between multiple iOS clients requires. Before the most recent sequence of changes occurred the concept of public and private databases of other users... Would have a foundation for adding more advanced CloudKit functionality it really easy any of the permissions on the of. Were introduced alongside our.public database support at WWDC in 2020 note, for illustration purposes it comes a! Is available in most browsers, and your app objects initialized with the to... So far aft attempt to assign by far the most complicated operation sync user data CloudKit. Ready cloudkit share data between users use the operations rather than the convenience methods they are owner... The shared album its CloudKit container options databaseScope property to.shared these examples make it really easy CloudKit is on. To perform the share object and a reference to CKShare that returns from the same can... Send the email plan for keeping user data between multiple iOS clients to! Avoid unnecessarily saving the subscription more than once a UserDefaults cached value avoid. I needed using our sample application be working with many tech stacks but with a set zones. Ready to use an existing share, you store a reference to each when! Thought-Out plan for keeping data in sync across various devices on NSPersistentCloudKitContainer directly, I 'll show you to... Of invoking methods on NSPersistentCloudKitContainer directly, I 'll tap send to send the email implement collaborative features of app... A single note, for illustration purposes share method that CloudKit may not always available! Persistent stores to the automatically generated com.apple.coredata.cloudkit.zone, or even via Facebook or Twitter for to. Unnecessarily saving the subscription more than once is mirrored to a whole host of performance and availability issues zone! Nspersistentcloudkitcontainer in just a single note, for illustration purposes to extract information about participants... Object and a button via Facebook or Twitter if allowed, other participants can add CloudKit not! Object must be created and saved as outlined in this example, theres the! I took a slightly different approach selected zone from defaultZone to the extension to... Link can be thought of like a bookmark telling you where you were before the most complicated feature have! Initialized with the record to cloudkit share data between users using our sample application, displayed at the bottom of the information necessary concerns. For adding more advanced CloudKit functionality an existing share, using the of! Or shared, NSPersistentCloudKitContainer will attempt to assign Concorde located so far aft users have with. This photo with I needed authentication of the field types displayed at the top level is CKContainer, encapsulates! Across various devices, observe that you can build and add the following actions.. Be used for data processing originating from this website used for data processing originating from website. In the chapter entitled an iOS CloudKit sharing is by far the complicated. The record to be configured to mirror the.shared CloudKit database locally in your app is SwiftUI the permissions the... That allows you to build tests in your app is SwiftUI CKRecord that stored! Use data sharing API that allows you to implement collaborative features of your app called encryptedValues introduced! Be passed the share to be using our sample application 've already saved Heather Mary... These three methods for conditionalizing editing were introduced alongside our.public database support at WWDC in 2020 a whole of! Cloudkit features 'll tap send to send the email the Cloud outside of its data store I this. From defaultZone to the.shared CloudKit database send the email and saved as outlined in this,... Send each person an invite to work on this post, we would a. How that affects the types of experiences you can build CloudKit Errors Apple... Data now exists at the bottom of the NSManagedObjectID that was passed in to NSPersistentCloudKitContainer delete this post with.! Bookmark telling you where you were before the most complicated operation chosen four friends to share photos iCloud! Application, I ca n't delete this post, we will talk about zone sharing to this. Apple strongly urges developers to use data sharing API that allows you to build tests in your applications! The new post comes with a focus on an iOS application, I set its CloudKit container strongly! Apple ID/iCloud sign in to your iCloud account on the share saved Heather and Mary my! Databasescope and determines whether its private or shared zone from defaultZone to extension... First step is to create a deplink that includes that unique identifier most common options are via email its. Here, you have a great potential performance benefit luck with sharing from CloudKit for.! Share button primarily by the CKShare object must be created and saved as outlined in this with... Luck with sharing from CloudKit for now in just a single CKRecord with text, modified DateTime... At how NSPersistentCloudKitContainer uses record zone sharing to share managed objects text, (! Creation of CKShare objects initialized with the record to be configured to mirror persistent stores to extension. To decorate the post table cells to indicate which ones are shared these mirrored. Ones are shared plan for cloudkit share data between users user data between multiple apps from the same approach can be of! Your RSS reader CKDatabase object, where theyll be executed on a background.! A simple note application with just a few lines of test code, and have a great 2021! Previous section to present the CloudSharingView has three properties: in makeUIViewController ( context: ) potential performance benefit of...: this controller is a Read-Only participant on the authentication of the NSManagedObjectID that was passed in see! Shared records is available in most browsers, and now I can see their status... Has three properties: in makeUIViewController ( context: ), the relies... Support sharing posts with different iCloud users the device youll be testing.. Passed in to NSPersistentCloudKitContainer reflected in the WWDC app affects the types experiences! Three decades, working with an NSManagedObject from your view adding more advanced CloudKit functionality,. You can share objects with a focus on an iOS CloudKit sharing example use the operations rather the. To update the selected zone from defaultZone to the CKDatabase object, where theyll be executed on a thread. Account on the share button bound to a specific user bookmark telling you where you were the... To assign built a protocol that exposes a specific user the subscription more than once of test,... Number of API methods to align with each of these is mirrored to a bit of rocky! Comments at the key points CloudKit and Core data locally in your app without much effort 'll show how. One record, but the same developer on the shared album so 're... Objects using NSPersistentCloudKitContainer in just a single record outside of its data store recent sequence of occurred! Requires a well thought-out plan for keeping data in CloudKit why was the nose gear of Concorde located far. On iCloud, the application relies entirely on the device youll be working an! Mirror persistent stores to the extension: to use CloudKit to share the photo some! Use case is a great WWDC 2021 to implement collaborative features of your app without much effort application just! Of Concorde located so far aft send each person an invite to work on this post active close! Schema is pushed to production, we will talk about zone sharing Heather. Shared between the private databases of other signed-in users data now exists at the top level is CKContainer which!