All Projects → jayhickey → Cirrus

jayhickey / Cirrus

Licence: mit
☁️ Simple CloudKit sync for Codable Swift models

Programming Languages

swift
15916 projects

Projects that are alternatives of or similar to Cirrus

Cloudkitgdpr
Framework for allowing users to manage data stored in iCloud
Stars: ✭ 126 (+93.85%)
Mutual labels:  cloudkit, icloud, watchos
FacePorts
Clockology ports of all the watch faces that Apple withholds from certain watch models
Stars: ✭ 27 (-58.46%)
Mutual labels:  apple, watchos
Pomosh-iOS-watchOS
🍅Pomosh is your next awesome Pomodoro Technique assistant on 📱iOS and ⌚️ WatchOS 🙌. It's native and lightweight. Uses SwiftUI. has a nice tomato icon and also ready for macOS too🔥
Stars: ✭ 50 (-23.08%)
Mutual labels:  apple, watchos
Swiftui Charts
🚀 SwiftUI Charts with custom styles
Stars: ✭ 272 (+318.46%)
Mutual labels:  apple, watchos
aprenda-swift
Uma lista de conteúdos para você aprender Swift
Stars: ✭ 429 (+560%)
Mutual labels:  apple, watchos
TermiNetwork
🌏 A zero-dependency networking solution for building modern and secure iOS, watchOS, macOS and tvOS applications.
Stars: ✭ 80 (+23.08%)
Mutual labels:  apple, watchos
SwiftGenStrings
genstrings replacement for Swift that actually works
Stars: ✭ 29 (-55.38%)
Mutual labels:  apple, watchos
Open Source Ios Apps
📱 Collaborative List of Open-Source iOS Apps
Stars: ✭ 28,826 (+44247.69%)
Mutual labels:  apple, watchos
Flint
The Flint framework for building apps on Apple platforms using Feature Driven Development
Stars: ✭ 636 (+878.46%)
Mutual labels:  apple, watchos
Attributedstring
基于Swift插值方式优雅的构建富文本, 支持点击长按事件, 支持不同类型过滤, 支持自定义视图等.
Stars: ✭ 294 (+352.31%)
Mutual labels:  apple, watchos
flying-apple
Just to keep track of nice content and new announcements related to Apple products and Swift
Stars: ✭ 45 (-30.77%)
Mutual labels:  apple, watchos
Swiftui
A collaborative list of awesome SwiftUI resources. Feel free to contribute!
Stars: ✭ 774 (+1090.77%)
Mutual labels:  apple, watchos
Cloudkit Demo.swift
Stars: ✭ 244 (+275.38%)
Mutual labels:  cloudkit, icloud
Wells
A lightweight diagnostics report submission system
Stars: ✭ 26 (-60%)
Mutual labels:  apple, watchos
Cloudkit Demo.objective C
Stars: ✭ 133 (+104.62%)
Mutual labels:  cloudkit, icloud
concurrency-kit
🚄 Concurrency abstractions framework for Apple Platforms [Task, Atomic, Lock, Operation, etc.].
Stars: ✭ 17 (-73.85%)
Mutual labels:  apple, watchos
Swiftui Sliders
🚀 SwiftUI Sliders with custom styles
Stars: ✭ 241 (+270.77%)
Mutual labels:  apple, watchos
Ricloud
Python client for Reincubate's ricloud API. Yes, it works with iOS 14 & iPhone 12 backups!
Stars: ✭ 71 (+9.23%)
Mutual labels:  cloudkit, icloud
Synckit
Automatic CloudKit synchronization
Stars: ✭ 280 (+330.77%)
Mutual labels:  cloudkit, icloud
Rome
Carthage cache for S3, Minio, Ceph, Google Storage, Artifactory and many others
Stars: ✭ 724 (+1013.85%)
Mutual labels:  apple, watchos

☁️ Cirrus

SPM License CI

Cirrus provides simple CloudKit sync for Codable Swift models. Rather than support every CloudKit feature, Cirrus is opinionated and prioritizes simplicity, reliability, and ergonomics with Swift value types.

Main Features
🙅 No more dealing with CKRecord, CKOperation, or CKSubscription
👀 Observe models and iCloud account changes with Combine
📲 Automatic CloudKit push notification subscriptions
🚀 Clean architecture with concise but powerful API
🎁 Self-contained, no external dependencies

