SwiftUI에서 ActivityView 구현하기

버질·2024년 12월 13일

1. 개요

ActivityView: iOS에서 데이터를 공유할 때 사용하는 UIActivityViewController를 SwiftUI에서 활용하기 위해 UIViewControllerRepresentable을 사용해 구현.
목적: URL, 텍스트, 이미지 등 다양한 데이터를 손쉽게 공유하도록 SwiftUI에서 ActivityView를 구성.

2. 구현 코드

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://velog.io/@soungjunban/posts")!]
            )
        )
    }
}

3. 코드 분석

UIViewControllerRepresentable:
UIKit의 UIActivityViewController를 SwiftUI에서 사용하기 위해 UIViewControllerRepresentable을 채택하여 SwiftUI 뷰로 변환.

ActivityView:
isPresented: ActivityView를 표시할지 여부를 제어.
activityItems: 공유할 데이터(문자열, 이미지, URL 등).
makeUIViewController: SwiftUI가 사용할 기본 UIViewController 생성.
updateUIViewController: UIActivityViewController를 구성하고 표시.

ContentView:
버튼을 통해 ActivityView를 표시.
ActivityView는 background 메서드로 추가.

4. ActivityView로 공유할 데이터 타입

activityItems 배열에 추가할 수 있는 데이터 타입:

텍스트:

let shareItems = ["Bans's blog"]

이미지:

guard let image = UIImage(named: "Ban.png") else { return }
let shareItems = [image]

URL:
guard let url = URL(string: "https://velog.io/@soungjunban/posts") else { return }
let shareItems = [url]

복합 데이터:
let text = "Check this out!"
let url = URL(string: "https://example.com")!
let image = UIImage(named: "example.png")!
let shareItems: [Any] = [text, url, image]

5. 추가 기능

특정 공유 플랫폼 제외:

activityController.excludedActivityTypes = [.postToFacebook, .postToTwitter]

특정 플랫폼(예: Facebook, Twitter)을 공유 옵션에서 제외.

Completion Handler:
completionWithItemsHandler를 사용해 공유 완료 후 처리.
isPresented = false로 설정하여 ActivityView가 닫히도록 구현.

6. 학습한 점

SwiftUI와 UIKit의 연계:
UIViewControllerRepresentable를 활용해 UIKit의 컨트롤러를 SwiftUI에서 쉽게 사용할 수 있다.
유연한 데이터 공유:
텍스트, 이미지, URL 등 다양한 데이터를 간단히 공유 가능.
복합 데이터를 사용하여 다양한 공유 옵션 제공.
사용자 경험 개선:
completionWithItemsHandler로 사용자가 공유를 완료했을 때 적절한 후처리를 수행.

profile
iOS Developer · SwiftUI & UIKit '가끔 되고 가끔 안 되는' 문제를 뿌리부터 잡습니다.

0개의 댓글