Install Realm in a Swift App

Install Realm in a Swift App

I have been talking with the guys at Realm, and it turns out that the latest instructions don't work with Realm <= 0.85 They changed they way the build the framework and it won't work anymore. They said they will release 0.86 later today that should fix the problems anyone is having with Swift. In the meantime I have a test project that anyone can take the latest framework from. https://github.com/smitt04/testRealm

Version 0.86 is now out and this is no longer an issue.

How can I install realm cocoa converter for swift into my app project

I'm the creator of the Realm Cocoa Converter. :)

At the moment, the converter only works for OS X apps, since it was designed to be integrated into the Realm Browser. So if you're looking at integrating it into iOS apps, it's not set up for that yet. We're looking at adding iOS support to it as soon as we can, but we're very busy on a few other things at the moment.

Aside from that, if you're running an OS X app, like Dejan said, you can install it via CocoaPods, or manually drag and link the dynamic framework into your app project.

How to create initial Realm objects that get added upon installation of app

"What should I do if I wanted to have some initial objects that get added to the database just once upon installation/update of the app?"

One option would be to have some code near the realm initialisation that checks if there are any WordInDictionary objects already in the realm - if not then add the required default objects.

E.g.

let realm = try! Realm()
if realm.objects(WordInDictionary.self).isEmpty
{
// Add required words here
}

"Also, is there a way to make it so that just those initial objects can't be deleted?"

I don't know of a way to make realm objects read-only. You'd have to implement this in code in some way, e.g. have a isDeletable boolean member which is true for every user-created object and false for your default members, then only delete those from realm.

E.g. for your deletion code:

func deleteWords(wordsToDelete: Results<WordInDictionary>)
{
try! realm.write
{
realm.delete(wordsToDelete.filter("isDeletable = true")
}
}

Move from manual install to use Realm through Cocoapods in Xcode

If you already have the workspace created by cocoapods, you don't need to modify your project settings, when you add a new pod to your podfile, cocoapods will automatically handle linking that to your project correctly.

Simply remove the manually added Realm framework files, remove the custom Run Script build phase containing "${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}/Realm.framework/strip-frameworks.sh", then run pod update and you should be good to go.

As for the original issue of

Module compiled with Swift 4.2 cannot be imported by the Swift 5.0 compiler: /Users/userName/MyApp/RealmSwift.framework/Modules/RealmSwift.swiftmodule/i386.swiftmodule

, when using precompiled frameworks, you need to wait until the developer of the framework updates the precompiled versions for Swift 5 (or the newest version you want to switch your project to) before you can use them.

Since cocoapods compiles all dependencies from source on your own machine, this issue of incompatible Swift compiler versions cannot arise and you can even control which Swift version to use for each project specifically from your podfile.

Setting location of Realm in Swift

try this code tested & working. we need to create Application Support directory it's not created by default.

    let fileManager = FileManager.default
var config = Realm.Configuration()

let urls = fileManager.urls(for: .applicationSupportDirectory, in: .userDomainMask)

if let applicationSupportURL = urls.last {
do {
try fileManager.createDirectory(at: applicationSupportURL, withIntermediateDirectories: true, attributes: nil)
config.fileURL = applicationSupportURL.appendingPathComponent("demo.realm")
} catch let err {
print(err)

}
}

// Set this as the configuration used for the default Realm
Realm.Configuration.defaultConfiguration = config

print (Realm.Configuration.defaultConfiguration.fileURL!)

Swift: Install package so available to any Xcode Project?

This is not something that Swift supports at the current time.

What you could do is clone the Git repo for a project, and then reference it as a local dependency, but I wouldn't recommend this.

RealmSwift installation on Xcode

Its working now! Its so weird since I didn't do anything. I just went into my pod file commented out the use_frameworks! statement and ran pod update on the terminal. It gave me an error, so I added it back to my pod file. I wrote in pod update again and hit enter. I restarted Xcode cleaned it and built it and I wasn't getting this error anymore.

New Realm migration gets called on new app installs

I will preface this by stating this is being posted as an answer as it attempts to validate that the code in the question is functioning correctly outside of the OP's environment.

I've taken the code and added print statements throughout so the code flow could be easily followed in console.

We start with all files deleted so it would emulate a new install of the app. Your comment says you entered data but that would not be fresh install as the user would not have any data yet.

Here's duplicate code with some print statements added. For me, this is a macOS app, but an iOS app will behave the same.

The migration function is located in the AppDelegate and called like this

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {

func applicationDidFinishLaunching(_ aNotification: Notification) {
self.doMigrate()

and then the function

func doMigrate() {

print("starting schema version: \(Realm.Configuration.defaultConfiguration.schemaVersion)")

/// Migration 1:
Realm.Configuration.defaultConfiguration = Realm.Configuration(
schemaVersion: 1,
migrationBlock: { migration, oldSchemaVersion in
print("migration 1")
if (oldSchemaVersion < 1) {
print(" old schema < 1, performaing migration")
// configuration for schema 1
}
})

print("schema is now: \(Realm.Configuration.defaultConfiguration.schemaVersion)")

/// Migration 2:
Realm.Configuration.defaultConfiguration = Realm.Configuration(
schemaVersion: 2,
migrationBlock: { migration, oldSchemaVersion in
print("migration 2")
if (oldSchemaVersion < 2) {
print(" old schema < 2, performaing migration")
// configuration for schema 2
}
})

print("schema is now: \(Realm.Configuration.defaultConfiguration.schemaVersion)")

/// Migration 3:
Realm.Configuration.defaultConfiguration = Realm.Configuration(
schemaVersion: 3,
migrationBlock: { migration, oldSchemaVersion in
print("migration 3")
if (oldSchemaVersion < 3) {
print(" old schema < 3, performaing migration")
// configuration for schema 3
}
})

print("schema is now: \(Realm.Configuration.defaultConfiguration.schemaVersion)")
}

On first run, here's the output, noting no migration happens

starting schema version: 0
schema is now: 1
schema is now: 2
schema is now: 3

When the code is run a second time, the output is identical

starting schema version: 0
schema is now: 1
schema is now: 2
schema is now: 3

Even if I add or change the models, add or change data, the output remains the same - with the exception of it does crash because it needs a migration if an object property is removed.

So the answer is: If you're not seeing the same behavior, there's something else affecting the code/realm structure in your environment. This works the same way whether it's run once or 3 times.

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()


Related Topics



Leave a reply



Submit