sahara108
sahara108

Reputation: 2859

Access Realm from 2 different target at the same time

Let say, I want to use realm for my share extension, so the question is, can I access Realm in the share target while the containing app is running. It looks like it is impossible but can I have advise from experienced. Thanks!

Upvotes: 5

Views: 1259

Answers (3)

Faizal Faisu
Faizal Faisu

Reputation: 1

  1. Created a group identifier in the Signing&Capabilities of main target, and added same group id to the second Target. (Ensure it has added to both debug and release mode).

  2. Make a single class for both targets (or extensions).

  3. The below class using for all targets in the Project.



import Foundation
import RealmSwift

class CustomRealm {
    let groupIdentifier: String  = "group.company.groupid" // Change it as in the signing and Capabilities
    var realm : Realm!
    var isReady = false
    var msg:String = "Nothing"
    init() {
        if var directory: URL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier:groupIdentifier) {
            do {
                if try directory.checkResourceIsReachable()  {
                    msg = "Realm groupIdentifier directory. found"
                    print(msg)
                }else {
                    msg = "Realm !!!groupIdentifier directory not found"
                    print(msg)
                }
                
            }catch {
                msg = "Realm groupIdentifier directory. Error = \(error)"
                print(msg)
                return
            }
            directory.appendPathComponent("db.realm", isDirectory: true)
            
            do {
                if try directory.checkResourceIsReachable()  {
                    msg = "Realm has already created"
                    print()
                }else { msg = "Realm not yet created"; print(msg)}
                
            }catch {
                msg = "Realm Db directory check. Error = \(error)"
                print(msg)
            }
            
            let config = Realm.Configuration(fileURL: directory, schemaVersion: 1)
            Realm.Configuration.defaultConfiguration = config
            
            do{
                realm = try Realm(configuration: config)
                isReady = true
            }catch{
                isReady = false
                print(error)
            }
            
            msg = "Realm location Configured"; print(msg)
        }else { msg = "Realm location not Configured"; print(msg)}

    }
}
  1. You can access realm using
let myRealm = CustomRealm()
let realmDb = myRealm.realm
  1. Check if it ready or not before doing any modify

if !isReady { msger("realm is not ready") return false }

Upvotes: 0

Mark Kazakov
Mark Kazakov

Reputation: 1116

Xcode 11 - Swift 5

In order for Realm to be accessible from more than 1 target you have to create an App Group within your workspace in Xcode.
In the Signing&Capabilities tab of your main target follow these steps:

Click +Capability enter image description here

Then App Groups
enter image description here

Inside the new App Groups section click the Add Container option
enter image description here

The container should have an identifier that begins with group.
Make sure all the targets that require access to realm have the same container specified inside the App Group section.

In your AppDelegate specify the following Realm config:

if var directory: URL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.com.yourappgroup.identifier") {
        directory.appendPathComponent("db.realm", isDirectory: true)
        let config = Realm.Configuration(fileURL: directory, schemaVersion: 1)
        Realm.Configuration.defaultConfiguration = config
    }  

Change "group.com.yourappgroup.identifier" to your actual group identifier as you specified in Signing&Capabilities.
This will tell Realm to place itself within the group container.

Lastly, each target that wishes to access Realm should be told to search for it within the same group container.
So when you wish to access Realm from your other targets add the same configuration code before accessing and that's it!

Upvotes: 4

Thomas Goyne
Thomas Goyne

Reputation: 8138

You have to place your files which you want to share in the shared container:

RLMRealmConfiguration *configuration = [RLMRealmConfiguration defaultConfiguration];
configuration.fileURL = [[[NSFileManager defaultManager]
    containerURLForSecurityApplicationGroupIdentifier:@"group.your.group.name"]
    URLByAppendingPathComponent:@"db.realm"];
RLMRealm *realm = [RLMRealm realmWithConfiguration:configuration error:nil];

This requires configuring the entitlements for your application and extension to have a shared container.

Upvotes: 1

Related Questions