Gitodo!를 진행하면서 레포지토리 별 할 일 목록 및 현황을 위젯에서 보여주기 위해, 앱 타겟과 위젯 타겟 간 데이터 공유가 필요했다.
KeyChain, UserDefaults 등을 이용해서 타겟 간 데이터를 공유하는 방법도 있지만, 이미 앱 타겟에서 Realm 저장소에 할 일 데이터를 저장하고 있었기 때문에 위젯 타겟에서 앱 타겟에서 사용하던 Realm 저장소에 접근할 수만 있으면 데이터 공유가 바로 가능했다 !
그래서 작성하는 타겟 간 같은 Realm 저장소 사용하는 방법
1. 앱 그룹(App Groups) 설정하기
먼저, 앱 그룹을 설정해야 한다. 앱 그룹은 동일한 개발자가 만든 여러 앱이나 확장 프로그램(여기에 위젯이 포함!) 사이에 안전하게 데이터를 공유할 수 있도록 해준다.
각 타겟에서 앱 그룹을 사용하기 위해서는 권한 파일인 entitlements 파일이 필요하다. Xcode의 [PROJECT] - [Build Settings] - [Signing] 탭에서 설정할 수도 있지만, Gitodo!의 경우 Tuist를 사용하기 때문에 entitlements 파일을 직접 생성하고 Project.swift 파일에 아래와 같이 설정해주었다.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.application-groups</key>
<array>
<string>group.com.goorung.Gitodo</string>
</array>
</dict>
</plist>
let project = Project(
name: "Gitodo",
targets: [
...
// App target
.target(
...
entitlements: "\(appName).entitlements",
...
),
// Small Static Widget target
.target(
...
entitlements: "\(appName).entitlements",
...
),
// Medium Intent Widget target
.target(
...
entitlements: "\(appName).entitlements",
...
)
]
)
tuist generate로 프로젝트 파일을 생성하면 각 타겟에 앱 그룹이 잘 추가된 모습을 확인할 수 있다 !

2. Realm 설정하기
앱 그룹을 설정했으니, 이제 공유 컨테이너를 통해 Realm 데이터베이스에 접근할 수 있다.

기본 컨테이너
기본적으로, iOS 앱과 위젯은 서로 독립적인 샌드박스 환경을 갖는다. 각각의 타겟은 고유한 디렉토리 구조와 파일 시스템을 가지며, 다른 타겟의 파일에 접근할 수 없다.
공유 컨테이너
앱 그룹을 사용하여 공유 컨테이너를 설정하면, 여러 타겟이 동일한 파일 시스템 경로를 공유하게 된다.
FileManager : iOS와 macOS에서 파일 시스템을 관리하는 데 사용되는 기본 클래스로 특히 앱의 샌드박스 내에서 파일과 디렉토리에 접근하고 관리하는 기능을 제공
3. 데이터 접근 및 공유
기존 코드 :
private func initializeRealm() throws -> Realm {
do {
return try Realm()
} catch {
throw RealmError.initializationError(error)
}
}
변경 코드 :
private func initializeRealm() throws -> Realm {
do {
let appGroupID = "group.com.goorung.Gitodo"
let container = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: appGroupID)
let realmURL = container?.appendingPathComponent("db.realm")
let config = Realm.Configuration(fileURL: realmURL)
return try Realm(configuration: config)
} catch {
throw RealmError.initializationError(error)
}
}
이제 앱 타겟과 위젯 타겟에서 동일한 Realm 저장소를 사용할 수 있게 된다 !
참고로, 타겟들이 공통으로 사용하는 모델은 공유 프레임워크를 생성하는 방법을 사용했다.
'iOS 🍎 Swift' 카테고리의 다른 글
Xcode 메모리 누수 체크하기 (2) | 2024.08.05 |
---|---|
Github OAuth 앱 스토어 심사 (iOS에서 URL을 여는 방법) (8) | 2024.07.18 |
iOS 민감한 정보 숨기기 (0) | 2024.07.18 |
iOS/Swift 토스트 메시지 🍞 (2) | 2024.07.16 |
Tuist 환경에서 Xcode Cloud CI/CD 구축 (1) | 2024.07.15 |