Realm-cocoa: Calling schemaVersionAtURL before first run crashes on initialisation of realm file

Created on 23 Jul 2018  路  6Comments  路  Source: realm/realm-cocoa

Goals


Create the default.realm file successfully doing a possible verification of schema before its initialisation.

Expected Results


Create the Realm file.

Actual Results


The call to schemaVersionAtURL() returns the error Cannot open an uninitialized realm in read-only mode and the initialisation fails returning error Unable to open a realm at path '/var/mobile/Containers/Data/Application/.../Documents/default.realm': Not a Realm file.

Steps to Reproduce


Run the script below on didFinishLaunchingWithOptions.

Code Sample


var databaseOnLastVersion: Bool = false

do {
  let version: UInt64 = try schemaVersionAtURL(oldUrl)
  databaseOnLastVersion = version == SCHEMA_VERSION
} catch {
  //Database was never created, so ignore it. Will return `Cannot open an uninitialized realm in read-only mode` on error.
  print(error)
  databaseOnLastVersion = true
}

if databaseOnLastVersion {

  let configuration = Realm.Configuration(
      encryptionKey: KeychainManager.getRealmKey(),
      schemaVersion: 15)

  //Init database if possible
  do {
    _ = try Realm(configuration: configuration)
  } catch {
    LogCrashSomewhere.log(error) //Real crash
  }

  return
}

//Continue conversion from non encrypted to encrypted database.

Workaround


let configuration = Realm.Configuration(
      encryptionKey: KeychainManager.getRealmKey(),
      schemaVersion: 15)

//Try to access the non-encrypted(will crash) or create a encrypted version of Realm.
do {
  _ = try Realm(configuration: configuration)
} catch {
  print(error) //Ignore crash
}

do {
  let version: UInt64 = try schemaVersionAtURL(oldUrl)
  databaseOnLastVersion = version == SCHEMA_VERSION
} catch {
  //Old database not found
  print(error)
  databaseOnLastVersion = true
}

if databaseOnLastVersion {

  do {
    _ = try Realm(configuration: configuration)
  } catch {
    LogCrashSomewhere.log(error) //Real crash
  }

  return
}

//Continue conversion from non encrypted to encrypted database.

Version of Realm and Tooling


Realm framework version: pod 'RealmSwift', '3.7.4'

Realm Object Server version: No

Xcode version: 9.4

iOS/OSX version: Any

Dependency manager + version: Cocoapods

O-Community T-Bug T-Enhancement

All 6 comments

I guess there's two issues here:

  1. It sounds like schemaVersionAtURL() is creating an empty file if given a URL for a file that doesn't exist, and it obviously shouldn't be doing that.
  2. In Swift schemaVersionAtURL() should be UInt64? and just return nil if the file doesn't exist rather than throwing.

First should be an easy bug fix, while the second needs to wait for a major version bump as it's a breaking change.

This is an automated message
It looks like more than one label assigned to this issue belongs to the same group:
T:Bug, T:Enhancement
Please remove the appropriate labels

Is there a fix planned for this? Thanks!

@jlubeck I am still waiting for the solution, the workaround is still working.

Whats the timeline on a fix for this? The workaround seems to crash for me despite the do {} catch {} blocks

I am often wrong, so please call me out if that's the case.
However, the problem I see with this "workaround" is that it still migrates the Realm when doing this:

_ = try Realm(configuration: configuration)

How would you get the schema version of the Realm before running any migrations on it?

Was this page helpful?
0 / 5 - 0 ratings