안녕하세요!
륵짭이 입니다.
이번에는 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
이렇게 해주고
앱 그룹을 추가해주고 원하는 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
- 코코아 팟 설치 오류 -
- Xcode Entitlement 에러 -
댓글