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
and that the file is included in the "Build Phases/Copy Bundle Resources"
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
After Getting Image from Uiimagepickercontroller, Uiimageview Rotates Image for iPhone 5
Create a Weak Container in Swift That Accepts a Native Swift Protocol
Rotation Gesture Produces Undesired Rotation
Stopping Timer at Defined Amount of Time in Swift
Swift Can Not Save .M3U8 File to Gallery
Error: Argument Type Double/String etc. Does Not Conform to Expected Type "Anyobject"
How to Create a Dynamic Link in Firebase Programmatically? Swift
How to Define an Array of a Particular Enum Case in Swift
String Nil Inside Nsurlsession
Update Text in While Loop Swift
.Sink Is Not Returning the Promise Values from a Future Publisher
How to Make Mglpolylines Selectable? - Swift, Mapbox
Check Whether the Arreferenceimage Is No Longer Visible in the Camera's View