iOS-SwiftはHybrid開発に迅速に進出

6867 ワード

前言:
Hybrid(ハイブリッド)開発は現在のapp開発でかなり一般的であり,iOS側からHybrid開発への迅速な導入を目的としている.
本文:
まず、ハイブリッド開発がなぜ必要なのかを理解してみましょう.AndroidでもiOSでも、オリジナル開発のみを採用している場合は、変更のたびにアプリケーションをパッケージ化してアプリケーションストアに配布し、監査が成功した後、ユーザーが新しいバージョンをインストールしてから使用する必要があります.これは間違いなく時間を無駄にしたに違いない.変化しやすいページをhtmlに置き、プログラムの固定モジュールをオリジナルで開発することを自然に思い浮かべます.すなわち、クライアントがh 5(すなわちwebフロントエンド、後文ではh 5と略称する)のページにアクセスし、必要な機能を完了する.
h 5のページは,展示機能だけでなくユーザの操作も含むため,クライアントとh 5の相互呼び出しも必要であり,webViewで表示するだけでは十分ではない.例えば、h 5ページに写真をアップロードする必要がある場合は、クライアントがh 5に写真を渡す必要があります.ここでh 5はカメラやアルバムを開くようクライアントに要求する必要があり、クライアントが写真を選択した後もh 5にアップロードする必要がある.では、今日のテーマ、Hybrid開発に入りました.
Hybrid開発の基礎は2点にある.
1:クライアントによるh 5の呼び出し
ここの肝心な方法は一つしかない.
webView.evaluateJavaScript(javascriptString, completionHandler: nil)
ここでwebViewはWKWebViewの例である.WKWebViewは、iOS 8以降にアップルが発売したフレームワークWebKitのブラウザコントロールで、UIWebViewよりもロード速度が大幅に速くなったが、メモリ使用率が大幅に低下し、Webページのロード時のメモリ漏洩問題も解決した.現在のプロジェクトの多くはiOS 8に適しているだけなので、プロジェクトのUIWebViewをWKWebViewに置き換える必要があります.evaluateJavaScriptこの方法は、パラメータjavascriptStringがJSON形式の文字列であるjavaScriptをブラウザに渡す方法です.h 5にパラメータを渡すにしても、呼び出し方法にしても、実行される文をパラメータとして、WKWebView呼び出しevaluateJavaScriptを使用してh 5に渡される.
2.h 5クライアントの呼び出しを調整する
肝心な方法も一つしかない
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {}
WKScriptMessageHandlerプロトコルに従い,本手法ではh 5エンドで伝達されるイベントとパラメータを取得し,次にクライアントのオリジナルメソッドを呼び出す必要がある.イベントとパラメータには再messageパラメータのbody属性が含まれています
3.実例プレゼンテーション
ここではまず、WKWebViewを備え、進捗バーなどのコントロールをカプセル化したサードパーティ製ライブラリAXWebViewControllerをお勧めします.このコントローラを継承するだけでいいです.
(1)まずAXWebViewControllerを導入し、次にコントローラWebViewControllerを新規作成し、AXWebViewControllerをメインコントローラとして継承する.
import AXWebViewController
class WebViewController: AXWebViewController {}
(2)メインコントローラにextensionを追加し、AXWebViewControllerDelegateに従う
//MARK: -AXWebViewControllerDelegate
extension WebViewController: AXWebViewControllerDelegate {
    //    
    func webViewControllerDidStartLoad(_ webViewController: AXWebViewController) {}
    //    
    func webViewControllerDidFinishLoad(_ webViewController: AXWebViewController) {
        //DOM  , webView     
        //1.        
        webView.evaluateJavaScript("document.documetElement.style.webkitUserSelect='none';", completionHandler: nil)
        //2.         
        webView.evaluateJavaScript("document.documentElement.style.webkitTouchCallout='none';", completionHandler: nil)
        //3. h5        , :app   ,token 
        self.invokeJavascript(method: "dataInit", data: ["token":token,"platform":"iOS","appVersion":sysManager.appVersion,"UUID":SysManager.main.uuid()])
    }
    //    
    func webViewController(_ webViewController: AXWebViewController, didFailLoadWithError error: Error) {}
}
以上の3つのエージェントメソッドは,それぞれwebViewのロード開始,ロード完了,ロード失敗の3つの状態に対応している.ロードの開始とロードの失敗の2つのエージェントメソッドでは、独自のニーズに基づいて実現します.ロードに失敗したり、失敗したページを表示したりします.では、この方法のロードを完了することに重点を置きます.本手法では,1,2はそれぞれWKWebViewを直接呼び出すevaluateJavaScript手法であり,h 5への文注入は1に達する.ユーザーがテキストを選択することを禁止します.このジェスチャー3を押すことを禁止するのはh 5ページの基礎構成であり、その中で私たち自身が実現した方法、invokeJavascriptを呼び出し、h 5にjavaScriptを渡すことを目的としている.ここでのメソッドdataInitやパラメータtoken,バージョン番号などもh 5と約束している.
func utimesInvokeJavascript(method:String, data:Any?) {
        do {
            let jsonData =  try JSONSerialization.data(withJSONObject: data!, options: [])
            let para = String(data: jsonData, encoding: .utf8)
            let javaScriptString =  "window.bridge.emit('"+method+"',"+para!+")"
            webView.evaluateJavaScript(javaScriptString, completionHandler: { (_, error) in})
        } catch {
            print(error)
        }
}
以上のカスタムメソッドは,パラメータとメソッドをJSON文字列に変換してh 5に渡す.その中の「window.bridge.emit('」+method+',"+para!+")」もh 5と約束したフォーマットで受信します.
その後、javaScriptをh 5に注入する、すなわちh 5をクライアントに応答させるたびに、utimesInvokeJavascriptによってevaluateJavaScriptを呼び出すことができる.
(3)WKScriptMessageHandler合意に従う
//messageHanlderName  h5        
webView.configuration.userContentController.add(self, name: messageHandlerName)
実装プロトコルメソッド
//MARK: -WKScriptMessageHandler
extension WebViewController: WKScriptMessageHandler {
    //    h5           
    func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
        let dictionary = message.body as! Dictionary
        let method = dictionary["method"] as? String
        let args = dictionary["args"] as? Dictionary
        self.reflectMethod(method:method, args: args)
    }
}
h 5がクライアントに呼び出されると,パラメータオブジェクトを渡す必要があり,messageオブジェクトのbody属性に含まれる.この中のmethodとargsの2つのパラメータは呼び出しの方法とパラメータに対応し、h 5とクライアントが約束した方法でもあり、reflectMethodという方法はh 5のクライアントに対する呼び出しに応答するようにカスタマイズされている.
//  javascript        
    func reflectMethod(method:String?, args:Dictionary?) {
        if method == "goBack" {
            perform(#selector(back), with: args, afterDelay: 0.1)
        }
    }
    
    @objc func goBack() {
        navigationController?.popViewController(animated: true)
    }
例えばgoBackという方法を定義すると、h 5は約束通りにgoBack対応文字列をmethodパラメータに入れて渡すだけで、認識後にこの方法に応答することができます(4)h 5ページのロードに異常が発生した場合、以下のような場合があります.
1.h 5に必要なパラメータが伝達されていない可能性がある
//     AXWebViewControllerDelegate     
func webViewController(_ webViewController: AXWebViewController, didFailLoadWithError error: Error) {
        //       ,        
}
2.メモリが高すぎるため、複数回のアップロードなどのwebViewプロセスの終了を招く可能性があります.
//     WKNavigationDelegate, AXWebViewController  WKNavigationDelegate,       
override func webViewWebContentProcessDidTerminate(_ webView: WKWebView) {
        //   webView.reload()    ,        
}
(5)呼び出しが必要な場合は,WebViewControllerをインスタンス化するだけでよい.
let webController = WebViewController(address: urlString)   //urlString html  
navigationController?.pushViewController(vc, animated: true)
まとめ:
では、ポイントをまとめてみましょう.サードパーティ製コントローラAXWebViewControllerに続くコントローラを作成する.WKWebViewを使用して、webViewを通過します.evaluateJavaScript(javaScriptString,completionHandler:nil)javascriptをh 5に注入し、h 5端をクライアントの要求に応答させる.2.WKScriptMessageHandlerに従い、プロキシメソッドfunc userContentController(_userContentController:WKUserContentController,didReceive message:WKScriptMessage){}を実装、クライアントにh 5側要求3に応答させる.func webViewControllerDidFinishLoad(_webViewController:AXWebViewController){}でtoken,uuidなどのh 5側に必要な基本構成を完了する.JAvaScriptの転送フォーマットにはクライアントとh 5側の共通の約束が必要です
以上、iOS端末からHybridに素早くアクセスする方法ですが、好きな方はいいね~