Sync Realm Database with CloudKit

Overview

IceCream

CI Status Version Carthage compatible License Platform

contributions welcome

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

  1. Be sure to have enrolled in Apple Developer Program
  2. Turn on your iCloud in Capabilities and choose CloudKit
  3. Turn on Background Modes and check Background fetch and Remote notification

Usage

Basics

  1. 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"
    }
}
  1. Do stuff like this:
extension Dog: CKRecordConvertible & CKRecordRecoverable {
    // Leave it blank is all
}

Is that easy? Protocol Extensions do this trick.

  1. Start the Engine!
var syncEngine: SyncEngine?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    ...
    syncEngine = SyncEngine(objects: [
            SyncObject(type: Dog.self),
            SyncObject(type: Cat.self),
            SyncObject(type: Person.self)
        ])
    application.registerForRemoteNotifications()
    ...
}
  1. Listen for remote notifications

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
        ])

Requirements

  • iOS 10.0+ / macOS 10.12+ / tvOS 10.0+ / watchOS 3.0+
  • Swift 5

Debug Suggestions

It's true that debugging CloudKit is hard and tedious. But I have some tips for you guys when facing puzzles:

  • You should know how Realm and CloudKit works.
  • Using GUI tools, like Realm Browser and CloudKit Dashboard.
  • 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):

$(SRCROOT)/Carthage/Build/iOS/IceCream.framework
$(SRCROOT)/Carthage/Build/iOS/Realm.framework
$(SRCROOT)/Carthage/Build/iOS/RealmSwift.framework

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 Sprint (A lightweight task management app) is using IceCream. 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.

