azhy의 iOS 이야기

[iOS] WidgetKit[3] - App과 Extension, UserDefaults 공유하기 + Realm DB 공유 본문

iOS

[iOS] WidgetKit[3] - App과 Extension, UserDefaults 공유하기 + Realm DB 공유

azhy 2024. 11. 12. 21:18

2022년 7월 19일에 작성됨

 

앞에서 작성한 WidgetKit [1] 부분을 보면 맨 처음에 기본적으로 app과 app extension는 각각 따로 container를 가지고 있어서 둘 사이는 UserDefaults를 공유하지 않는다고 설명했습니다.

 

이번 글은 저번 Widget 1, 2의 연장이기 때문에 Widget Extension으로 포커스를 잡고 정리하겠지만 AppExtension은 Widget 말고도 많습니다. (Today Extension, Widget Extension, Siri Extension 등) 그래도 Widget 이랑 크게 다를 게 없을 거 같다는 느낌이긴 합니다. 어쨌든 이번엔 Widget Extension을 예시로 정리해 보겠습니다!

App Group 추가

먼저 App 쪽에 Signing & Capabilities의 +버튼을 눌러서 Capability AppGroup를 추가하고 Extension도 마찬가지로 AppGroup을 추가해줘야 하는데 App과 Extension에 같은 이름으로 App Group Identifier를 등록해 주세요.

사용하기

extension UserDefaults {
    static var shared: UserDefaults {
        let appGroupId = "group.ungchun.coupleDayProject"
        return UserDefaults(suiteName: appGroupId)!
    }
}

 

이렇게 사용하기 쉽게 extension으로 세팅해 줍니다. appGroupId 에는 본인의 Identifier를 적어주셔야 합니다.

UserDefaults.shared.set("test Value", forKey: "testKey") // set

UserDefaults.shared.string(forKey: "testKey")! // get

 

데이터를 저장하고 싶은 쪽에는 set, 그 데이터를 가져오고 싶으면 get 부분의 코드를 쓰시면 정상적으로 출력이 됩니다.

Realm DB 공유

진행 중인 프로젝트에서 Realm DB를 사용 중인데 Widget에서 app 쪽의 realm db를 바로 사용하지 못하기 때문에 공유하려면 세팅이 필요합니다.

 

우선 위에서 진행한 App Group을 똑같이 만들어줘야 합니다.

// app, widget extension
private var realm: Realm {
    let container = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.ungchun.coupleDayProject")
    let realmURL = container?.appendingPathComponent("default.realm")
    let config = Realm.Configuration(fileURL: realmURL, schemaVersion: 1)
    return try! Realm(configuration: config)
}

 

그다음에 이 코드를 app과 widget 쪽에서 사용하면 서로 같은 realm db를 공유해서 사용이 가능합니다.