[iOS] App Group Capability

이정훈·2025년 6월 5일
0

iOS

목록 보기
5/6
post-thumbnail

iOS Sandbox 구조

App Extension은 iOS 8.0부터 등장하여 Host App과 별개의 프로세스로 동작하는 확장 Framework를 말한다. 가령, Notification, Widget 등을 App Extension을 통해서 구현할 수 있다.

App Extension은 App과 별개로 독립된 프로세스로 실행되며, App과 독립된 공간(Container)을 활용한다. 따라서 기본적으로 두 Container 사이에서 UserDefaults 또는 CoreData를 활용한 데이터는 공유되지 않는다. 이러한 Sandbox 구조는 아래 그림과 같이 도식화하여 표현할 수 있다.

App Group Capability

그럼에도 불구하고 위의 그림과 같이 두 Container 사이에 Shared Container를 사용한다면, 두 Container 사이에 데이터를 공유할 수 있다.

App Group Capability는 개발자의 여러 앱 또는 extension 프로그램 사이에서 데이터를 공유할 수 있도록 Sandbox 내부의 Container 공유 기능을 말한다.

App Group 활성화

프로젝트 세팅 상황은 Host App 하나와 Notification Service Extension 두 개의 타깃으로 구성되어 있다. 프로젝트의 기본 상태로는 App Group이 활성화 되어 있지 않다.

우측 상단의 + 버튼을 클릭해서 App Group에 대한 Capability를 추가한다.

그리고 Host App과 Extension에 동일한 App Group Identifier를 등록한다.

App Group을 통한 데이터 공유

이번 포스트에서는 UserDefaults를 활용한 데이터 공유 방법에 대해 소개하고자 한다.

기존에는 UserDefaultsstandard 프로퍼티를 사용하여 싱글톤 인스턴스를 사용하였지만, 해당 인스턴스는 Host App의 Container를 가리키고 있으므로 App Group 기반의 Shared Container에 데이터를 공유하는 싱글톤 인스턴스를 생성하도록 한다.

이때, 해당 소스파일은 Extension에서도 사용할 수 있도록 Target Membership에 Target을 추가하는 것도 잊지 않는다.

import Foundation

extension UserDefaults {
    static var shared: UserDefaults = {
        let groupId = "com.jeonghun.AppGroupTest"
        return UserDefaults(suiteName: groupId)!
    }()
}

init(suiteName:) 이니셜라이저에 그룹 식별자를 전달하여 새로운 UserDefaults 인스턴스를 생성한다.

이제 Host App에서 저장한 데이터가 Extension에서도 동일하게 공유되는지 확인해보자.

struct ContentView: View {
    var body: some View {
        VStack {
            Image(systemName: "globe")
                .imageScale(.large)
                .foregroundStyle(.tint)

            Text("Hello, world!")
        }
        .padding()
        .onAppear {
            //문자열 저장
            UserDefaults.shared.set("테스트입니다.", forKey: "testKey")
        }
    }
}
import UserNotifications

class NotificationService: UNNotificationServiceExtension {
    var contentHandler: ((UNNotificationContent) -> Void)?
    var bestAttemptContent: UNMutableNotificationContent?

    override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {

        print(UserDefaults.shared.string(forKey: "testKey"))    //"테스트입니다."

		// Modify the notification content here...
    }
profile
새롭게 알게된 것을 기록하는 공간

0개의 댓글