안녕하세요 후르륵짭짭 입니다.
이번에는 Share Extension에 대해 정리해보려고 합니다.
Share Extension이란, 공유 버튼을 누르고 앱을 클릭 했을 때,
현재 앱과 연동 할 수 있는 작은 앱을 의미합니다.
그리고 Share Extension을 구현 할 수 있는 방법은 총 두가지가 있습니다.
( 처음 해보는 것이라 생각 보다 난감했었는데, 차근차근 정리 해보도록 하겠습니다. )
** Share Extension 생성 하기 **
일단 새로운 프로젝트를 생성하고 File -> New -> Target 에 들어가서 share Extension을 클릭해주세요.
그리고 나면 새로운 Share Extension 파일이 생성 될 것 입니다.
** 기본으로 제공되는 View **
class ShareViewController: SLComposeServiceViewController {,,,}
ShareViewController를 보면 SLComposeServiceViewController로 되어 있다.
이것은 기본적으로 제공하는 ViewController인데, 특별하게 필요한 것이 없다면 유용하게 사용 할수 있습니다.
자세하면서도 기본적인 설명은 (zeddios.tistory.com/1041) 여기도 잘 되어 있습니다.
//post 버튼이 false 라면 꺼져 있음 반대로 true 라면 켜져 있음
//이 부분은 TextField에 들어가는 부분
override func isContentValid() -> Bool {
// Do validation of contentText and/or NSExtensionContext attachments here
//플레이스 홀더
self.placeholder = "Hello world"
//contentText는 shareExtension의 TextField 부분
return self.contentText.isEmpty ? false : true
}
override func configurationItems() -> [Any]! {
// To add configuration options via table cells at the bottom of the sheet, return an array of SLComposeSheetConfigurationItem here.
let item = SLComposeSheetConfigurationItem()!
item.title = "Hello"
item.value = "ChapChap"
item.tapHandler = {
let vc = ShareExViewController()
self.pushConfigurationViewController(vc)
}
return [item]
}
여기서 configurationItems는 네비게이션 바와 같은 역할을 하게 해줍니다.
그리고 pushConfigurationViewController( 아무 ViewController)를 넣을 수도 있습니다.
자세한 내용은 저기 링크에 있습니다.
소스 코드 :
github.com/HururuekChapChap/Xcode_TestProj/tree/master/ShareExtension
** Custom View **
이에 위에 있는 모든 코드를 다 지워주시고 평소와 같이 UIViewController를 상속 받아주시기 바랍니다.
class ShareViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
}
그리고 이제 ViewDIdLoad()를 꾸며볼려고 합니다.
let extensionItems = extensionContext?.inputItems as! [NSExtensionItem]
현재 나온 VIewController에서 내용물들을 추철해주는 것 입니다.
현재 여러개의 값을 가지고 있기 때문에 배열로 선언 했는데, 사실 하나의 index만 받아오면 되기 때문에
if let extensionItem = self.extensionContext?.inputItems[0] as? NSExtensionItem {}
이렇게 해줘도 상관 없습니다.
for items in extensionItems{
if let itemProviders = items.attachments {}
}
이제 extensionItems (보통 하나의 데이터이기 때문에 이렇게 안해줘도 됩니다.)에 들어가 있는 내용물을 가져옵니다.
이렇게 attachments는 여러개의 media data를 가지고 있다고 해서 배열 형태 입니다.
그럼 이제 이것을 하나씩 확인 해보도록 하겠습니다.
for item_provider in itemProviders { ,,, }
이렇게 attachments들의 내용 물들을 확인하는데,
//이미지 파일을 가지고 있는가?
if item_provider.hasItemConformingToTypeIdentifier(kUTTypeImage as String) {}
//URL 데이터를 가지고 있는가?
if item_provider.hasItemConformingToTypeIdentifier(kUTTypeURL as String) {}
...
이렇게 kUTType의 여러가지 값이 있습니다.
그리고 원하는 타입으로 타입 캐스팅 해주면 됩니다!
( 이때 주의 해야할 것이 import MobileCoreServices 를 반드시 해주셔야 합니다. )
item_provider.loadItem(forTypeIdentifier: kUTTypeImage as String, options: nil)
{ (data, error) in
print("Image : \(data)")
}
그리고 이렇게 loadItem을 호출해주고 (forTypeIdentifier : kUTType , options : nil) {결과 , 오류 in} 이렇게 값이 전달이 됩니다.
이렇게 하면 이제 URL이나 Image 정보를 가져올 수 있습니다.
** UserDefault로 데이터 전송하기 **
이제 위와 같이 데이터 정보를 가져 왔으니,,, 원래 앱으로 데이터를 전송 해야 합니다
(그게 가장 큰 목적이져 ㅎㅎㅎ)
그래서 필요 한 것이 UserDefault 입니다.
2020/08/11 - [Xcode/IOS] - IOS) UserDefault로 간단한 내용을 저장하자!
하지만 일단 UserDefault를 사용하기 전에, Extension 앱과 기존 App을 연동 시켜줘야합니다.
일단 Capability를 눌러서 App Group을 추가해주고
App Ground에 " + "을 눌른 다음에, group.(Bundle Indentifier)를 추가해주세요.
이 짓을 기존 앱과 Share Extension 양쪽에 모두 등록을 해주셔야 합니다.
그리고 기존앱에서 Info를 들어간 다음 URL Type에 URL Schemes를 등록 해주시기 바랍니다.
URL Scheme는 UserDefault에서 Key 값이 될 놈 입니다.
이제 기본적인 Setting은 끝나고 본격적으로 코드를 작성 해주면 됩니다.
let savedata = UserDefaults.init(suiteName: "group.TeamProj.ShareExtension102.ShareEx102")
이제 UserDefaults.init(suiteName : "group.(Bundel Identifier)")를 해서 UserDefault 객체를 생성 해주시기 바랍니다.
if let url = data as? URL{
let test = String(describing: url)
print("URL : \(test)")
savedata?.set(test, forKey: "urlData")
savedata?.synchronize()
}
이렇게 해서 URL을 String으로 변화 시키고 UserDefault에 데이터를 저장 합니다.
그리고 여기서 set은 데이터를 저장하는 것이고 (setValue도 가능합니다.)
그리고 synchronize()를 통해 기본 데이터베이스에 대한 보류중인 비동기 업데이트를 기다렸다가 반환하게 합니다.
즉, synchronize로 데이터를 임시적으로 보류상태로 만드는 것 입니다.
이제 기존 앱으로 가서 비슷하게 처리를 해줍니다.
let savedata = UserDefaults.init(suiteName: "group.TeamProj.ShareExtension102.ShareEx102")
이렇게 위에 처럼 해준 다음에,
if let url = savedata?.string(forKey: "urlData"){
name.text = String(describing: url)
print(url)
}
이렇게 string으로 userDefault를 해독 해주면 이상 없이 데이터를 잘 받아 오게 됩니다.
하지만 만약에 여러개의 데이터를 보내고 싶은 경우에는 아래 처럼 배열을 만들거나 Dictionary 형태
아니면 Encode를 해서 Data로 보내주면 될 것 같습니다.
var arrayList : [String] = []
if let allData = savedata?.object(forKey: "urlData"){
if let tempList = allData as? NSArray{
arrayList = tempList as! [String]
}
}
let test = url.absoluteString
arrayList.append(test)
print(arrayList)
savedata?.setValue(arrayList, forKey: "urlData")
savedata?.synchronize()
이렇게 Array로 넣어주고 NSArray로 데이터를 풀어주면 됩니다.
소스 코드 :
github.com/HururuekChapChap/Xcode_TestProj/tree/master/ShareExtension102
먼가 많이 부족하지만,,, 나중에 실력을 더 키워서 좀더 자세한 내용을 다룰 수 있도록 하겠습니다.
참고 사이트 :
Share Extension의 기본적인 설명 :
Extension INFO.plist 내용 :
많이 도움이 된 Share Extension 설명 한글 버전 :
g-y-e-o-m.tistory.com/92?category=237961
코드를 비교하면서 Share Extension 공부하기 도움 되었던 사이트 :
medium.com/@abhishekthapliyal/ios-share-extension-930ba1ad3c3d
정말 큰 도움이 된 Share Extension 영어 설명 :
www.jellyfishtechnologies.com/blog/share-extension-ios-swift/
Share Extension Custom View에 대한 설명 :
diamantidis.github.io/2020/01/11/share-extension-custom-ui
UserDefault에 none - property list 에러 해결 방법 (Data나 String과 같은 형식으로 압축으로 해결) :
stackoverflow.com/a/41355671/13065642
App extension Programing Guild :
developer.apple.com/library/archive/documentation/General/Conceptual/ExtensibilityPG/Share.html
아직은 이해하기 어려운 Share Extension 내용 ㅜㅜ :
medium.com/@damisipikuda/how-to-receive-a-shared-content-in-an-ios-application-4d5964229701
Share Extension과 Core data를 함께 사용하는 방법 :
medium.com/@manibatra23/sharing-data-using-core-data-ios-app-and-extension-fb0a176eaee9
'Xcode > IOS' 카테고리의 다른 글
IOS) Dynamic UIScrollView in Code (0) | 2020.12.25 |
---|---|
IOS) StoryBoard없이 Custom Navigation Controller (0) | 2020.12.24 |
IOS) TableVIew의 Pagination을 구현해보자 (0) | 2020.12.17 |
IOS) TableView의 Section을 다뤄보자 (0) | 2020.12.13 |
IOS) 동적인 TableView Cell을 만드는 방법 (0) | 2020.12.12 |
댓글