Realm Swift Bundle Data

Realm Swift Bundle Data

When it comes to importing, the file being imported has to be in a very specific format along with a specific file name

Your Realm object name is Tree, so the imported file name needs to match

Tree.csv

along with that the first line of the file needs to match the classes property names, comma separated

id,br,nm1...

I would suggest creating a very small test file to import with 3-4 lines to get it working. Then, once you mastered that then import the big file.

How to bundle a realm file with my app in swift4.2?

Make sure that the file's "Target Membership" is correct

Target Maembership

and that the file is included in the "Build Phases/Copy Bundle Resources"

Copy bundle resource

And, yes, I've wasted hours on the is to

How to bundle a realm file

It appears that your line try Realm().writeCopy(toFile: destination) basically opens the default realm file, but without the key needed to decrypt it (I'm assuming you've already encrypted it here before attempting to write a compact copy).

Realm complains that the file can't be opened because it's not a Realm file (it's not, it's a scrambled version of it).

Open the Realm using the appropriate encryption key (try Realm(configuration: config) or similar) and then try writing a copy.

Sources

Realm Docs - Encryption

Realm Docs - Compacting Realms

Loading Data from Bundled Realm Database in Swift

The behavior you describe is what I'd expect to see if you've already opened the Realm at the target path prior to copying the bundled Realm over to that location. You can confirm this by putting a breakpoint on the Realm initializer and on your code that calls removeItemAtURL and seeing which is hit first.

Bundling a Realm with an App section

If you bundle Realm file with your app it will be stored inside your app's bundle in Resources directory which is not writeable (because of the code signing). So if you want your users be able to change this data you have to copy this file to some directory with write access. Application’s Documents directory seems to be a good choice and it's also a default directory for default Realm.Configuration.

If it's an initial data for your app and you don't want to overwrite it each time your app launches, you can simply check if destination file exists and not copy your initial database in this case.

You can do it like this:

let initialURL = NSBundle.mainBundle().URLForResource("initial", withExtension: "realm")!
let defaultURL = Realm.Configuration.defaultConfiguration.fileURL!

if (!defaultURL.checkResourceIsReachableAndReturnError(nil)) {
do {
try NSFileManager.defaultManager().copyItemAtURL(initialURL, toURL: defaultURL)
} catch {
// Handle error here
}
}

let realm = try! Realm()

How to create a pre bundled realm file and upload data to it?

We're still looking at ways to officially make generating pre-populated Realms more easy. It's definitely a desired feature for the Realm Browser, but due to the way that Realm files require a migration when changing the schema, it's somewhat tricky to incorporate into a UI. It's definitely something we want to improve down the line.

At the moment, the Browser has a converter in it that can perform minimal data import like CSV files.

The Realm documentation is saying that the easiest way for you to produce a pre-populated Realm specific for your apps needs is to build a separate macOS app whose sole role is to generate the Realm file, pre-populate the data and then expose the resulting Realm file so you can copy it to your app.

The operation to do this is just like any normal Realm interaction (try! Realm() is what causes the file to actually be initially created), except you manually interact with the Realm file on disk upon completion.

I'm working on an app for an iOS conference, and the schedule data for the event is going to be stored in a Realm that is pre-bundled with the app when it ships.

Since I thought creating an extra macOS app would be overkill for an iOS app, I instead used iOS unit tests that would generate the pre-bundled Realm from scratch every time it was executed.

class Tests: XCTestCase {
func testGenerateNewDefaultRealm() {
let sources = [conferences, sponsors, conferenceDays] as [Any]
XCTAssert(generateDefaultRealm(named: "MyConferenceRealm.realm", sources: sources))
}
}

extension Tests {
public func generateDefaultRealm(named name: String, sources: [Any]) -> Bool {
// Create and configure the Realm file we'll be writing to
let realm = generateRealm(named: name)

// Open a Realm write transaction
realm.beginWrite()

// Loop through each source and add it to Realm
for source in sources {
if let objectArray = source as? [Object] {
for object in objectArray {
realm.add(object)
}
}
else if let objectDictionary = source as? [String : Object] {
for (_, object) in objectDictionary {
realm.add(object)
}
}
}

// Commit the write transaction
do {
try realm.commitWrite()
}
catch let error {
print(error.localizedDescription)
return false
}

// Print the file location of the generated Realm
print("=====================================================================")
print(" ")
print("Successfully generated at")
print(realm.configuration.fileURL!.path)
print(" ")
print("=====================================================================")

return true
}

public func generateRealm(named name: String) -> Realm {
let exportPath = NSTemporaryDirectory()
let realmPath = exportPath.appending(name)

// Delete previous Realm file
if FileManager.default.fileExists(atPath: realmPath) {
try! FileManager.default.removeItem(atPath: realmPath)
}

// Create new Realm file at path
let objectTypes: [Object.Type] = [Conference.self, ConferenceDay.self, SessionBlock.self, Event.self, Presentation.self,
Session.self, Location.self, Speaker.self, Sponsor.self, Venue.self]
let configuration = Realm.Configuration(fileURL: URL(string: realmPath), objectTypes: objectTypes)
let realm = try! Realm(configuration: configuration)
return realm
}
}

Running this unit test will generate a new Realm file in the NSTemporaryDirectory() directory of the Mac, and then feed in a set of Array and Dictionary objects of un-persisted Realm Object instances that are created each time the test is run. The location of the final Realm is then printed in the console so I can grab it and move it to the app bundle.



Related Topics



Leave a reply



Submit