SwiftUIの基本を身につけたい方はこちら

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

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

実装方法

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

パターン1

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

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
struct ContentView: View {
var body: some View {
Button(action: {
sharePost(shareText: "iOS-Docs", shareImage: UIImage(named: "imageName"), shareUrl: "https://ios-docs.dev")
}) {
Text("シェアする")
}
}
func sharePost(shareText: String, shareImage: UIImage, 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)
}
}
struct ContentView: View { var body: some View { Button(action: { sharePost(shareText: "iOS-Docs", shareImage: UIImage(named: "imageName"), shareUrl: "https://ios-docs.dev") }) { Text("シェアする") } } func sharePost(shareText: String, shareImage: UIImage, 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) } }
struct ContentView: View {
    var body: some View {
        Button(action: {
            sharePost(shareText: "iOS-Docs", shareImage: UIImage(named: "imageName"), shareUrl: "https://ios-docs.dev")
        }) {
            Text("シェアする")
        }
    }
    
    func sharePost(shareText: String, shareImage: UIImage, 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を作って以下のコードを記載します。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
struct ShareSheetView: UIViewControllerRepresentable {
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) {
}
}
struct ShareSheetView: UIViewControllerRepresentable { 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) { } }
struct ShareSheetView: UIViewControllerRepresentable {
    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を以下のように変更してください。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
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")
}
}
}
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") } } }
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の方がおすすめです。

評価