Comments
  • Realm Lists are being destroyed by SyncEngine

    Realm Lists are being destroyed by SyncEngine

    IceCream seems like an awesome solution to Realm/iCloud! I've got sync somewhat working. However I'm having a fatal issue.

    In my situation I need Dogs to have the option to have more than one Owner. So in Realm:

    Owner: let dogList = List<Dog>()

    Dog: let owners = LinkingObjects(fromType: Owner.self, property: "dogList")

    Everything works fine in Realm. When I create a new Dog, I do this:

            realm.add(dog)
            if let owners = owners {
                for owner in owners {
                   owner.dogList.append(dog)
               }
            }
    

    Once I add the code below code however, all of my dogs get removed from their owners.

    syncEngine = SyncEngine(objects: [
            SyncObject<Owner>(),
            SyncObject<Dog>(),
            ])
    

    The dogs are still visible in Realm Studio (they still exist in Realm), but their relationship to their owner(s) has been destroyed. All of my owners show zero objects in their dogList, whereas they had nonzero objects before SyncEngine runs. Do you know why this is happening? Again this only happens when I start the SyncEngine. If I comment that out, all of my relationships are maintained in subsequent app launches.

    opened by jln19 21
  • Hangs when there are too many changes

    Hangs when there are too many changes

    My app gives the user the option to delete all his data and also to restore data from backup files.

    When erasing all data, I used realm.deleteAll(). Now that I'm using IceCream, I iterate over all my objects and set isDeleted to true.

    Then, when restoring data, I go over a different Realm database and use realm.create() to add it to the current Realm.

    Now, using IceCream, if I open my app in two devices at the same time, erase all data and then add it back from a backup file, the app will receive the cloudKitDataDidChangeRemotely hundreds of times and it'll hang forever, making it unusable and requiring me to force quit.

    In these cases I think it would be better to group multiple changes together and sync them on a background thread.

    good first issue 
    opened by dbmrq 18
  • Public database working

    Public database working

    This version appears to be working...

    Tell SyncEngine to use public database:

    let syncEngine = SyncEngine<MyObject>(usePublicDatabase: true)

    Mark objects to be stored in public database:

    extension MyObject: StoredInPublicDatabase {}

    opened by matadan 15
  • Implement background synchronization(closed by mistake)

    Implement background synchronization(closed by mistake)

    This resolves issue #88.

    I am unable to test this particular branch at the moment, as my personal fork of IceCream includes a few other changes (in order to get IceCream to work with App Groups and to fix some other sync issues. Both of which I will try to extract into PRs in the near future). I tried to extract only the background synchronization implementation. Background synchronization works wonderfully in my own project, so if I've extracted it correctly, it should work here as well.

    opened by kitlangton 14
  • Cannot find type 'ListBase' in scope

    Cannot find type 'ListBase' in scope

    Compile the project, the following code reports an error

    /// We may get List here /// The item cannot be casted as List /// It can be casted at a low-level type ListBase guard let list = item as? ListBase, list.count > 0 else { break } var referenceArray = CKRecord.Reference let wrappedArray = list._rlmArray

    opened by Mr-ZNN 13
  • New ErrorHandler class

    New ErrorHandler class

    Implemented a new class called "CKErrorHandler" to switch on the generated error code and handle any and all potential CKError.codes should they arise.

    I modified SyncEngine to use the CKErrorHandler class where appropriate.

    enhancement 
    opened by randycarney 12
  • Crash  with longLivedOperation iOS 15

    Crash with longLivedOperation iOS 15

    Good afternoon, with the arrival of iOS 15 beta 4, there was a problem during synchronization and it seems that it will not go away. When SyncEngine is initialized, the method is called resumeLongLivedOperationIfPossible, which causes the application to crash. The crane happens when trying to add longLivedOperation in container, reason:

    Terminating app due to uncaught exception 'CKException', reason: 'CKDatabaseOperations must be submitted to a CKDatabase

    I attach the library code and the place of departure

    final class PrivateDatabaseManager {
        
        let container: CKContainer
        let database: CKDatabase
        
        public init(container: CKContainer) {
            self.container = container
            self.database = container.privateCloudDatabase
        }
        
        func resumeLongLivedOperationIfPossible() {
            container.fetchAllLongLivedOperationIDs { [weak self]( opeIDs, error) in
                guard let self = self, error == nil, let ids = opeIDs else { return }
                for id in ids {
                    self.container.fetchLongLivedOperation(withID: id, completionHandler: { [weak self](ope, error) in
                        guard let self = self, error == nil else { return }
                        if let modifyOp = ope as? CKModifyRecordsOperation {
                            modifyOp.modifyRecordsCompletionBlock = { (_,_,_) in
                                print("Resume modify records success!")
                            }
                            self.container.add(modifyOp) // CRASH HERE
                        }
                    })
                }
            }
        }
    }
    
    opened by alxrguz 11
  • Zone not found, first sync fail

    Zone not found, first sync fail

    Hey guys, this library is awesome thank you for creating it.
    I've noticed that when launching the SyncEngine the first time it syncs, I get the following errors:
    "ErrorHandler.Fail: Zone Not Found: the specified record zone does not exist on the server.CKError.Code: 26".

    I checked the code and I noticed that in the init, the createCustomZones function is called after syncRecordsToCloudKit, so I believe this is why I get the errors.

    The flow I use in the app is the following:
    iCloud is disabled by default, the user can add objects to realm and use the app.
    In Settings I've a toggle to turn iCloud on, when that happens the SyncEngine gets initialized.

    At the moment as a workaround I just call syncRecordsToCloudKit after the init and that solves the problem.

    Thank you.

    opened by timefrancesco 11
  • Relationships recover but not to the original parent class

    Relationships recover but not to the original parent class

    Expected behavior

    Relationships should recover properly to the records/objects they belong.

    Actual behavior

    Relationships recover but not to the original parent class. Instead they get added to random objects and update records in CloudKit causing loss of original data.

    Steps to reproduce the problem

    • Use example to add data and sync it with CloudKit • Uninstall the app and delete all files • Reinstall app and let it recover data from CloudKit and you'll see relationships not recovering properly and get added to random objects • Visit CloudKit dashboard and you'll find that your data is now updated with new/wrong relationships

    bug 
    opened by mohitnandwani 10
  • One to Many Relationships not supported

    One to Many Relationships not supported

    First of all, let me thank you all for the awesome framework, I can't believe how easy it is to sync data with IceCream it is really like magic.

    I currently have a project where I'm using a One-to- many relationships in Realm using the List method let dogs = List<Dog>() but I tried it and IceCream does not create the right relationship in CloudKit dashboard.

    Can someone please confirm that let dogs = List<Dog>() is not supported in IceCream and that the only option would be using the LinkingObject option, let dogs = LinkingObjects(fromType: Dog.self, property: "owner")?

    Thanks a lot!

    opened by fstigre 9
  • Multiple objects support

    Multiple objects support

    Ok, here comes the big one.

    Why

    IceCream needs multiple object support, right now it can only sync one data type.

    How

    I´ve changed how SyncEngine works and now we have 2 classes:

    • SyncEngine: In charge of all the CloudKit login. Manages subscriptions, creation of zones and pushing changes to CloudKit
    • SyncSource: One for each model you want so sync. They are in charge of the Realm part. They provide required info to SyncEngine and also call SyncEngine when new changes are created in realm so they are pushed to the cloud.

    Result

    The only change is setting up the SyncEngine. Now it receives all the sources as a parameter.

    syncEngine = SyncEngine(syncSources: [
          SyncSource<Trip>(),
          SyncSource<Restaurant>()
        ])
    

    Breaking changes

    I've used the same SyncEngine name but it no longer works as it used to. We can rename the new class and still include the old SyncEngine so old users app keep working without changes or we can pack some more PR and release a big number version.

    Todo in this PR

    • [ ] Update readme

    Todo in future

    • [ ] Stop using Notification to report changes from CloudKit to the SyncEngine. We should use a method in it that users could call just passing the notification dictionary.
    • [ ] Create a new RealmDataSource that feeds the SyncSource
    • [ ] Allow that RealmDataSource to write in batches instead of with each change
    • [ ] Clean code and add tests

    What do you think @caiyue1993 , maybe there's more things to be fixed on this PR.

    opened by bitomule 8
  • deleted data cannot sync to private database

    deleted data cannot sync to private database

    There is one object defind as below.After set property is_del_force =1 at my app, I went to the CloudKit database to scan the data, the is_delete_force field of this row of data has not changed, it is still 0. Whether it is after a few minutes or a few hours, I think I need your advice, thank you!

    
    @objc dynamic var is_del_force: Int64 = 0
    
    extension User: CKRecordConvertible {
        var isDeleted: Bool {
            return self.is_del_force == 1 ;
        }
        
        // Leave it blank if you are using private database
        // For public database users, uncomment the following code:
         static var databaseScope: CKDatabase.Scope {
             return .private
         }
    }
    

    Expected behavior

    deleted data can sync to private database

    Actual behavior(optional)

    deleted data cannot sync to private database

    Steps to reproduce the problem(optional)

    opened by dong706 0
  • Cannot find type 'ListBase' in scope

    Cannot find type 'ListBase' in scope

    Hello, I am getting this error after updating to the latest version of ICream. I am using Cocoapods on Xcode 14.0, with swift 5. RealmSwift (10.8.1) IceCream (2.0.2)

    public var record: CKRecord {
           let r = CKRecord(recordType: Self.recordType, recordID: recordID)
           let properties = objectSchema.properties
           for prop in properties {
               
               let item = self[prop.name]
               
               if prop.isArray {
                   switch prop.type {
                   case .int:
                       guard let list = item as? List<Int>, !list.isEmpty else { break }
                       let array = Array(list)
                       r[prop.name] = array as CKRecordValue
                   case .string:
                       guard let list = item as? List<String>, !list.isEmpty else { break }
                       let array = Array(list)
                       r[prop.name] = array as CKRecordValue
                   case .bool:
                       guard let list = item as? List<Bool>, !list.isEmpty else { break }
                       let array = Array(list)
                       r[prop.name] = array as CKRecordValue
                   case .float:
                       guard let list = item as? List<Float>, !list.isEmpty else { break }
                       let array = Array(list)
                       r[prop.name] = array as CKRecordValue
                   case .double:
                       guard let list = item as? List<Double>, !list.isEmpty else { break }
                       let array = Array(list)
                       r[prop.name] = array as CKRecordValue
                   case .data:
                       guard let list = item as? List<Data>, !list.isEmpty else { break }
                       let array = Array(list)
                       r[prop.name] = array as CKRecordValue
                   case .date:
                       guard let list = item as? List<Date>, !list.isEmpty else { break }
                       let array = Array(list)
                       r[prop.name] = array as CKRecordValue
                   case .object:
                       /// We may get List<Cat> here
                       /// The item cannot be casted as List<Object>
                       /// It can be casted at a low-level type `ListBase`
                       -------ERROR ON THIS LINE BELOW----------
                       **guard let list = item as? ListBase, list.count > 0 else { break }**
                       var referenceArray = [CKRecord.Reference]()
                       let wrappedArray = list._rlmArray
                       for index in 0..<wrappedArray.count {
                       ---- AlSO THIS ERROR ON LINE BELOW : -- Type of expression is ambiguous without more context -- 
                           guard let object = wrappedArray[index] as? Object, let primaryKey =     object.objectSchema.primaryKeyProperty?.name else { continue }
    
    opened by wawilliams003 1
  • Generic class 'SyncObject' requires that 'String' inherit from 'RealmSwiftObject'

    Generic class 'SyncObject' requires that 'String' inherit from 'RealmSwiftObject'

    Hi all, I am using icecream library and want to achieve the following functionality.

    In app delegate, I have written

    syncEngine = SyncEngine(objects: [
                SyncObject(type: Recipient.self, uListElementType: String.self),
                SyncObject(type: SMSSchedule.self, uListElementType: Recipient.self),
                SyncObject(type: Template.self),
                SyncObject(type: ContactsGroup.self, uListElementType: Recipient.self)
            ])
    

    where Recipient class is...

    @objc class Recipient: Object {
        
        @objc dynamic var rec_id = ""
        @objc dynamic var firstName = ""
        @objc dynamic var lastName = ""
        var phoneNumbers = List<String>()
        @objc dynamic var email = ""
        @objc dynamic var colorTag = "#FFFFFFFF"
        @objc dynamic var isDeleted = false  // IceCream requirement
        
        override static func primaryKey() -> String? {
            return "rec_id"
        }
    
    // initialization code
    
    }
    

    Look at the phoneNumbers property. It is a list of string objects. However the SyncObject doesn't accept String as uListElementType. How can I solve this issue?

    opened by mibrahim025 1
  • Warning about use of private API when uploading app with Xcode 14

    Warning about use of private API when uploading app with Xcode 14

    There is a problem with Connect uploading with Xcode 14, it gives a warning "The app references non-public selectors in Payload" because same method name is now being used in private apple API. Please refer to this issue #7945 and this - PR

    Because IceCream use older version of Realm I am not sure what should be done here. I also manually changed the method name and in my case it is still havу this warning but without method name now, not sure why. However I got app approved on the app store even with this warning, but probably this is something that needs to be look into. Thank you!

    Expected behavior

    Upload build to App Store Connect without warnings.

    Actual behavior(optional)

    Warning when build is uploaded to Connect using Xcode 14

    Steps to reproduce the problem(optional)

    Upload build to App Store Connect using Xcode 14

    not related 
    opened by alexeydemidovkz 1
  • Migration not working

    Migration not working

    Below is the issue template. You can fill each part then submit your issue. Or you can just delete all of these and describe your questions in you-like style. But please remember: the more detailed info you offered, the greater possibility your problem will be solved. 😜

    Expected behavior

    1. On existed Project(yes the project is already on production), I tried to introduce IceCream to connect iCloud.
    2. So Existed data also migates to iCloud and also new data will as well.

    Actual behavior(optional)

    1. After initialized IceCream and related with it, I tried to migrate my existed realm to iCloud, but it doesn't work properly(I Could not find any on console).
            syncEngine = SyncEngine(objects: [
                SyncObject(type: MemoCollection.self, uListElementType: Memo.self),
                SyncObject(type: Memo.self, uListElementType: MemoImage.self, vListElementType: Tag.self),
                SyncObject(type: MemoImage.self),
                SyncObject(type: Tag.self),
            ], container: CKContainer.init(identifier: "iCloud.WAI.edison"))
            syncEngine?.pushAll()
    
    1. Of course newly data smoothly upload on iCloud.(Only happened on existed datas)

    Reference

    Screen Shot 2022-08-14 at 5 59 16 PM
    • As you see you can see three datas on my realm but only one data on iCloud(yes I add after initialize)

    Screen Shot 2022-08-14 at 6 01 03 PM

    opened by stareta1202 0
  • Releases(2.0.4)
    Owner
    Soledad
    no is temporary, yes is forever.
    Soledad
    Enables developers to write code that interacts with CloudKit in targets that don't support the CloudKit Framework directly

    CloudKit Web Services This package enables developers to write code that interac

    Eric Dorphy 2 Dec 27, 2021
    CodableCloudKit allows you to easily save and retrieve Codable objects to iCloud Database (CloudKit)

    CodableCloudKit CodableCloudKit allows you to easily save and retrieve Codable objects to iCloud Database (CloudKit) Features ℹ️ Add CodableCloudKit f

    Laurent Grondin 65 Oct 23, 2022
    Realm is a mobile database: a replacement for Core Data & SQLite

    Realm is a mobile database that runs directly inside phones, tablets or wearables. This repository holds the source code for the iOS, macOS, tvOS & wa

    Realm 15.7k Jan 1, 2023
    A simple order manager, created in order to try Realm database

    Overview A simple order manager, created in order to get acquainted with the features and limitations of the local Realm database. The project is writ

    Kirill Sidorov 0 Oct 14, 2021
    Simplified access to Apple's CloudKit

    EVCloudKitDao Discuss EVCloudKitDao : What is this With Apple CloudKit, you can focus on your client-side app development and let iCloud eliminate the

    Edwin Vermeer 632 Dec 29, 2022
    This is the BlurrMC social media platform for iOS hosted on Apple's CloudKit.

    BlurrMC for iOS This is the BlurrMC social media platform for IOS! WOOOOOOO! On this version of the social media platform, you have the full featured

    BlurrMC 0 Nov 4, 2021
    iForage helps foragers to track and manage foraging spots around them using CloudKit

    iForage CloudKit Preface To expand on what I've created here: https://github.com/LynchConnor/iForage, I initially developed the app using Firebase. Th

    Connor Lynch 3 Jul 14, 2022
    CoreDataCloudKitShare - Learn how to use Core Data CloudKit

    Sharing Core Data Objects Between iCloud Users Implement the flow to share data

    null 3 Feb 10, 2022
    CloudKit, Apple’s remote data storage service, provides a possibility to store app data using users’ iCloud accounts as a back-end storage service.

    CloudKit, Apple’s remote data storage service, provides a possibility to store app data using users’ iCloud accounts as a back-end storage service. He

    Yalantis 252 Nov 4, 2022
    CoreData/Realm sweet wrapper written in Swift

    What is SugarRecord? SugarRecord is a persistence wrapper designed to make working with persistence solutions like CoreData in a much easier way. Than

    Modo 2.1k Dec 9, 2022
    A library that provides the ability to import/export Realm files from a variety of data container formats.

    Realm Converter Realm Converter is an open source software utility framework to make it easier to get data both in and out of Realm. It has been built

    Realm 212 Dec 9, 2022
    Unrealm is an extension on RealmCocoa, which enables Swift native types to be saved in Realm.

    Unrealm enables you to easily store Swift native Classes, Structs and Enums into Realm . Stop inheriting from Object! Go for Protocol-Oriented program

    Artur  Mkrtchyan 518 Dec 13, 2022
    Realm GeoQueries made easy

    RealmGeoQueries simplifies spatial queries with Realm Cocoa. In the absence of and official functions, this library provide the possibility to do prox

    Marc Hervera 142 Jul 21, 2022
    Creating a Todo app using Realm and SwiftUI

    Realmで作るTodoアプリ note記事「【SwiftUI】Realmを使ってTodoアプリを作る」のソースです。

    null 1 Jul 20, 2022
    MagicData - A replacement of SQlite, CoreData or Realm.

    MagicData A replacement of SQlite, CoreData or Realm. It is very easy to use and is a light version. Guides MagicData We use MagicData manage all the

    Underthestars-zhy 20 Jul 4, 2022
    Realm-powered Core Data persistent store

    RealmIncrementalStore Realm-powered Core Data persistent store Wait, what? I like Realm. Realm's memory-mapped DB blows other databases out of the wat

    Eureka 227 Jun 24, 2022
    Realm Manager for iOS

    Microservices for RealmSwift. Split realms for easier management and migration

    Lê Xuân Quỳnh 2 Aug 13, 2022
    Listens to changes in a PostgreSQL Database and via websockets.

    realtime-swift Listens to changes in a PostgreSQL Database and via websockets. A Swift client for Supabase Realtime server. Usage Creating a Socket co

    Supabase 35 Dec 1, 2022
    WCDB is a cross-platform database framework developed by WeChat.

    WCDB 中文版本请参看这里 WCDB is an efficient, complete, easy-to-use mobile database framework used in the WeChat application. It's currently available on iOS,

    Tencent 9.6k Jan 8, 2023