Jalal Jalal -4 years ago 148
Swift Question

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.

Answer Source

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)
}
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download