본문 바로가기

iOS공통

[Extension] Action Extension, AppGroups과 함께 사용해보기

 

안녕하세요✋✋

 

오늘은 ActionExtension을 사용하는 방법과 AppGroups를 사용해 파일을 공유하는 방법에 대해 다뤄보려고 합니다.

 

먼저 프로젝트에 Action Extension을 추가합니다.

 

File > Target

 

기본적인 코드는 이미지 데이터를 불러오는 코드가 아마 구현되어 있을 겁니다.

 

저는 웹 url을 가져오는 엑션을 구현해 보겠습니다.

 

사용 컨텐츠 제한하기

 

일단 기본적으로 Action Extension은 ActivityView에서 사용이 가능합니다.

 

Action Extension을 구현한 경우 아래 사진의 빨간색으로 상자쳐진 부분에 표시되게 됩니다.

 

ActivityView

 

모든 엑티비티 뷰에서 액션이 실행되는 것을 방지할 수 있습니다.

 

바로 nsextensionactivationrule을 지정하는 방법인데요

 

원하는 키를 InfoPlist에 넣어줌으로서 지정한 컨텐츠에 대해서만 액션이 표시되도록 할 수 있습니다.

 

Info.Plist

 

저같은 경우에는 WebUrl만을 받아오기 위해 사진의 키를 사용하였고 갯수를 1개로 제한하였습니다.

 

일반 텍스트와 WebUrl링크는 다르게 분류됩니다.

 

데이터 불러오기

이제 컨텐츠 데이터를 불러와 보겠습니다.

 

호스트앱(엑티비티 뷰를 실행한 앱)과 익스텐션 앱은 NSExtensionContext를 사용하여 데이터를 주고 받을 수 있습니다.

(ViewController는 컨텍스트 인스턴스를 보유하고 있습니다.)

 

let item = self.extensionContext?.inputItems as? [NSExtensionItem]?.first

 

 

컨텍스트의 inputItems프로퍼티에는 컨텍스트와 연관된 데이터가 들어있습니다.

 

[Any] 타입이지만 NSExtensionItem타입의 리스트 입니다.

 

NSExtensionItem인스턴스는 attachments라는 프로퍼티를 가지는데 미디어 데이터 배열입니다.

 

let providers = item.attachments

 

공식문서에는 해당 미디어 데이터를 비디오, 이미지 그리고 url과 같은 데이터로 채워라 라고 적혀있습니다.

 

데이터를 전달받는 입장임으로 해당 프로퍼티를 사용해 데이터를 추출할 수 있습니다.

 

정확하게 attachments는 NSItemProvider배열로 선언되어 있습니다.

 

NSItemProvider는 드래그앤 드랍, 카피앤 페이스트 그리고 호스트앱과 익스텐션 사이의 데이터를 나른다 라고 문서에 적혀있습니다.

 

스위프트의 UTType을 사용하여 특정 데이터가 UTI를 만족하는지 확인한후 Provider로 부터 데이터를 전달받을 수 있습니다.

 

let idetifier = UTType.url.identifier

if provider.hasItemConformingToTypeIdentifier(idetifier) {
    	
	provider.loadItem(forTypeIdentifier: idetifier, options: nil) { (data, error) in
        
		let urlString = (data as? URL)?.absoluteString
        
	}

 

최종적으로 URL을 추출한 코드입니다.

 

데이터 저장하기

 

익스텐션은 호스트앱에 의해 생성되지만 사실상 별개의 앱입니다.

 

따라서 먼저 두 앱을 연결해야 합니다.

 

AppGroups Capability를 사용하여 두앱을 연결할 수 있습니다.

 

App Groups Capability

 

이후 역 도메인 으로 그룹명을 작성하고 같은 그룹명으로 앱들을 그룹화 합니다.

 

그룹화

 

AppGroups공식문서에 보시면 같은 앱그룹의 경우 UserDefaults를 공유할 수 있고 파일시스템내 특정 앱그룹이 공유할 수 있는 경로가 생성됩니다.

 

AppGroups 공식문서

 

위 사실을 몰랐을 때 저는 CoreData를 사용하여 익스텐셔과 호스트앱간 데이터를 공유하였습니다.

 

하지만 매번 코어데이터 컨테이너를 로드하는 것은 파일 시스템을 사용하는 것보다 기능적으로 비효율적이라고 합니다.

 

공유 디렉토리 경로는 아래와 같은 방법으로 접근할 수 있습니다.

 

let path = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.그룹명")

 

해당 경로에 파일을 저장하고 호스트앱에서 불러오는 방식을 사용하여 데이터를 공유할 수 있었습니다. 🙌

 

앱그룹에 속한 타겟에서만 해당 코드 실행시 경로를 전달받을 수 있습니다.

(앱그룹이 아닌 경우 nil)

 

Library/Caches 하위에 디렉토리를 생성합니다. 앱그룹의 모든 앱이 삭제된다면 시스템은 해당 디렉토리를 삭제한다고 합니다.

 

엑션 이름 지정하기

Bundle Display Name값을 변경하여 액션의 이름을 지정할 수 있습니다.

Info.plist

 

이름이 변경된 액션

 

NSExtension, Provider같이 데이터를 다루는 부분은 좀더 해당기능을 사용해보며 다뤄야할 것같습니다.

 

감사합니다~! 🤗