ViewだけでWebView埋め込みiOSアプリを作る

# はじめに
みなさんは「あ〜このWebサイト・アプリがモバイルアプリだったら便利なのにな〜」と思うことはありませんか？
私はあります…！！

SafariからWebページをホームに追加しても、PWAに対応してないサイトはなんとなく不便、、、
そんなあなたに、WebView埋め込みのiOSアプリをサクッと作るお話を共有したいと思います！

# 環境
- macOS Sonoma 14.2
- Xcode 15.1
- iOS 17.1.2
- Swift 5.x系

# 作ったもの
- Safariに遷移することなく、Webページのコンテンツをアプリ自体に埋め込んだもの
- SwiftUIのViewの中で「WKWebView」を使って実装
- フッターに「戻る」ボタンと「進む」ボタンを実装

# プロジェクトの作成
慣れているみなさまは読み飛ばしてください…！

1. Xcodeで「Create New Project...」を選択
<img width="600" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3622149/951e9261-8f03-2833-352a-89843e1f22ed.png">

2. 「iOS」 > 「App」を選択して「Next」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3622149/8f959841-74da-8a7d-c7e9-25ac0faa836d.png)

3. 任意のアプリ名とチームを入力、選択して「Next」ををクリック
![スクリーンショット 2023-12-15 9.10.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3622149/246b9d48-2199-47fa-3dc0-839406eec7d8.png)


4. この画面が出たらプロジェクト作成は終わりです！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3622149/da8c9096-b02a-b85a-0f93-70ad92cc34cd.png)

# ソースコード
```Swift
import SwiftUI
import WebKit

// WebView
struct WebView: UIViewRepresentable {
    
    let url: URL
    let webView: WKWebView
    
    func makeUIView(context: Context) -> WKWebView {
        let view = webView
        view.allowsBackForwardNavigationGestures = true // スワイプジェスチャーを有効化
        return view
    }
    func updateUIView(_ uiView: WKWebView, context: Context) {
        let request = URLRequest(url: url)
        uiView.load(request)
    }
}

struct ContentView: View {
    
    @State private var webView: WKWebView?
    
    var body: some View {
        VStack {
            if let webView = webView {
                VStack(spacing: 0){
                    WebView(url: URL(string: "https://google.com/")!, webView: webView) // ここに任意のURL
                    Divider()
                    // ここからナビゲーションボタン
                    HStack {
                        Button(action: {
                            webView.goBack() // 戻る
                        }, label: {
                            Image(systemName: "chevron.backward")
                        })
                        Spacer()
                            .frame(width: 40)
                        Button(action: {
                            webView.goForward() // 進む
                        }, label: {
                            Image(systemName: "chevron.forward")
                        })
                        Spacer()
                    }
                    .padding(.leading,40)
                    .padding(.top,10)
                    .padding(.bottom,7)
                    .frame(maxWidth: .infinity)
                    
                }
            }
        }
        
        .onAppear {
            webView = WKWebView()
        }
    }
}

#Preview {
    ContentView()
}
```

最初から存在する ContentView.swift にコピペしたら動作するかと思います！

## 簡単な解説
※iOS初心者が書いているので間違っている可能性があります！鵜呑みにせず再度確認してください〜！

### 1. WebView
SwiftUIにない機能をUIKitから引っ張ってきて使えるようにする「UIViewRepresentable」を使った構造体です。
makeUIViewメソッドでwebViewインスタンスを作成し、updateUIViewメソッドでURLリクエストをロードしています。
allowsBackForwardNavigationGesturesを有効にすることで、スワイプジェスチャーを有効化しているので、不要な方は消してください。

### 2. ContentView
WebViewを呼び出して、ナビゲーションボタンを追加したメインビューです。
@StateでWebViewの状態変化を追跡し、ナビゲーションボタンの動作をビューに反映させます。
全体をVStackでラップし、その中にWebViewとナビゲーションボタンを配置しています。
ナビゲーションボタンはHStackで配置し、各ボタンにWKWebViewのメソッドであるgoBackとgoForwardを割り当てています。

# おわりに
WKWebKitを使えば、非常にシンプルなコードでWebコンテンツを埋め込むことができます！
皆さんもぜひやってみてください〜！！

拙い文章でしたが、読んでいただきありがとうございました！

# 参考文献
https://swifty-ui.com/wkwebview/

https://developer.apple.com/documentation/swiftui/uiviewrepresentable
https://developer.apple.com/documentation/webkit/wkwebview/1414952-goback