-
[ios-Swift] Share Extension 사용하기ios 2021. 1. 27. 10:49
이번 글에서는 Share Extension을 커스텀 뷰로 꾸며 사용하는 글입니다.
1. 설정
ShareExtensionExample 프로젝트를 생성한 후
File -> Target -> Share Extension을 추가해 주도록 합니다.
Extension -> App 간 데이터 사용은 동일한 그룹을 사용해야 데이터를 공유할 수 있는 것으로 알고 있어 그룹 설정을 먼저 하도록 하겠습니다.
프로젝트의 Capacapabilities -> App Grouops를 선택 후 그룹을 설정해 주도록 합니다.
그룹명은 group.Bundle identifier.Share를 사용했습니다.
TARGETS -> 프로젝트에서 추가한 그룹을 셰어 익스텐션에서 체크해주도록 합니다.
이제 그룹 설정이 완료되었습니다.
이제 우리는 커스텀 뷰에서 어떤 데이터를 받을 것 인지를 설정해야 하는데 Extension의 info.plist 에서 설정하겠습니다.
NSExtensionActivationRule -> Dictionary로 변경 후 키와 밸류를 설정합니다.
NSExtensionActivationSupportsWebURLWithMaxCount : 허용할 HTTP URL 최대 수
NSExtensionActivationSupportsImageWithMaxCount : 허용할 IMAGE 최대 수
NSExtensionActivationRule의 키 값은 이곳에서 확인해 보시면 됩니다.
2. 소스
MainInterface.stroryboard에서 오브젝트들을 추가 및 ShareViewController에서 SLComposeServiceViewController -> UIViewController로 변경했습니다.
import UIKit import Social class ShareViewController: UIViewController { override func viewDidLoad() { } }
이제 앱이 아닌 익스텐션을 실행시켜 사파리 브라우저를 실행시키면 아래와 같이 커스텀 뷰가 나타나는 것을 확인할 수 있습니다.
커스텀 뷰의 버튼 및 동작을 추가하도록 하겠습니다.
import UIKit import Social import MobileCoreServices class ShareViewController: UIViewController { @IBOutlet weak var imageView: UIImageView! @IBOutlet weak var textView: UITextView! override func viewDidLoad() { let extensionItems = extensionContext?.inputItems as! [NSExtensionItem] for extensionItem in extensionItems { if let itemProviders = extensionItem.attachments as? [NSItemProvider] { for itemProvider in itemProviders { // 해당 객체가 있는지 식별 if itemProvider.hasItemConformingToTypeIdentifier(kUTTypeImage as String) { itemProvider.loadItem(forTypeIdentifier: kUTTypeImage as String, options: nil, completionHandler: { result, error in var image: UIImage? if result is UIImage { image = result as? UIImage } if result is URL { let data = try? Data(contentsOf: result as! URL) image = UIImage(data: data!)! } if result is Data { image = UIImage(data: result as! Data)! } DispatchQueue.main.async { if let image = image { self.imageView.image = image } } }) } if itemProvider.hasItemConformingToTypeIdentifier(kUTTypeURL as String) { itemProvider.loadItem(forTypeIdentifier: kUTTypeURL as String, options: nil, completionHandler: { result, error in let data = NSData.init(contentsOf:result as! URL) DispatchQueue.main.async { if let urlStr = result { self.textView.text = "\(urlStr)" } } }) } } } } } }
kUTTypeImage 외 다른 타입도 많으니 필요하신 걸 찾아서 변경 후 사용하면 됩니다.
kUTTypeImage as string는 "public.image"와 동일합니다.
// 익스텐션의 버튼 이벤트 @IBAction func btnSend(_ sender: UIButton) { // 처리후 종료 if let userDefaults = UserDefaults(suiteName: "위에서 설정한 그룹") { if let image = imageView.image { userDefaults.set(image.pngData(), forKey: "image") } if let text = textView.text { userDefaults.set(text, forKey: "text") } } self.hideExtensionWithCompletionHandler(completion: { _ in self.extensionContext?.completeRequest(returningItems: nil, completionHandler: nil) }) } @IBAction func btnDismiss(_ sender: UIButton) { self.hideExtensionWithCompletionHandler(completion: { _ in self.extensionContext?.completeRequest(returningItems: nil, completionHandler: nil) }) } func hideExtensionWithCompletionHandler(completion: @escaping (Bool) -> Void) { UIView.animate(withDuration: 0.3, animations: { self.navigationController?.view.transform = CGAffineTransform(translationX: 0, y:self.navigationController!.view.frame.size.height) }, completion: completion) }
익스텐션 뷰를 닫으려고 해도 그냥 dismiss를 사용하면 뷰가 사라지지 않아 hideExtensionWithCompletionHandler를 사용하도록 합니다.
//앱 뷰 컨트롤러 import UIKit class ViewController: UIViewController { override func viewDidLoad() { if let userDefaults = UserDefaults(suiteName: "group.com.fostep.Share") { if let data = userDefaults.data(forKey: "image") { imageView.image = UIImage(data: data) } if let text = userDefaults.string(forKey: "text") { textLabel.text = text } } }
익스텐션과 앱과의 데이터 전송은 UserDefaults를 사용해 저장 후 앱을 실행 UserDefaults를 확인하는 방식을 사용합니다.
꼭 UserDefaults를 사용하지 않아도 되며 익스텐션에서 서버에 전송 후 받는 방법을 사용하셔도 될 겁니다.
'ios' 카테고리의 다른 글
[ios - SwiftUI] Widget 사용하기 (2/2) (0) 2021.02.04 [ios - SwiftUI] Widget 사용하기 (1/2) (0) 2021.02.04 [ios - Swift] Phi Chart View (CALayer) (0) 2021.01.12 [ios - Swift] Circle Progressbar 만들기 (CALayer) (0) 2021.01.08 [ios - Swift] FileManager 사용한 저장, 불러오기 (0) 2021.01.05