0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【SwiftUI】UIActivityViewController・URLスキームを用いたシェア機能の実装

Last updated at Posted at 2025-02-21

はじめに

SwiftUIにおけるシェア機能の実装方法について学習したので、備忘録として残します。
シェア機能の実装方法はいくつかありますが、今回はUIActivityViewControllerURLスキームの2つを学習したため、これらの実装方法をまとめます。


環境

【Xcode】16.2
【iOS】18.2
【macOS】Sequoia 15.3.1


ポイント

UIActivityViewControllerは最も簡単で一般的なシェア機能。
 XやLINEなど、ユーザーがインストールしているさまざまなアプリへ共有できる。
URLスキームは特定のアプリに直接シェアする方法。
 あらかじめシェアして欲しいアプリが決まっている場合にこちらを使用。


1.UIActivityViewControllerURLスキームについて

まずはそれぞれの違いとメリット・デメリットについてまとめます。

方法 違い メリット デメリット
UIActivityViewController
ユーザーがインストールしている様々なアプリにシェアできる UIActivityViewControllerを使うだけで簡単に実装できる
・システム標準のUIなのでUXが統一されている
・シェアボタンのデザインやシェア対象のカスタマイズが難しい
URLスキーム
特定のアプリ(XやLINEなど)を指定してシェアできる ・どのアプリでシェアするかを固定できる
・シェア内容を細かくカスタマイズできる
・対象のアプリがインストールされていないと動作しない

基本的には簡単で一般的なUIActivityViewControllerを使用し、特定のアプリを指定してシェアさせたい場合にURLスキームを使用するとよさそう。


2.実装方法

続いて、各機能の実装方法についてまとめます。

UIActivityViewController

📌 UIActivityViewControllerを使う流れ

  1. シェアしたい内容(テキストやURL、画像など)を準備する
  2. UIActivityViewController を作成し、シェア内容を渡す
  3. .sheet() を使ってシェア画面を表示する

import SwiftUI

struct ContentView: View {
    @State private var isShowingShareSheet = false
    
    var body: some View {
        VStack {
            Text("シェア機能\n(UIActivityViewController)")
                .font(.title)
                .padding()
            Button {
                isShowingShareSheet = true
            } label: {
                Text("シェアする")
                    .font(.title2)
                    .padding()
                    .foregroundStyle(.white)
                    .background(Color.blue)
                    .cornerRadius(10)
            }
            .padding()
            .font(.title)
            .sheet(isPresented: $isShowingShareSheet) {
                ShareSheet(activityItems: ["このアプリを試してみよう! #シェア機能"])
            }
        }
    }
}

// ⬇️ UIViewControllerRepresentable でSwiftUIでも使えるようにする
struct ShareSheet: UIViewControllerRepresentable {
    let activityItems: [Any]
// ⬇️ UIKitの UIActivityViewController をSwiftUIのViewとして作成する
    func makeUIViewController(context: Context) -> some UIViewController {
        UIActivityViewController(activityItems: activityItems, applicationActivities: nil)
    }
    func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) {
    }
}

まず、UIActivityViewControllerはUIKitのコンポーネントであるため、そのままではSwiftUIで使用することはできません。
SwiftUIのViewとして使うにはUIViewControllerRepresentableを用います。

let activityItems: [Any]でシェアする内容を入れる定数を用意します。 文字列や画像、URLなどに対応するため型はAny、複数のアイテムを同時にシェアできる仕様なので配列にします。

続いてfunc makeUIViewControllerで、UIKitのUIActivityViewControllerをSwiftUIのViewとして作成します。
Contextは、SwiftUIとUIKitの間で情報をやり取りするためのオブジェクトです。(今回は特に使ってません)

some UIViewController は、「戻り値の正確な型を明示しなくても、UIViewController の仲間を返すよ!」という意味です。
例えば、後から UIActivityViewController 以外の UIViewController に変更したくなった場合でも、柔軟に対応できます。

let activityItems: [Any]で定義したシェアしたい内容(activityItems)をUIActivityViewController に渡して、シェアできるようにします。

applicationActivities: nilとすることで、デフォルトのシェアオプション(LINE, X, メールなど)が表示されます。
カスタムのアクティビティを追加する場合は、applicationActivitiesに独自のUIActivityを渡します。

func updateUIViewControllerは、SwiftUIの状態が変わったときに UIKit側のUIActivityViewController を更新するためのメソッド です。
今回はシェア機能において特に更新が不要なため、空のままにしています。


URLスキーム

📌 URLスキームを使う流れ

  1. シェアしたいアプリのURLスキームを調べる
  2. UIApplication.shared.open() を使ってURLスキームを開く
  3. アプリがインストールされているか確認し、未インストール時の対策をする(例: canOpenURL

import SwiftUI

struct ContentView: View {
    var body: some View {
        VStack {
            Text("シェア機能(URLスキーム)")
                .font(.title)
                .padding()
            
            Button {
                shareOnX()
            } label: {
                Text("Xでシェア")
                    .font(.title2)
                    .padding()
                    .foregroundStyle(.white)
                    .background(Color.blue)
                    .cornerRadius(10)
            }
        }
    }
}

//URLスキームを使ってXでシェア
func shareOnX() {
    let text = "このアプリを試してみよう! #シェア機能"
// シェア用のテキストをエンコード
    guard let encodedText = text.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) else {
        return  // エンコードに失敗した場合は処理を終了
    }
    
    // Xアプリ用のURLスキーム
    if let url = URL(string: "twitter://post?message=\(encodedText)"),
       UIApplication.shared.canOpenURL(url) {
        UIApplication.shared.open(url, options: [:], completionHandler: nil)
        return
    }
    
    // Xアプリがインストールされていない場合はWebで開く
    if let webURL = URL(string: "https://twitter.com/intent/tweet?text=\(encodedText)") {
        UIApplication.shared.open(webURL, options: [:], completionHandler: nil)
    }
}

※上記はXでのシェアの例です。

今回は"このアプリを試してみよう! #シェア機能"というテキストをXでシェアさせたいです。
ただ、日本語やスペースなどの特殊文字が含まれているとURLとして正しく処理されないため、addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) を使ってURLエンコード(%エンコーディング)を行っています。

続いて、URLエンコードしたテキストを、Xのシェア用URLに組み込みます。
Xアプリを開いて、特定のテキストを投稿するURLスキームは以下の通りです。

twitter://post?message=投稿したいテキスト

UIApplication.shared.canOpenURL(url)で指定したurlを開けるかどうかを事前に確認し、Xアプリがインストールされていればアプリを開き、インストールされていなければWebでURLを開くようにします。
Webの共有URLは以下のとおりです。

https://twitter.com/intent/tweet?text=投稿したいテキスト

options: [:]UIApplication.shared.openメソッドのoptionsパラメータに空の辞書 [:] を渡す処理で、デフォルトの動作となります。 このパラメータは、特定のオプションを指定するために使用されますが、特に指定がない場合は空の辞書を渡す形で問題ないです。

今回は例としてXで共有する形で記載しましたが、それ以外でも各アプリのURLスキームに組み込むことでシェアが可能になります。
例として、以下はLINEを開いてメッセージを送信するURLスキーム、Webの共有URLです。

line://msg/text/送信したいテキスト
https://line.me/R/msg/text/?送信したいテキスト

おわりに

自分の知らなかったことや理解が難しかった内容を詰め込んで記載したので、読みづらい文章になっていたらすみません。。。
また、間違っている部分などあればご指摘ただけますと幸いです。

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?