Usage

After installing and following Apple's steps for Enabling CloudKit in Your App:

  1. Register your app for remote CloudKit push notifications
// AppDelegate.swift
func application(
  _ application: UIApplication,
  didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
  ...
  application.registerForRemoteNotifications()
  ...
}
  1. Conform your model(s) to CloudKitCodable
import CloudKitCodable

struct Landmark: CloudKitCodable {
  struct Coordinate: Codable {
    let latitude: Double
    let longitude: Double
  }

  let identifier: UUID
  let name: String
  let coordinate: Coordinate

  // MARK: - CloudKitCodable

  /// A key that uniquely identifies the model. Use this identifier to update your 
  /// associated local models when the sync engine emits changes.
  var cloudKitIdentifier: CloudKitIdentifier {
    return identifier.uuidString
  }

  /// Managed by the sync engine, this should be set to nil when creating a new model.
  /// Be sure to save this when persisting models locally.
  var cloudKitSystemFields: Data? = nil

  /// Describes how to handle conflicts between client and server models.
  public static func resolveConflict(clientModel: Self, serverModel: Self) -> Self? {

    // Use `cloudKitLastModifiedDate` to check when models were last saved to the server
    guard let clientDate = clientModel.cloudKitLastModifiedDate,
      let serverDate = serverModel.cloudKitLastModifiedDate else {
      return clientModel
    }
    return clientDate > serverDate ? clientModel : serverModel
  }
}
  1. Initialize a SyncEngine for the model
import Cirrus

let syncEngine = SyncEngine<Landmark>()
  1. Configure the SyncEngine to process remote changes
// AppDelegate.swift
func application(
  _ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any]
) {
  syncEngine.processRemoteChangeNotification(with: userInfo)
  ...
}
  1. Start syncing
// Upload new or updated models
syncEngine.upload(newLandmarks)

// Delete models
syncEngine.delete(oldLandmark)

// Observe remote model changes
syncEngine.modelsChanged
  .sink { change in
    // Update local models
    switch change {
    case let .updated(models):
      ...
    case let .deleted(modelIDs):
      ...
    }
  }

// Observe iCloud account status changes
syncEngine.$accountStatus
  .sink { accountStatus in
    switch accountStatus {
      case .available:
        ...
      case .noAccount:
        ...
      ...
    }
  }

And that's it! Cirrus supports syncing multiple model types too, just initialize and configure a new SyncEngine for every type you want to sync.

To see an example of how Cirrus can be integrated into an app, clone this repository and open the CirrusExample Xcode project.

Installation

You can add Cirrus to an Xcode project by adding it as a package dependency.

  1. From the File menu, select Swift Packages › Add Package Dependency…
  2. Enter "https://github.com/jayhickey/cirrus" into the package repository URL text field
  3. Depending on how your project is structured:
    • If you have a single application target that needs access to the library, add both Cirrus and CloudKitCodable directly to your application.
    • If you have multiple targets where your models are in one target but you would like to handle syncing with Cirrus in another, then add CloudKitCodable to your model target and Cirrus to your syncing target.

Limitations

Cirrus only supports private iCloud databases. If you need to store data in a public iCloud database, Cirrus is not the right tool for you.

Nested Codable types on CloudKitCodable models will not be stored as separate CKRecord references; they are saved as Data blobs on the top level CKRecord. This leads to two important caveats:

  1. CKRecord has a 1 MB data limit, so large models may not fit within a single record. The SyncEngine will not attempt to sync any models that are larger than 1 MB. If you are hitting this limitation, consider normalizing your data by creating discrete CloudKitCodable models that have identifier references to each other. You can use multiple SyncEngines to sync each model type.
  2. If any child models have properties that reference on-disk file URLs, they will not be converted into CKAssets and stored in CloudKit. If you have a need to store files that are referenced by local file URLs on child models, you can override the Encodable encode(to:) and Decodable init(from:) methods on your model to set the file URLs as keys on the coding container of the top level CloudKitCodable type. The SyncEngine will then be able to sync your files to iCloud.

License

This library is released under the MIT license. See LICENSE for details.

🙌 Special Thanks

Thanks to Tim Bueno for helping to build Cirrus.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].