Seed Data From Realm Sync Configuration in UICollectionView

331 views Asked by At

So, here's my issue:

The local path for realms on iOS are located in the Documents Directory. I can open them with:

let realm = try! Realm()

Opening a sync realm is different as they are located by URLs https://realm.io/docs/swift/latest/#realms

I have a UICollectionView with a Results<Object> I can render default data to called in the AppDelegate from a separate file by writing to the Realm on launch

Separate File

class SetUpData {

// MARK: - Seed Realm

static func defaults() {

    let realm = try! Realm()

    guard realm.isEmpty else { return }

    try! realm.write {
        realm.add(List.self())
        }
    }
}

App Delegate

class AppDelegate: UIResponder, UIApplicationDelegate {

var window: UIWindow?

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

     // MARK: - Set Up Realm If Deleted

    var config = Realm.Configuration()
    config.deleteRealmIfMigrationNeeded = true

    Realm.Configuration.defaultConfiguration = config

    SetUpData.defaults()

    return true
}

From here, client-side (iOS), I am able to successfully log in (rolled my own log in but the values correspond to the Realm Object Server (ROS) admin user) and retrieve the default values from List.cell and begin writing "Lists" to my application.

However, when I configure my realm with a Sync Configuration par opening a synchronized Realm requires a User that’s been authenticated to the Object Server and that’s authorized to open that Realm, I reasonably crash in my cellForItemAtIndexPath return lists.count fatal error: unexpectedly found nil while unwrapping an Optional value because there is no initial data to return.

That makes sense. But what do I do?

Do I need to create a Realm file in the default config and migrate it to the server? I attempted to change my config to a Sync object in the App Delegate with the code below (which is what I am using in ListViewController). No dice.

private func setUpRealm() {

    let username = "\(LoginViewController().username.text!)"
    let password = "\(LoginViewController().password.text!)"

    SyncUser.logIn(with: SyncCredentials.usernamePassword(username: username, password: password, register: true), server: URL(string: "http://000.000.000.000:9080")!) { (user, error) in

        guard let user = user else {
            fatalError(String(describing: error))
        }

        DispatchQueue.main.async {
            let configuration = Realm.Configuration(syncConfiguration: SyncConfiguration(user: user, realmURL: URL(string: "realm://000.000.000.000:9080/~/realmList")!))

                    let realm = try! Realm(configuration: configuration)
                    self.lists = realm.objects(List.self).sorted(byKeyPath: "created", ascending: false)
                    self.notificationToken = self.lists.addNotificationBlock { [weak self] (changes: RealmCollectionChange) in

                        guard (self?.collectionView) != nil else { return }

                        switch changes {
                        case .initial:
                            self?.collectionView.reloadData()
                            break

                        case .update(_, let deletions, let insertions, let modifications):
                            self?.collectionView.performBatchUpdates({
                                self?.collectionView.insertItems(at: insertions.map({ IndexPath(row: $0, section: 0)}))
                                self?.collectionView.deleteItems(at: deletions.map({ IndexPath(row: $0, section: 0)}))
                                self?.collectionView.reloadItems(at: modifications.map({ IndexPath(row: $0, section: 0)}))
                            }, completion: nil)
                            break

                        case .error(let error):
                            print(error.localizedDescription)
                            break
                        }
                    }
                }
            }
        }
1

There are 1 answers

1
kishikawa katsumi On BEST ANSWER

Realm does not provide an API to convert a standalone Realm to a synced Realm currently. If my understanding is correct, it is necessary to copy the data from the seed Realm to synced Realm when opening the synced Realm.