[iOS] Extension과 Main App 사이 Data 공유하기

Picnic·2024년 12월 14일

iOS

목록 보기
3/5
post-thumbnail

안녕하세요 Picnic🧃입니다.
Extension과 Main App 사이의 데이터를 공유하는 법을 알아보겠습니다.

정확히는 Extension에서 얻은 값을 Main App에서 사용하는 방법입니다.

지금의 글은 Realm 파일을 Main App과 Share Extension의 공유 컨테이너에 저장하여 데이터를 공유하는 법을 볼 것입니다.
Extension과 Main App 사이에 데이터를 공유하는 방법은 Realm뿐만 아니라 다른 방법들도 있습니다.
다른 방법들도 공부해가면서 이 글을 계속 업데이트 할 예정입니다.

이 글을 읽기 전에 타겟App Group에 관한 글을 읽고 오면 좋습니다!



Realm을 공유 컨테이너에 저장하기


일단 Main App와 Share Extension이 같은 공간을 사용하기 위해서는 이전 글들에서 봐왔듯이 Target Dependency가 있어야 하고, App Group을 생성해줘야 합니다.

여기까지 했다면 간단합니다!

App Group에 대한 글에서 마지막에 있던 말이 있습니다.

앱이 App Group의 멤버가 되면, 해당 그룹의 공유 컨테이너에 데이터를 읽고 쓰기 위해 사용할 수 있는 여러 API를 제공받게 됩니다. 예를 들어:

  • init(suiteName:) 메서드를 사용하여 App Group의 공유 사용자 기본값(shared user defaults) 데이터베이스에 접근하여 환경설정(preferences) 및 기타 제한된 데이터를 공유할 수 있습니다.
  • containerURL(forSecurityApplicationGroupIdentifier:) 메서드를 호출하여 App Group의 공유 컨테이너의 물리적 위치를 검색할 수 있습니다. 검색한 URL을 사용해 데이터를 읽거나 쓸 수 있습니다.
  • 백그라운드 URL 세션의 구성(configuration)에서 sharedContainerIdentifier 속성을 설정하여 파일을 App Group의 공유 컨테이너에 직접 다운로드할 수 있습니다

이 때 “containerURL(forSecurityApplicationGroupIdentifier:) 메서드를 호출하여 App Group의 공유 컨테이너의 물리적 위치를 검색할 수 있습니다. 검색한 URL을 사용해 데이터를 읽거나 쓸 수 있습니다.

이 부분이 중요한데, 이 메서드를 통해 App Group의 공유 컨테이터의 위치를 검색할 수 있다고 하고 이 URL을 이용할 수 있다고 합니다. 그래서 이를 이용하면

func shareRealm() {
    let directory = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.com.example.myGroup")?.appendingPathComponent("shared.realm")
    let sharedConfig = Realm.Configuration(fileURL: directory)        
    database = try! Realm(configuration: sharedConfig)
}

FileManager를 통해 공유 컨테이너 위치를 찾아줍니다.
(이 때 사용하는 identifier는 App Group을 생성할 때 사용한 identifier입니다.)

그리고 Realm이 가지고 있는 Realm.Configuration(fileURL:) 메서드를 통해 해당 파일의 위치를 알려주고
Realm(configuration:) 생성자를 통해 Realm 객체를 생성해주면 됩니다!

그러면 shared.realm 파일은 Main App과 Share Extension간의 공유 컨테이너에 생성되게 됩니다.
이제 realm 파일은 Main App과 Share Extension 모두에서 접근 가능하기 때문에 양쪽에서 데이터를 사용할 수 있습니다.

예를 들어 Realm으로 데이터를 관리하는 DataBaseManger를 싱글톤으로 만들어서 Share Extension와 타겟 멤버쉽을 통해 연결해주면 Share Extenion의 화면에서 Realm 데이터베이스를 읽어와 어떤 데이터가 있는지 보여줄 수 있죠!

그리고 Share Extension에서 얻은 값을 DataBaseManager를 통해 저장해주면 MainApp에서도 같은 DataBaseManager를 이용해 Share Extension에서 저장한 값을 사용할 수 있습니다!

간단하게 작성하자면 다음과 같습니다.

class DatabaseManager() {
  static let shared = DataBaseManager()
	private var database: Realm!
	
	private init() {
		shareRealm()
	}
	
	func shareRealm() {
    let directory = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.com.example.myGroup")?.appendingPathComponent("shared.realm")
    let sharedConfig = Realm.Configuration(fileURL: directory)        
    database = try! Realm(configuration: sharedConfig)
    
    /*
    데이터베이스 관리 코드...
    */
}



FileManager로 공유 컨테이너 관리하기


위의 Realm 파일을 공유 컨테이너에 저장하는 방법을 보았다면 FileManager를 통해 공유 컨테이너의 위치를 찾는 것을 볼 수 있습니다. 그렇다면 FileManager를 이용해 데이터를 저장할 때에도 같은 방법으로 저장할 수 있을 것입니다.

let directory = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.com.example.myGroup")

App Group에서 보았듯이, containerURL(forSecurityApplicationGroupIdentifier:) 메서드를 통해 공유 컨테이너의 위치를 찾는다면 해당 디렉토리에 데이터를 저장하거나 이용하는 등의 작업을 할 수 있을 것입니다.

해당 공유 컨테이너에 그대로 작업하거나 따로 디렉토리를 또 생성해서 이용할 수 있겠죠!

0개의 댓글