iOS开发SwiftUI

SwiftUI: 打开 Safari (or default browser) with POST

前言

在Swift中,用Safari打开URL比较简单。但是这都是get请求。

假如我们需要用post请求先load Html页面,该如何处理呢?

     let url = URL(string: "https://www.baidu.com")
        //根据iOS系统版本,分别处理
        if #available(iOS 10, *) {
            // get打开
            UIApplication.shared.open(url!, options: [:],
                                      completionHandler: {(success) in
                                        print(success)
            })
        } else {
            // get打开
            UIApplication.shared.openURL(url!)
        }
解决方案

我们可以通过webView来解决,方案如下:

wkWebView post加载网页 –> wkWebView加载完成后,获取wkWebView的url –> 通过浏览器打开url

struct WebView: UIViewRepresentable {
    var url: String
    var text: String
    
    func makeUIView(context: Context) -> WKWebView {
        guard let url = URL(string: url) else {
            return WKWebView()
        }

        // 通过wkWebView Post loadHtml页面。
        let wkWebView = WKWebView()
        wkWebView.navigationDelegate = context.coordinator
        var request = URLRequest(url: url)
        request.addValue("application/json", forHTTPHeaderField: "Content-Type")
        request.httpMethod = "POST"
        let parameters = ["text": text] as [String: Any]
        let httpBodyData = try? JSONSerialization.data(withJSONObject: parameters, options: [])
        request.httpBody = httpBodyData
        wkWebView.load(request)

        return wkWebView
    }

    func updateUIView(_ uiView: UIViewType, context: UIViewRepresentableContext<WebView>) {}

    func makeCoordinator() -> WebView.Coordinator {
        Coordinator(self)
    }

    class Coordinator: NSObject, WKNavigationDelegate {
        var control: WebView

        init(_ control: WebView) {
            self.control = control
        }

        func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) {
            NotificationCenter.default.post(name: .loadWebPageError, object: error.localizedDescription, userInfo: nil)
        }

        func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
            if let url = webView.url?.absoluteString {
                print("url = \(url)")
                // 获取加载后的HTML的url,并且发送出去。
                NotificationCenter.default.post(name: .loadWebPageFinish, object: url, userInfo: nil)
            }
        }
    }
}
// 引用WebViewPost加载页面
WebView(url: "https://xxxxxxxxxxx", text: "test").frame(width: 1, height: 1).zIndex(1)
struct XXXXXXXView: View {
    

    var loadWebPageFinish = NotificationCenter.default.publisher(for: .loadWebPageFinish)
    var loadWebPageError = NotificationCenter.default.publisher(for: .loadWebPageError)

    var body: some View {
        VStack(spacing: 0) {
            }
        }.onReceive(loadWebPageFinish) { param in
            // 这里面获取到webview的url, 用浏览器打开。
            let url = URL(string: param.object as! String)
            UIApplication.shared.open(url!, options: [:],
                                      completionHandler: { _ in
                                      })
        }
    }
}