3
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?

金沢工業大学Advent Calendar 2023

Day 13

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

Posted at

はじめに

みなさんは「あ〜この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...」を選択
image.png
  1. 「iOS」 > 「App」を選択して「Next」をクリック
    image.png

  2. 任意のアプリ名とチームを入力、選択して「Next」ををクリック
    スクリーンショット 2023-12-15 9.10.04.png

  3. この画面が出たらプロジェクト作成は終わりです!
    image.png

ソースコード

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://developer.apple.com/documentation/swiftui/uiviewrepresentable
https://developer.apple.com/documentation/webkit/wkwebview/1414952-goback

3
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
3
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?