まったくのiOSアプリ初心者が、5日間で一通り動くアプリを作った話

こんにちは。今日はまったくのiOSアプリ初心者である私が、たった5日間でアプリを作り上げた経験についてお話しします。アプリの詳細は話すことができないことをご了承ください。結論から言うと、WebSimを使ってWebページを作り、WebViewを使ってHTMLページを表示させることでプロトタイプを作り上げたという話です。

# 背景

私はこれまでWeb開発に携わってきましたが、ネイティブアプリの開発は初めてでした。ある日、上司から「とあるiOSアプリを作ってほしい」という依頼が舞い込みました。初めての経験でプレッシャーを感じましたが、なんとかスピード感を持って取り組みたいと思いました。私はiOSアプリ開発やSwiftについて全く知りませんでしたが、アプリの見た目をリッチなものにしたいという思いがありました。

# Webページの作成

iOS開発環境はすでに整っていたので、iOSアプリのプロジェクトを作成しました。
何かWeb開発の知識をそのまま活かせる方法はないかと思い、ClaudeにSwiftでHTML、CSS、JavaScriptを表示する方法はないかと尋ねました。そうすると、あるではありませんか！WebViewという方法でHTMLを表示し、JavaScriptとSwiftが双方向の通信を行えると教えてくれました。
なので、一日目はアプリの画面一覧を作成し、[WebSim](https://websim.ai/)(ノーコードでWebページが作成できるツール)を使ってスマホ画面用のWebページを作成するということをひたすら行いました。
WebSimを使ったWebアプリの開発例を以下に載せておきます。

https://qiita.com/ssc-yshikeda/items/39495a295d52505c7fad



# WebViewの導入

次の日、WebViewを使ってHTMLページを表示させることから始めました。以下のコードを使用してWebViewを設定しました。

```swift
import SwiftUI
import WebKit

struct ContentView: View {
    private var templates = "ローディング画面"
    
    var body: some View {
        WebView(htmlString: HTMLFile())
    }
    
    func HTMLFile() -> String {
        guard let url = Bundle.main.url(forResource: templates, withExtension: "html") else {
            return "<html><body><h1>Error: HTML file not found</h1></body></html>"
        }
        do {
            var htmlContent = try String(contentsOf: url, encoding: .utf8)
            return htmlContent
        } catch {
            return "<html><body><h1>Error loading HTML file</h1></body></html>"
        }
    }
}


struct WebView: UIViewRepresentable {
    let htmlString: String
    
    func makeUIView(context: Context) -> WKWebView {
        let configuration = WKWebViewConfiguration()
        let userContentController = WKUserContentController()
        userContentController.add(context.coordinator, name: "goBack")
        configuration.userContentController = userContentController
        
        let webView = WKWebView(frame: .zero, configuration: configuration)
        webView.navigationDelegate = context.coordinator
        return webView
    }
    
    func updateUIView(_ uiView: WKWebView, context: Context) {
        let baseURL = Bundle.main.bundleURL
        uiView.loadHTMLString(htmlString, baseURL: baseURL)
    }
    
    func makeCoordinator() -> Coordinator {
        return Coordinator(self)
    }
    
    class Coordinator: NSObject, WKNavigationDelegate, WKScriptMessageHandler {
        var parent: WebView
        
        init(_ parent: WebView) {
            self.parent = parent
        }
        
        func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
            if message.name == "goBack" {
                DispatchQueue.main.async {
                    //ここに戻る処理を書く
                }
            }
        }
    }
}

```

以下に簡単な解説を載せます。
- `ContentView`: SwiftUIのビューを定義しています。
- `templates`: 表示したいHTMLファイルの名前を指定するプロパティです。
- `userContentControllerメソッド`: JavaScriptからのメッセージを受け取って処理を行います。ここでは「goBack」というメッセージを受け取ると、指定された処理を実行します。

初めてHTMLがスマホで表示された時には「うぉーー！！」とテンションが上がりました。
トップページに戻るなどの画面遷移はHTMLに以下のように書きました。
```html
<button onclick="window.webkit.messageHandlers.goBack.postMessage('')">Home</button>
```
goBackに送られるメッセージを受け取ったら、ステートを変化させて画面遷移を実現しました。
あとはClaudeをフル活用し、エラーを解消したり機能追加したりしてアプリ開発を行いました。

# WebViewでアプリを作成するときの注意点
[App Store Reviewガイドライン](https://developer.apple.com/jp/app-store/review/guidelines/#design)には以下のように書かれています。

> 4.2 最低限の機能
アプリを作成する際は、Webサイトを単に再パッケージしたようなものではなく、優れた機能、コンテンツ、UIを作成するようにしてください。特に利便性も独自性もなく、アプリらしさもない場合、そのアプリをApp Storeで提供することはできません。アプリが継続的に楽しめる何らかの価値、または十分な有用性を備えていない場合は、承認されない可能性があります。アプリが単に曲または映画のみである場合は、iTunes Storeに提出してください。アプリが単に書籍またはゲームの攻略本のみの場合は、Apple Books Storeに提出してください。

ただ単にWebサイトをアプリとして配布するのはいけないようです。この点には注意したいですね。

# まとめ

以上が、まったくのiOSアプリ初心者である私が5日間でアプリを作り上げた方法です。WebViewを活用し、爆速でプロトタイプを作ることができました。これからiOSアプリ開発を始める方にとって、少しでも参考になれば幸いです。