본문 바로가기
카테고리 없음

IOS)Realm - Configuration & Extension Realm Share - 2

by 후르륵짭짭 2022. 2. 13.
728x90
반응형

 

안녕하세요!

륵짭이 입니다.

이번에는 Realm을 다른 Extension에서 공용으로 사용할 수 있도록 하는 방법을 공유하려고 합니다.

후우,,, 개발은 왤케 공부할게 많은걸까요,,,

 

** ShareExtension을 만들자 ** 

일단 Extension을 추가해준다.

이렇게 해서 Extension을 추가를 해주고

 - Podfile에 추가 - 

target 'Realm-Config&Encryp' do
  # Comment the next line if you don't want to use dynamic frameworks
  use_frameworks!

  # Pods for Realm-Config&Encryp
pod "RealmSwift"

target 'shareExtension' do
inherit! :search_paths
end

end

위에 처럼 추가 해준다.

inherit! :search_paths를 하면 위에 있는 pod 내용을 해당 target에서도 사용할 수 있도록 해준다.

 

** Extension에서 Realm 사용 ** 

import RealmSwift

class ShareViewController : UIViewController {

func accessMainRealm(){
        //Cannot Access
        print(#function)
        let config = Realm.Configuration(fileURL: inLibrarayFolder(fileName: "main.realm"))
        let realm = try! Realm(configuration: config)
        
        let airports = realm.objects(Airport.self)
        
        print("Airports in database = \(airports.count)")
        print(config.fileURL!)
        print("=====================")
    }
    
}

//결과
file:///Users/taesooyoon/Library/Developer/CoreSimulator/Devices/48103AEA-4A40-4AA1-B304-1766D4547117/data/Containers/Data/PluginKitPlugin/B369D9B6-129A-4536-83F5-36849182F5DD/Library/main.realm

이걸 보면 main.realm을 보면 

PluginKitPlugin

이 들어가서 이상한 곳을 가르키고 있습니다.

 

** App Group 등록하기 **

이렇게 앱 끼리 다른 현상이 있을 때, App Group을 통해서 서로 연결 시켤 줄 수 있습니다.

https://zeddios.tistory.com/349

 

iOS ) Add the App Groups feature to your App ID.

안녕하세요. Today extension을 해볼까...해서 하는데(Today Extension 처음해봄..) ㅇ..?이게머얌 이건!! 나의 developer사이트에서 해결할 수 있습니다. 로 들어가셔서, 저는 App Groups을 생성해본적이 없으..

zeddios.tistory.com

이렇게 해주고 

앱 그룹을 추가해주고 원하는 App Group을 등록 해줍니다.

