본문 바로가기
Apple/UIKit

[iOS] UIActivityViewController로 이미지 공유 기능 구현하기

by 어멘드 2022. 7. 7.
반응형

앱 내에서 선택한 이미지를 공유하는 기능을 구현해보려고 한다.
[공유하기] 버튼을 누르면 아래 사진과 같은 모달이 뜨고, 모달에서 공유하고 싶은 다른 앱을 고르는 방식이다.

 


UIActivityViewController

 저 모달이 바로 UIActivityViewController이다.
 UIActivityViewController는 Standard Service를 제공하기 위한 뷰 컨트롤러이다.
 Standard Service의 예시로는 아래와 같은 것들이 있다.

  • Pasteboard에 아이템 복사하기
  • SNS에 포스팅하기
  • email이나 SNS로 아이템 전송하기

 그 외 커스텀 서비스도 제공이 가능하다.
 위에 스크린샷에서 인스타그램을 선택하면 스토리/피드/DM에 공유하기가 뜨는 것처럼, 앱에서 서비스를 커스텀해서 제공할 수도 있다.

 

 아래와 같은 이니셜라이저를 사용해서 생성할 수 있다.

init(
    activityItems: [Any],
    applicationActivities: [UIActivity]?
)

 

activityItems
 서비스의 대상이 되는 데이터들이다.
 이미지를 공유하는 기능을 위해 구현한다면, 공유할 이미지들이 activityItems가 될 것이다.
 Any 타입이기 때문에 다양한 형태의 데이터를 담을 수 있다.
 배열 형태임에 유의하자. 빈 배열이면 안되고, 최소 1개 이상의 원소가 담겨야 한다.

applicationActivities
 제공할 커스텀 서비스들이다.
 Standard Service 설명에서 커스텀 서비스 제공도 가능하다고 했는데,
 그 커스텀 서비스를 모달에 뜨게 하고 싶다면 여기에 담아주면 된다.

 


 텍스트 뷰 이미지를 가지고 ActivityViewController를 띄우는 코드이다.

@IBAction func share(_ sender: UIButton) {
    guard let image = textView.convertToUIImage() else { return }

    let activityViewController = UIActivityViewController(activityItems: [image],
                                                          applicationActivities: nil)
    self.present(activityViewController, animated: true)
}

 

 아래 스크린샷처럼 공유하기 버튼을 터치하면 ActivityViewController가 모달로 띄워지고,
 메세지 앱을 선택하면 메시지에 사진이 첨부된다.

 

 


 그런데 현재 코드를 아이패드에서 실행하면 다음과 같은 에러가 난다.

'UIPopoverPresentationController should have a non-nil sourceView or barButtonItem set before the presentation occurs.'

 

기기 종류에 따라 present 방식이 다르기 때문이다.
 공식 문서를 읽어보면 iPad는 popover 방식으로 띄워야 하고, iPhone/iPod에서는 modally하게 띄워야 한다고 나와있다.

 

 아이패드는 popover 방식으로 띄워지기 때문에, popover가 가능하도록 아래 코드를 추가해주어야 한다.

@IBAction func share(_ sender: UIButton) {
    guard let image = textView.convertToUIImage() else { return }

    let activityViewController = UIActivityViewController(activityItems: [image],
                                                          applicationActivities: nil)

    // 아이패드의 경우 popover 방식으로 띄워짐
    activityViewController.popoverPresentationController?.sourceView = self.view
    activityViewController.popoverPresentationController?.sourceRect = sender.frame

    self.present(activityViewController, animated: true)
}


> 레퍼런스
https://developer.apple.com/documentation/uikit/uiactivityviewcontroller

반응형

댓글