IceCream helps you sync Realm Database with CloudKit.
It works like magic!
Features
Realm Database
Off-line First
Thread Safety
Reactive Programming
Optimized for mobile apps
Easy when migrating
Apple CloudKit
Automatical Authentication
Silent Push
Free with limits(Private database consumes your user’s iCloud quota)
Delta update
Reachability(Support Long-lived Operation)
Powerful Error Handling
Sync Automatically
Multiple object models support
Public/Private Database support
Large Data Syncing
Manually Synchronization is also supported
Relationship(To-One/To-Many) support
Available on every Apple platform(iOS/macOS/tvOS/watchOS)
Support Realm Lists of Natural Types
Complete Documentation
Prerequisite
Be sure to have enrolled in Apple Developer Program
Turn on your iCloud in Capabilities and choose CloudKit
Turn on Background Modes and check Background fetch and Remote notification
Usage
Basics
Prepare your Realm Objects (e.g. Dog, Cat…):
class Dog: Object {
@objc dynamic var id = NSUUID().uuidString
@objc dynamic var name = ""
@objc dynamic var age = 0
@objc dynamic var isDeleted = false
static let AVATAR_KEY = "avatar"
@objc dynamic var avatar: CreamAsset?
@objc dynamic var owner: Person? // to-one relationships must be optional
override class func primaryKey() -> String? {
return "id"
}
}
Do stuff like this:
extension Dog: CKRecordConvertible & CKRecordRecoverable {
// Leave it blank is all
}
The sample code in AppDelegate will be a good reference.
That’s all you need to do! Every time you write to Realm, the SyncEngine will get notified and handle sync stuff!
For more details, clone the project to see the source code.
Object Deletions
Yep, we highly recommend you use Soft Deletions. That’s why we add an isDeleted property to CKRecordConvertible protocol.
When you want to delete an object, you just need to set its isDeleted property to true and the rest of the things are already taken care of.
You also don’t need to worry about cleaning-up things. It has also been considered.
How about syncing asset?
Luckily, we have a perfect solution for syncing asset.
Absolutely, you could also store your image or kind of resource stuff as Data type and everything works fine. But Realm has a 16MB limit of data property. And CloudKit encourages us to use CKAsset in places where the data you want to assign to a field is more than a few kilobytes in size.
So taking the consideration of the above two, we recommend you to use CreamAsset property to hold data. CreamAsset will store local data on the file system and just save file paths in the Realm, all automatically. And we’ll wrap things up to upload to CloudKit as CKAsset.
An example project is provided to see the detailed usage.
Relationships
IceCream has officially supported Realm relationship(both one-to-one and one-to-many) since version 2.0.
Especially, for the support of to-many relationship, you have to pass the element type of the List to the SyncObject init method parameters. For example:
syncEngine = SyncEngine(objects: [
SyncObject(type: Dog.self),
SyncObject(type: Cat.self),
SyncObject(type: Person.self, uListElementType: Cat.self) // if Person model has a List<Cat> property
])
When you are lost and don’t remember where you are, I suggest starting all over again. In CloudKit Dashboard, “Reset…” button is provided. You can also clear local database by re-install apps.
By default, IceCream only prints some logs to your console in DEBUG mode. However, you could turn it off by adding IceCream.shared.enableLogging = false if it bothers you.
Keep calm and carry on!
Warning: If you’re going to launch your app onto App Store, don’t forget to deploy your environment settings to production. You can do it easily in the CloudKit Dashboard. Write & Read permissions are also need to be considered.
One More Tip
How to debug CloudKit in production mode? See this post.
Example
To run the example project, clone the repo, then open the Example/IceCream_Example.xcodeproj.
Installation Guide
Using Swift Package Manager, Carthage or CocoaPods.
Swift Package Manager
From Xcode 11, you can use Swift Package Manager to add IceCream and its dependencies to your project.
Select File > Swift Packages > Add Package Dependency. Enter https://github.com/caiyue1993/IceCream.git in the “Choose Package Repository” dialog.
In the next page, specify the version resolving rule as “Up to Next Major” with “2.0.2” as its earliest version.
After Xcode checking out the source and resolving the version, you can choose the “IceCream” library and add it to your app target.
If you encounter any problem or have a question on adding the package to an Xcode project, I suggest reading the Adding Package Dependencies to Your App guide article from Apple.
Carthage
Carthage is a decentralized dependency manager for Cocoa applications.
To integrate IceCream into your Xcode project using Carthage, specify it in your Cartfile:
github "caiyue1993/IceCream"
Then, run the following command to build the frameworks:
carthage update
Normally, you’ll get IceCream, Realm and RealmSwift frameworks. You need to set up your Xcode project manually to add these 3 frameworks.
On your application targets’ General settings tab, in the Linked Frameworks and Libraries section, drag and drop each framework to use from the Carthage/Build folder on disk.
On your application targets’ Build Phases settings tab, click the “+” icon and choose “New Run Script Phase”. Create a Run Script with the following content:
/usr/local/bin/carthage copy-frameworks
and add the paths to the frameworks you want to use under “Input Files”(taking iOS platform for example):
For more information about how to use Carthage, please see its project page.
CocoaPods
IceCream is available through CocoaPods. To install it, simply add the following line to your Podfile:
pod 'IceCream'
If you want to build IceCream as a static framework, CocoaPods 1.4.0+ is required.
Make it better
This is the to-do list for the IceCream project. You can join us to become a contributor.
CloudKit Shared Database
See the CONTRIBUTING file for contributing guidelines.
Live Demo
My app Music Mate (The missing mate for Apple Music) is using IceCream to its fullest. You can download it and try it on your multiple devices to see this magic.
This project exists thanks to all the people who contribute:
Sponsorship
Open source is great, but it takes time and efforts to maintain. I’d be greatly appreciated and motivated if you could to support the maintenance of IceCream financially. You could sponsor this project through the below ways:
IceCream helps you sync Realm Database with CloudKit.
Features
Realm Database
Apple CloudKit
Delta update
Reachability(Support Long-lived Operation)
Powerful Error Handling
Sync Automatically
Multiple object models support
Public/Private Database support
Large Data Syncing
Manually Synchronization is also supported
Relationship(To-One/To-Many) support
Available on every Apple platform(iOS/macOS/tvOS/watchOS)
Support Realm Lists of Natural Types
Complete Documentation
Prerequisite
CloudKit
Background fetch
andRemote notification
Usage
Basics
Is that easy? Protocol Extensions do this trick.
That’s all you need to do! Every time you write to Realm, the SyncEngine will get notified and handle sync stuff!
For more details, clone the project to see the source code.
Object Deletions
Yep, we highly recommend you use Soft Deletions. That’s why we add an
isDeleted
property toCKRecordConvertible
protocol.When you want to delete an object, you just need to set its
isDeleted
property to true and the rest of the things are already taken care of.You also don’t need to worry about cleaning-up things. It has also been considered.
How about syncing asset?
Luckily, we have a perfect solution for syncing asset. Absolutely, you could also store your image or kind of resource stuff as
Data
type and everything works fine. But Realm has a 16MB limit of data property. And CloudKit encourages us to useCKAsset
in places where the data you want to assign to a field is more than a few kilobytes in size. So taking the consideration of the above two, we recommend you to useCreamAsset
property to hold data.CreamAsset
will store local data on the file system and just save file paths in the Realm, all automatically. And we’ll wrap things up to upload to CloudKit asCKAsset
.An example project is provided to see the detailed usage.
Relationships
IceCream has officially supported Realm relationship(both one-to-one and one-to-many) since version 2.0.
Especially, for the support of to-many relationship, you have to pass the element type of the List to the SyncObject init method parameters. For example:
Requirements
Debug Suggestions
It’s true that debugging CloudKit is hard and tedious. But I have some tips for you guys when facing puzzles:
IceCream.shared.enableLogging = false
if it bothers you.Warning: If you’re going to launch your app onto App Store, don’t forget to deploy your environment settings to production. You can do it easily in the CloudKit Dashboard. Write & Read permissions are also need to be considered.
One More Tip
How to debug CloudKit in production mode? See this post.
Example
To run the example project, clone the repo, then open the
Example/IceCream_Example.xcodeproj
.Installation Guide
Using Swift Package Manager, Carthage or CocoaPods.
Swift Package Manager
From Xcode 11, you can use Swift Package Manager to add IceCream and its dependencies to your project.
Select File > Swift Packages > Add Package Dependency. Enter https://github.com/caiyue1993/IceCream.git in the “Choose Package Repository” dialog. In the next page, specify the version resolving rule as “Up to Next Major” with “2.0.2” as its earliest version. After Xcode checking out the source and resolving the version, you can choose the “IceCream” library and add it to your app target.
If you encounter any problem or have a question on adding the package to an Xcode project, I suggest reading the Adding Package Dependencies to Your App guide article from Apple.
Carthage
Carthage is a decentralized dependency manager for Cocoa applications.
To integrate IceCream into your Xcode project using Carthage, specify it in your
Cartfile
:Then, run the following command to build the frameworks:
Normally, you’ll get IceCream, Realm and RealmSwift frameworks. You need to set up your Xcode project manually to add these 3 frameworks.
On your application targets’ General settings tab, in the Linked Frameworks and Libraries section, drag and drop each framework to use from the
Carthage/Build
folder on disk.On your application targets’ Build Phases settings tab, click the “+” icon and choose “New Run Script Phase”. Create a Run Script with the following content:
and add the paths to the frameworks you want to use under “Input Files”(taking iOS platform for example):
For more information about how to use Carthage, please see its project page.
CocoaPods
IceCream is available through CocoaPods. To install it, simply add the following line to your Podfile:
Make it better
This is the to-do list for the IceCream project. You can join us to become a contributor.
See the CONTRIBUTING file for contributing guidelines.
Live Demo
My app Music Mate (The missing mate for Apple Music) is using IceCream to its fullest. You can download it and try it on your multiple devices to see this magic.
Reference
Contributors
This project exists thanks to all the people who contribute:
Sponsorship
Open source is great, but it takes time and efforts to maintain. I’d be greatly appreciated and motivated if you could to support the maintenance of IceCream financially. You could sponsor this project through the below ways:
And thanks to all our backers on open collective:
License
IceCream is available under the MIT license. See the LICENSE file for more info.