LoginSignup
4
2

More than 3 years have passed since last update.

iOS10でもWKWebViewを使ってPOSTしたい

Posted at

はじめに

初心者のハマりどころのひとつと思われるWebViewにまつわる話です(私もiOS初心者です)。
iOS10でWKWebViewを使用してPOSTでリクエストする時、httpBodyがnilになるというバグがあるようです。
バグについては、iOS10までとiOS11以降で検証されているこちらの記事が分かりやすいです。
解決策はこちらの記事を参考にしました。

前提条件

XCode 10.2.1
Swift4
DeploymentTarget: iOS10

解決案

今回は「はじめに」の参考にした記事で紹介されている、「URLSessionDataTaskで取得したデータをWKWebViewの以下のメソッドに渡す」方法で対応しました。

まずはURLSessionでリクエストを送信する処理を追加していきます。
今回はデータをjson形式にして送ります。
do-catch内でURLSessionDataTaskにリクエストの内容を渡して、リクエストを開始します。

ViewController.swift
    @IBOutlet weak var webViewContainer: UIView!
    private let url = "http://xxx.xxx.x.x"

    override func viewDidLoad() {
        super.viewDidLoad()

        let config = URLSessionConfiguration.default
        let session = URLSession(configuration: config, delegate: self, delegateQueue: nil)

        var request = URLRequest(url: URL(string: url)!)
        request.httpMethod = "POST"
        request.addValue("application/json", forHTTPHeaderField: "Content-Type")

        let params: [String: String] = [
            "hoge": "hoge",
            "huga": "huga"
        ]

        do {
            request.httpBody = try JSONSerialization.data(withJSONObject: params, options: .prettyPrinted)
            let task = session.dataTask(with: request as URLRequest)
            task.resume()
        } catch {
            print(error.localizedDescription)
        }
    }

URLSessionDataDelegateに、URLSessionで受け取ったデータをWebViewに渡す処理を実装します。UIを更新する処理なのでメインスレッドで行う必要があります。DispatchQueueを使ってメインスレッドでWebViewのロードを行います。

ViewController.swift
extension ViewController: URLSessionDataDelegate {

    func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) {

        DispatchQueue.main.async(execute: {
            let webView = WKWebView(frame: self.webViewContainer.bounds)
            self.webViewContainer.addSubview(webView)
            webView.load(data, mimeType: "text/html", characterEncodingName: "UTF-8", baseURL: URL(string: self.url)!)
        })
    }
}

Web側のソースです。
今回はローカルにXAMPPを入れてテストします。

test.php
<?php
    $json = file_get_contents('php://input');
    echo $json;

結果

以下のようにパラメータが表示されれば成功です。
iPhoneSE_iOS10_0.png

まとめ

iOS13が発表されましたが、iOS10がサポートされている間は、この手法を使うことがあるかもしれません。ただ私はまだiOSの経験が浅いですし、この実装方法で正しいか分かりませんので、もっといい方法があれば知りたいです。

参考

iOS(swift)ガワアプリの作成で色々苦労した話
iOSのWKWebViewの3つのつまずきポイントと解決方法
SwiftでjsonをphpへPOSTする

4
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
4
2