【SwiftUI】SNSへのシェア機能の実装方法~UIActivityViewController~

SwiftUIで、SNSのシェア機能の実装方法をご紹介します。

実装方法

実装方法は2パターンあります。

パターン1

以下のように関数で、UIActivityViewControllerを呼び出します。

struct ContentView: View {
    var body: some View {
        Button(action: {
            sharePost(shareText: "iOS-Docs", shareImage: Image("imageName"), shareUrl: "https://ios-docs.dev")
        }) {
            Text("シェアする")
        }
    }
    
    func sharePost(shareText: String, shareImage: Image, shareUrl: String) {
        let activityItems = [shareText, shareImage, URL(string: shareUrl)!] as [Any]
        let activityVC = UIActivityViewController(activityItems: activityItems, applicationActivities: nil)
        let viewController = UIApplication.shared.windows.first?.rootViewController
        viewController?.present(activityVC, animated: true)
    }
}

ボタンを押すと、このような感じで、表示されます。

端末に、TwitterやLINEなどをインストールしていると、ここに表示されます。シミュレーターにはアプリを入れることができないので、実機で確認してください。

ただ、この方法だと、UIApplication.shared.windows.firstで警告が表示されてしまう。警告を消す方法については以下の記事を見てください。

【Xcode/Swift】windowsで警告:’windows’ was deprecated in iOS 15.0: Use UIWindowScene.windows on a relevant window scene instead

パターン2

こちらは、ハーフモーダルではなくなるので、あまりおすすめしません。

ShareSheetView.swiftを作って以下のコードを記載します。

struct ShareSheetView: UIViewControllerRepresentable {
    @State var text: String
    
    func makeUIViewController(context: Context) -> UIActivityViewController {
        let activityItems: [Any] = [text]
        let controller = UIActivityViewController(
            activityItems: activityItems,
            applicationActivities: nil)
        return controller
    }
    
    func updateUIViewController(_ vc: UIActivityViewController, context: Context) {
    }
}

次に、ContentViewを以下のように変更してください。

struct ContentView: View {
    @State private var showActivityView = false
    
    var body: some View {
        VStack {
            Button(action: {
                showActivityView.toggle()
            }) {
                Text("シェアする")
            }
        }
        .sheet(isPresented: $showActivityView) {
            ShareSheetView(text: "iOS-Docs")
        }
    }
}

これで一応、シェアできるのですが、このように全画面に開いてしまいます。

なので、パターン1の方がおすすめです。