SwiftUI

ActivityView in SwiftUI

GREEN.1229 2021. 11. 29. 22:00

안녕하세요. 그린입니다🟢

이번 포스팅에서는 SwiftUI에서 ActivityView(액티비티 뷰)를 띄우는것에 대해 학습해보겠습니다💁🏻

 

SwiftUI를 통해 구현을 하다 어떻게 하면 요런 데이터를 공유할 수 있는 액티비티 뷰를 띄울 수 있을까에 대해 고민하고
스택 오버플로와 다양한 레퍼런스를 통해 구현해보았습니다!
바로 이전 블로그 포스팅인 링크공유 & 링크이동에서 액티비티 뷰를 띄우는걸 학습해보았는데요.
그건 UIKit의 방식에 거의 유사하여 조금 더 SwiftUI로 구현해보았어요.
https://green1229.tistory.com/194

네 앞으로 구현할것이 이런 half한 액티비티 뷰를 띄우는 것입니다.

그럼 먼저 동작되는 화면을 간단한 짤로 보시죠!

 

동작화면

자 정말 간단히 제 블로그 URL을 공유할 수 있도록 버튼을 통해 공유할 수 있는 액티비티 뷰를 띄우고 동작해봤습니다.

그럼 바로 코드를 보시죠!

 

소스코드

import SwiftUI

public struct ActivityView: UIViewControllerRepresentable {
  @Binding var isPresented: Bool
  public let activityItmes: [Any]
  public let applicationActivities: [UIActivity]? = nil
  
  public func makeUIViewController(context: Context) -> UIViewController {
    UIViewController()
  }
  
  public func updateUIViewController(_ uiViewController: UIViewController, context: Context) {
    let activityViewController = UIActivityViewController(
      activityItems: activityItmes,
      applicationActivities: applicationActivities
    )

    if isPresented && uiViewController.presentedViewController == nil {
      uiViewController.present(activityViewController, animated: true)
    }
    activityViewController.completionWithItemsHandler = { (_, _, _, _) in
      isPresented = false
    }
  }
}

struct ContentView: View {
  @State private var isActivityViewPresented = false
  
  var body: some View {
    Button("Share Link") {
      self.isActivityViewPresented = true
    }
    .background(
      ActivityView(
        isPresented: $isActivityViewPresented,
        activityItmes: [URL(string: "https://green1229.tistory.com")!]
      )
    )
  }
}

우선 UIKit을 SwiftUI에서 사용할 수 있도록 UIViewControllerRepresentable 프로토콜을 따릅니다.

프로토콜을 따른 ActivityView에 필요한 프로퍼티들과 처음과 업데이트되었을때의 필수 메서드를 구현해줍니다.

updateUIVC 메서드에서 필요한 인자(텍스트, 이미지, URL 등 공유되거나 사용될 옵션)을 받아 구성 후 띄워주도록 합니다.

여기서 컴플리션 핸들러를 사용해 구성 후 다시 isPresented를 false로 바꿔주었습니다.

그러면 한번 노출되고 계속 노출되진 않습니다.

이걸 이제 ContentView에서 background 메서드로 호출해 사용합니다.

해당 뷰에서는 Share Link 버튼이 눌렸을때 눌린 Bool 값을 ActivityView에 넘겨주고 또한 activityItems에 제 블로그 URL을

넘겨주도록 합니다.

정말 간단하죠!?

 

그러면 이 액티비티 뷰에서는 어떤것들을 Share해줄 수 있는지 알아보도록 할께요🙌

UIAcitivityViewController를 구성할때 activityItems 인자를 설정해주어야 합니다.

그 인자에 들어올 수 있는 3가지가 있습니다.

1. Text

기본적으로 문구를 공유할 수 있습니다.

let shareItems = ["Green's blog"]
let activityController = UIActivityViewController(
  activityItems: shareItems,
  applicationActivities: nil
)
self.present(activityController, animated: true, completion: nil)

2. Image

guard let image = UIImage(named: "Green.png") else { return }
let shareItems = [image]
let activityController = UIActivityViewController(
  activityItems: shareItems,
  applicationActivities: nil
)
self.present(activityController, animated: true, completion: nil)

3. URL

guard let url = URL(string: "https://green1229.tistory.com/") else { return }
let shareItems = [url]
let activityController = UIActivityViewController(
  activityItems: shareItems,
  applicationActivities: nil
)
self.present(activityController, animated: true, completion: nil)

activityItems는 Any타입의 Array입니다.

그렇기에 위의 텍스트 / 이미지 / URL들이 다 같이 혹은 하나만 들어갈 수 있습니다.

let text = "green is green!"
guard let url = URL(string: "https://green1229.tistory.com/"),
  let image = UIImage(named: "Green.png") else { return }
let shareItems: [Any] = [text, url, image]
let activityController = UIActivityViewController(
  activityItems: shareItems,
  applicationActivities: nil
)
self.present(activityController, animated: true, completion: nil)

이렇게 사용될 수 있겠네요!

 

또한 아래와 같은 메서드를 사용해 공유에서 제외할 플랫폼을 설정할 수 있습니다.

let shareItems = ["Write your share content"]
let activityController = UIActivityViewController(
  activityItems: shareItems,
  applicationActivities: nil
)
activityController.excludedActivityTypes = [.postToFacebook, .postToTwitter]
self.present(activityController, animated: true, completion: nil)

이렇게 사용해주면 페이스북과 트위터는 나타나지 않게 됩니다.

 

마무리

자 이렇게 흔한 기본적으로 제공되는 공유 액티비티 뷰에 대해 SwiftUI스럽게 띄우고 사용하는것을 학습해봤습니다☺️

스유스러운것에 대해 항상 고민해봐야겠습니다.

 

[참고자료]

https://stackoverflow.com/questions/56533564/showing-uiactivityviewcontroller-in-swiftui

 

Showing 'UIActivityViewController' in SwiftUI

I want to let the user to be able to share a location but I don't know how to show UIActivityViewController in SwiftUI.

stackoverflow.com

https://www.swiftdevcenter.com/uiactivityviewcontroller-tutorial-by-example/

 

UIActivityViewController tutorial by Example

How to share content using UIActivityViewController. How to share text, image and URLs in Swift 4

www.swiftdevcenter.com