【SwiftUI】シェアを実装する際に気を付ける事

# はじめに
SwiftUIでシェア機能を実装する際は`UIActivityViewController`を使用します。
ここにかなり深い落とし穴があるので落ちないように気をつけましょう。
私は落っこちて原因に気づかず長い間、クラッシュを生み出していました笑
みなさんはそうならない様に気をつけましょう。

# 結論
iPadで普通に`UIActivityViewController`を使うとクラッシュします

# パターン1(おすすめ)
```Swift
import SwiftUI

struct ContentView: View {
    @State var ShowSharePopover: Bool = false
    var body: some View {
        Button("シェア") {
            Share()
        }
        .popover(isPresented: $ShowSharePopover) {
            ShareView()
        }
    }
    // iPhone: ハーフモーダル
    // iPad: ポップアップ
    func Share() {
        if UIDevice.current.userInterfaceIdiom == .pad {
            ShowSharePopover = true
        } else {
            let link = URL(string: "https://qiita.com/SNQ-2001/items/86646b661ccc4a7a9034")!
            let activityViewController = UIActivityViewController(activityItems: [link], applicationActivities: nil)
            let scene = UIApplication.shared.connectedScenes.first(where: { $0.activationState == .foregroundActive }) as? UIWindowScene
            let viewController = scene?.keyWindow?.rootViewController
            viewController?.present(activityViewController, animated: true, completion: nil)
        }
    }
}

struct ShareView: UIViewControllerRepresentable {
    func makeUIViewController(context: Context) -> UIActivityViewController {
        let link = URL(string: "https://qiita.com/SNQ-2001/items/86646b661ccc4a7a9034")!
        let activityViewController = UIActivityViewController( activityItems: [link], applicationActivities: nil)
        return activityViewController
    }
    func updateUIViewController(_ vc: UIActivityViewController, context: Context) {
    }
}
```
|iPhone|iPad|
|-|-|
|![IMG_0243.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/3cba2029-61f3-7b73-ecfc-af16bf1ff767.png)|![IMG_2470.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/d2985c61-7fb2-6d7d-4fbd-9ab8fe833016.png)|
# パターン2
```Swift
import SwiftUI

struct ContentView: View {
    @State var ShowShareSheet: Bool = false
    var body: some View {
        Button("シェア") {
            share()
        }
        .sheet(isPresented: $ShowShareSheet) {
            ShareView()
        }
    }
    // iPhone: ハーフモーダル
    // iPad: 中央ポップアップ
    func share() {
        if UIDevice.current.userInterfaceIdiom == .pad {
            ShowShareSheet = true
        } else {
            let link = URL(string: "https://qiita.com/SNQ-2001/items/86646b661ccc4a7a9034")!
            let activityViewController = UIActivityViewController(activityItems: [link], applicationActivities: nil)
            let scene = UIApplication.shared.connectedScenes.first(where: { $0.activationState == .foregroundActive }) as? UIWindowScene
            let viewController = scene?.keyWindow?.rootViewController
            viewController?.present(activityViewController, animated: true, completion: nil)
        }
    }
}

struct ShareView: UIViewControllerRepresentable {
    func makeUIViewController(context: Context) -> UIActivityViewController {
        let link = URL(string: "https://qiita.com/SNQ-2001/items/86646b661ccc4a7a9034")!
        let activityViewController = UIActivityViewController( activityItems: [link], applicationActivities: nil)
        return activityViewController
    }
    func updateUIViewController(_ vc: UIActivityViewController, context: Context) {
    }
}
```
|iPhone|iPad|
|-|-|
|![IMG_0244.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/6de9da82-bd7a-50ee-75db-9c822f54aff7.png)|![IMG_2468.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/a058e98f-de88-3beb-a3d4-4ea5dc189e70.png)|

# パターン3(使用してはいけない)
```Swift
import SwiftUI

struct ContentView: View {
    var body: some View {
        Button("シェア") {
            share()
        }
    }
    // iPhone: ハーフモーダル
    // iPad: クラッシュ
    func share() {
        let link = URL(string: "https://qiita.com/SNQ-2001/items/86646b661ccc4a7a9034")!
        let activityViewController = UIActivityViewController(activityItems: [link], applicationActivities: nil)
        let scene = UIApplication.shared.connectedScenes.first(where: { $0.activationState == .foregroundActive }) as? UIWindowScene
        let viewController = scene?.keyWindow?.rootViewController
        viewController?.present(activityViewController, animated: true, completion: nil)
    }
}
```
|iPhone|iPad|
|-|-|
|![IMG_0244.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/1ac2e66c-5cde-0434-d416-c79ea6be2348.png)|クラッシュ|
# パターン4
```Swift
import SwiftUI

struct ContentView: View {
    @State var ShowSharePopover: Bool = false
    var body: some View {
        Button("シェア") {
            Share()
        }
        .popover(isPresented: $ShowSharePopover) {
            ShareView()
        }
    }
    // iPhone: モーダル
    // iPad: ポップアップ
    func Share() {
        ShowSharePopover = true
    }
}

struct ShareView: UIViewControllerRepresentable {
    func makeUIViewController(context: Context) -> UIActivityViewController {
        let link = URL(string: "https://qiita.com/SNQ-2001/items/86646b661ccc4a7a9034")!
        let activityViewController = UIActivityViewController( activityItems: [link], applicationActivities: nil)
        return activityViewController
    }
    func updateUIViewController(_ vc: UIActivityViewController, context: Context) {
    }
}
```
|iPhone|iPad|
|-|-|
|![IMG_0245.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/ee09e31d-be58-f9cd-4158-4191e36175a4.png)|![IMG_2470.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/f40c7e3f-1b37-6cab-f59c-dfbe0df800a2.png)|

# パターン5
```Swift
import SwiftUI

struct ContentView: View {
    @State var ShowShareSheet: Bool = false
    var body: some View {
        Button("シェア") {
            Share()
        }
        .sheet(isPresented: $ShowShareSheet) {
            ShareView()
        }
    }
    // iPhone: モーダル
    // iPad: 中央ポップアップ
    func Share() {
        ShowShareSheet = true
    }
}

struct ShareView: UIViewControllerRepresentable {
    func makeUIViewController(context: Context) -> UIActivityViewController {
        let link = URL(string: "https://qiita.com/SNQ-2001/items/86646b661ccc4a7a9034")!
        let activityViewController = UIActivityViewController( activityItems: [link], applicationActivities: nil)
        return activityViewController
    }
    func updateUIViewController(_ vc: UIActivityViewController, context: Context) {
    }
}
```
|iPhone|iPad|
|-|-|
|![IMG_0245.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/ee09e31d-be58-f9cd-4158-4191e36175a4.png)|![IMG_2468.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/a058e98f-de88-3beb-a3d4-4ea5dc189e70.png)|

# おわり
今回作成したプロジェクトを置いとくので参考にしてください。

https://github.com/SNQ-2001/Share-Demo