Search code examples
swiftrealmrealm-mobile-platform

Realm default sync file


Learning how to use Realm Mobile Platform.

I built a small iOS app which successfully saves data to a server and the data is consistent across different devices. The app is very similar to the official realm tutorial.

I can open the Sync URL from the Realm Browser Mac Application and I see the changes happening fine in real time. This is where I'm stuck: I am trying to see the changes in the local realm file, but

print(self.realm.configuration.fileURL) returns nil print(Realm.Configuration.defaultConfiguration.fileURL) is an empty file

This is my code:

SyncUser.logIn(with: cloudKitCredentials, server: serverURL) { user, error in
    guard let user = user else {
        fatalError(String(describing: error))
    }

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

        self.realm = try! Realm(configuration: configuration)

        // Show initial tasks
        func updateList() {
            self.items = Array(self.realm.objects(Row.self))
            self.tableView.reloadData()
        }

        updateList()

        print(self.realm.configuration.fileURL) 
        //returns nil

        print(Realm.Configuration.defaultConfiguration.fileURL) 
        // I can open the file, but it's empty

        // Notify us when Realm changes
        self.notificationToken = self.realm.addNotificationBlock { _ in
            updateList()
        }
}

The reason I'm testing this, is so that I can load the data from the file instead of from the server. So that: (a) login will only be called once (b) data is available when the user is offline.


Solution

  • When you login for the first time Realm automatically stores the user in the keychain. You can then retrieve it via SyncUser.currentUser property and use it to open your realm even if you're offline. However if you log out the user then you won't be able to use it offline.

    realm.configuration.fileURL is not available when using syncConfiguration.


    For this case:

    1. Call SyncUser.logIn only once
    2. For normal app runs (i.e all runs except the initial run), open the realm with the same configuration.

    You should have something like this:

    // First launch
    if launchedBefore == false {
        setupRealm()
    
    // All other launches
    } else if launchedBefore == true {
        let user = SyncUser.current!
        openRealm(forUser: user)
    }
    

    openRealm(forUser: SyncUser) is basically the same as the whole dispatch block from the previous code.

    setupRealm()can call it too to clean up the code:

    SyncUser.logIn(with: cloudKitCredentials, server: serverURL) { user, error in
        guard let user = user else {
            fatalError(String(describing: error))
        }
    
        self.openRealm(forUser: user)
    }