** Shared Realm 생성하기 **

    func shareRealm(){
        print(#function)
        let directory = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.taesoo.shareExtension.Share")?.appendingPathComponent("shared.realm")
        let sharedConfig = Realm.Configuration(fileURL: directory)
        if let bundleUrl = Bundle.main.url(forResource: "bundle", withExtension: "realm") {
            if !FileManager.default.fileExists(atPath: directory!.path) {
                try! FileManager.default.copyItem(at: bundleUrl, to: sharedConfig.fileURL!)
                print(sharedConfig.fileURL!)
            }
            else{
                print("file exist")
            }
        }
        print("==========================")
    }

위와 같이 FileManager의 forSecurityApplicationGroupIndentifier를 통해서 

AppGroup 이름을 적어주고 Realm Configuration을 생성해줍니다.

그리고 기본을 생성한 Bundle.Realm을 그대로 복사한 후에는

해당 Path에 Realm 파일을 생성이 됩니다.

그럼 이제 원래 App 에서도 접근 할 수 있도록 

똑같이  아래 코드를 넣어줍니다.

class ViewController: UIViewController {

func shareRealm(){
        print(#function)
        let directory = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.taesoo.shareExtension.Share")?.appendingPathComponent("shared.realm")
        let sharedConfig = Realm.Configuration(fileURL: directory)
        
        if FileManager.default.fileExists(atPath: directory!.path) {
            let realm = try! Realm(configuration: sharedConfig)
            let airports = realm.objects(Airport.self)
            print(sharedConfig.fileURL!)
            print(airports.count)
            self.label.text = "\(airports.count)"
        }
        else{
            print("file exist")
        }
        
        print("==========================")
    }
    
}

 

 

 ** 전체 코드  **

더보기

 - 메인 앱 - 

import UIKit
import RealmSwift

class ViewController: UIViewController {
    
    let label : UILabel = {
        let label = UILabel()
        label.textColor = .blue
        return label
    }()

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        setView()
        realmLocation()
//        prebundleData()
        readLocalPreDefineBundle()
//        makeMainRealmFile()
        
//        addPreDefineDataToMainRealm()
//        createMainRealmWithCopyBundle()
        readMainBundle()
    }
    
    func setView(){
        self.view.addSubview(label)
        label.frame.size = CGSize(width: 100, height: 100)
        label.bounds.origin = CGPoint(x: 100, y: 100)
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        shareRealm()
    }
    
    func shareRealm(){
        print(#function)
        let directory = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.taesoo.shareExtension.Share")?.appendingPathComponent("shared.realm")
        let sharedConfig = Realm.Configuration(fileURL: directory)
        
        if FileManager.default.fileExists(atPath: directory!.path) {
            let realm = try! Realm(configuration: sharedConfig)
            let airports = realm.objects(Airport.self)
            print(sharedConfig.fileURL!)
            print(airports.count)
            self.label.text = "\(airports.count)"
        }
        else{
            print("file exist")
        }
        
        print("==========================")
    }
    
    func readMainBundle(){
        print(#function)
        let config = Realm.Configuration(fileURL: inLibrarayFolder(fileName: "main.realm"))
        let realm = try! Realm(configuration: config)
        let airports = realm.objects(Airport.self)
        
        print(airports[0].airport)
        print(airports[1].airport)
        print(config.fileURL!)
        print("==========================")
        
    }
    
    func createMainRealmWithCopyBundle(){
        print(#function)
        let main2RealmURL = inLibrarayFolder(fileName: "main2.realm")
        if let bundleUrl = Bundle.main.url(forResource: "bundle", withExtension: "realm") {
            if !FileManager.default.fileExists(atPath: main2RealmURL.path) {
                try! FileManager.default.copyItem(at: bundleUrl, to: main2RealmURL)
                print(main2RealmURL)
            }
        }
        print("==========================")
    }
    
    func addPreDefineDataToMainRealm(){
        print(#function)
        let configurationMain = Realm.Configuration(fileURL: inLibrarayFolder(fileName: "main.realm"))
        let realmMain = try! Realm(configuration: configurationMain)
        
        let BundleFileURL = Bundle.main.url(forResource: "bundle", withExtension: "realm")
        let configurationBundle = Realm.Configuration(fileURL: BundleFileURL)
        let realmBundle = try! Realm(configuration: configurationBundle)
        
        if true {
            var needsToCopy = [Airport]()
            for obj in realmBundle.objects(Airport.self){
                let airports = realmMain.objects(Airport.self).filter { airport in
                    return airport.userId == obj.userId
                }
                
                if airports.isEmpty {needsToCopy.append(obj)}
            }
            
            if !needsToCopy.isEmpty {
                try! realmMain.write({
                    for airport in needsToCopy{
                        realmMain.create(Airport.self, value: airport, update: .all)
                        //2개 이상의 Realm을 동시에 사용 할 때
                        //Realm 값을 변경해야한다면 Add는 사용 할 수 없고
                        //Create로 업데이트 해줘야한다.
                    }
                })
            }
        }
        
        print("==========================")
    }
    
    func makeMainRealmFile(){
        print(#function)
        let configuration = Realm.Configuration(fileURL: inLibrarayFolder(fileName: "main.realm"))
        guard let realm = try? Realm(configuration: configuration) else {return}
        print(configuration.fileURL!)
        
        let airport1 = Airport(airport: "London", model: "LOD", userId: 3)
        let airport2 = Airport(airport: "Seoul", model: "SEL", userId: 4)
        
        try! realm.write({
            realm.add([airport1,airport2])
        })
        
        print("==========================")
    }

    func realmLocation(){
        print(#function)
        guard let realm = try? Realm() else {return}
        print(realm.configuration.fileURL!)
        print(realm.configuration.schemaVersion)
        print("==========================")
    }
    
    func readLocalPreDefineBundle(){
        print(#function)
        let fileURL = Bundle.main.url(forResource: "bundle", withExtension: "realm")
        let configuration = Realm.Configuration(fileURL: fileURL)
        guard let realm = try? Realm(configuration: configuration) else {return}
        
        let airports = realm.objects(Airport.self)
        print(airports[0].airport)
        print(airports[1].airport)
        print("==========================")
    }

    func prebundleData(){
        print(#function)
        let configuration = Realm.Configuration(fileURL: inLibrarayFolder(fileName: "bundle.realm"))
        guard let realm = try? Realm(configuration: configuration) else {return}
        print(realm.configuration.fileURL!)
        print(realm.configuration.schemaVersion)
        print(realm.isEmpty)
        
        let airport1 = Airport(airport: "jinnah", model: "OKC", userId: 1)
        let airport2 = Airport(airport: "Steven", model: "NYC", userId: 2)
        
        try! realm.write({
            realm.add([airport1, airport2])
        })
        
        print(realm.configuration.fileURL!)
        
        print("==========================")
    }

    func inLibrarayFolder(fileName : String) -> URL {
        //allDomainMask - "/Users/taesooyoon/Library/Developer/CoreSimulator/Devices/48103AEA-4A40-4AA1-B304-1766D4547117/data/Containers/Data/Application/8AF0F793-DBE6-4DF8-A186-7988D0E84189/Library", "/Library", "/Network/Library", "/System/Library"

        //userDomainMask - "/Users/taesooyoon/Library/Developer/CoreSimulator/Devices/48103AEA-4A40-4AA1-B304-1766D4547117/data/Containers/Data/Application/D3124A1D-9B22-47C5-9B9A-815771A39A58/Library"

        //localDomainMask - /Library"

        //networkDomainMask - "/Network/Library"

        let libraryUserDomain = NSSearchPathForDirectoriesInDomains(.libraryDirectory, .userDomainMask, true)
        let makeFileUrl = URL(fileURLWithPath: libraryUserDomain[0], isDirectory: true)
        return makeFileUrl.appendingPathComponent(fileName)
    }


}

 

 - Extension - 

import RealmSwift

class ShareViewController : UIViewController {
    
    lazy var button : UIButton = {
       let btn = UIButton()
        btn.setTitle("Click", for: .normal)
        btn.setTitleColor(.blue, for: .normal)
        btn.addTarget(self, action: #selector(add), for: .touchUpInside)
        return btn
    }()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        accessMainRealm()
        shareRealm()
        setView()
    }
    
    func setView(){
        self.view.backgroundColor = .white
        self.view.addSubview(button)
        button.frame.size = CGSize(width: 100, height: 100)
        button.bounds.origin = CGPoint(x: 100, y: 100)
    }
    
    @objc func add(){
        print(#function)
        let directory = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.taesoo.shareExtension.Share")?.appendingPathComponent("shared.realm")
        let sharedConfig = Realm.Configuration(fileURL: directory)
        
        let realm = try! Realm(configuration: sharedConfig)
        
        let count = realm.objects(Airport.self).count
        
        let new = Airport(airport: "TAIPAI", model: "JAN", userId: count + 1)
        
        try! realm.write {
            realm.add(new)
        }
        print("===================")
    }
    
    func shareRealm(){
        print(#function)
        let directory = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.taesoo.shareExtension.Share")?.appendingPathComponent("shared.realm")
        let sharedConfig = Realm.Configuration(fileURL: directory)
        if let bundleUrl = Bundle.main.url(forResource: "bundle", withExtension: "realm") {
            if !FileManager.default.fileExists(atPath: directory!.path) {
                try! FileManager.default.copyItem(at: bundleUrl, to: sharedConfig.fileURL!)
                print(sharedConfig.fileURL!)
            }
            else{
                print("file exist")
            }
        }
        print("==========================")
    }
    
    func accessMainRealm(){
        //Cannot Access
        print(#function)
        let config = Realm.Configuration(fileURL: inLibrarayFolder(fileName: "main.realm"))
        let realm = try! Realm(configuration: config)
        
        let airports = realm.objects(Airport.self)
        
        print("Airports in database = \(airports.count)")
        print(config.fileURL!)
        print("=====================")
    }
    
    func inLibrarayFolder(fileName : String) -> URL {
        let libraryUserDomain = NSSearchPathForDirectoriesInDomains(.libraryDirectory, .userDomainMask, true)
        let makeFileUrl = URL(fileURLWithPath: libraryUserDomain[0], isDirectory: true)
        return makeFileUrl.appendingPathComponent(fileName)
    }

    
}

 

참고 사이트 

https://baked-corn.tistory.com/100

 

[ios] File System (2)

[ios] File System (2) 안녕하세요. 지난 번 iOS의 파일 시스템의 포스팅에서는 전반적인 구조와 개념을 알아보았습니다. 오늘은 본격적으로 코드를 통해 파일 시스템을 다루어보도록 하겠습니다. 지

baked-corn.tistory.com

https://ali-akhtar.medium.com/realm-custom-configuration-and-encryption-realmswift-part-3-f991f090ae22

 

Realm Custom Configuration and Encryption (RealmSwift Part 3)

In this part we will cover following topics

ali-akhtar.medium.com

 

- 코코아 팟 설치 오류 - 

https://tttap.tistory.com/145

 

[ Xcode ] CocoaPods 설치 에러 수정 xcrun: error: invalid active developer path

Traceback (most recent call last): 5: from /usr/local/bin/pod:23:in ` ' 4: from /usr/local/bin/pod:23:in `load' 3: from /Library/Ruby/Gems/2.6.0/gems/cocoapods-1.10.1/bin/pod:55:in ` ' 2: from /Lib..

tttap.tistory.com

 

- Xcode Entitlement 에러 -

https://stackoverflow.com/questions/55456335/entitlements-file-was-modified-during-the-build-which-is-not-supported

 

Entitlements file was modified during the build, which is not supported

I'm getting following error during release build: error: Entitlements file "projectname.entitlements" was modified during the build, which is not supported. You can disable this error by

stackoverflow.com

 

728x90
반응형

댓글