Swift WKWebView 實(shí)現(xiàn)支付寶师妙,微信支付流程

公司做微信和支付寶支付時(shí)采用了h5的方式。我是使用swift開發(fā)的镀虐,所以選擇使用WKWebView箱蟆。
1.使用webview必然會(huì)有js交互沟绪。就會(huì)使用到evaluateJavaScript為h5傳參數(shù)刮便。
2.做h5支付寶支付的時(shí)候,我們必須使用到WKWebView這個(gè)代理方法绽慈,就是一個(gè)截取navigationAction.request.url?.scheme的值為alipay恨旱。這個(gè)是我們進(jìn)行app間跳轉(zhuǎn)的URLScheme辈毯,通過白名單跳轉(zhuǎn)。當(dāng)然支付完成后我們也需要返回到自己的app 中搜贤。在獲取alipay的網(wǎng)址中會(huì)有一個(gè)fromAppUrlScheme字段谆沃,這個(gè)就是我們app自己的URLScheme。直接上代碼仪芒。

 func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void){

    let urlScheme = navigationAction.request.url?.scheme ?? ""
    let urlStr = navigationAction.request.url?.absoluteString ?? ""
    if urlScheme == "alipay"{

        UIApplication.shared.open(handleAlipayUrl(url: URL.init(string: urlStr)!)!, options: [:]) { (bo) in
        }
        print("dsfsdf ====\(urlScheme) ======\(urlStr)")
        decisionHandler(WKNavigationActionPolicy.cancel)

    }
  
    else{
    decisionHandler(WKNavigationActionPolicy.allow)
    }


}
fileprivate func handleAlipayUrl(url: URL) -> URL? {
    if url.absoluteString.hasPrefix("alipay://alipayclient/") {
        // 更換scheme
        var decodePar = url.query ?? ""
        decodePar.urlDecode()
        var dict = ValidateManager.jsonToDictionary(jsonString: decodePar)
        dict["fromAppUrlScheme"] = "myappScheme"
        if let strData = try? JSONSerialization.data(withJSONObject: dict , options: []) {
            var param = String(data: strData, encoding: .utf8)
            param?.urlEncode()
            let finalStr = "alipay://alipayclient/?\(param ?? "")"
            if let finalUrl = URL(string: finalStr) {
                return finalUrl
            }
        }
        return url
    }
    return nil
}

2.微信的比較坑吧唁影,第一個(gè)坑就是支付完成后會(huì)跳轉(zhuǎn)到Safari瀏覽器中,第二個(gè)坑是不會(huì)有支付回調(diào)掂名。先解決第一個(gè)坑吧据沈,就是先要根據(jù)支付域名設(shè)置自己APP的URLScheme,這樣的話就可以在支付完成后返回到的我們自己的app中饺蔑,當(dāng)然需要在APPdelegate中處理這個(gè)回調(diào)锌介。

   func webView(_ webView: WKWebView, decidePolicyFor   navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {

    let urlScheme = navigationAction.request.url?.scheme ?? ""
    let urlStr = navigationAction.request.url?.absoluteString ?? ""
  if urlScheme == "weixin"{

        if UIApplication.shared.canOpenURL(URL.init(string: urlStr)!){
        UIApplication.shared.open(URL.init(string: urlStr)!, options: [:]) { (bo) in
        }
        print("dsfsdf ====\(urlScheme) ======\(urlStr)")
        decisionHandler(WKNavigationActionPolicy.cancel)
        }else{
            let url = URL.init(string: PayUrl)
            
            let request = NSURLRequest(url: url!)
            //加載請(qǐng)求
            webView.load(request as URLRequest)

            let alert = JLAlertView.init(title: "溫馨提示", detailText: "請(qǐng)先現(xiàn)在微信客戶端", customView: nil, cancelButtonTitle: "取消", otherButtonTitles: ["去下載"])
            alert?.show({ (index) in
                if index == 1{
                    UIApplication.shared.open(URL.init(string: "https://apps.apple.com/cn/app/wei-xin/id414478124")!, options: [:]) { (bo) in
                    }
                }
            })
            
        
            decisionHandler(WKNavigationActionPolicy.allow)
        }

    }else{
        if urlStr.range(of: "https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb") != nil && !self.isload{
                let array : Array = urlStr.components(separatedBy: "redirect_url=")
                self.redirect_url =  array[1]
                let rs = "******.cn://".urlDecoded
                let mNewUrl = array[0] + "redirect_url=\(rs)"
                let newURLS = URL(string: mNewUrl)
                var mRequest = URLRequest.init(url: newURLS!, cachePolicy: .useProtocolCachePolicy, timeoutInterval: 60)
                mRequest.setValue("******.cn://", forHTTPHeaderField: "Referer")
                webView.load(mRequest)
                self.isload = true

            decisionHandler(WKNavigationActionPolicy.cancel)
                return
        }
        self.isload = false
    decisionHandler(WKNavigationActionPolicy.allow)
    }
}

3.js調(diào)用原生方法這個(gè)就需要使用到WKWebview中WKUserScript和WKScriptMessageHandler的代理方法。我使用的最笨的方案猾警,因?yàn)榍岸藳]有時(shí)間處理孔祸,我只能通過頁面控件的id進(jìn)行處理點(diǎn)擊事件。

     let baiduButtonId = "back"
    let baiduMessage = "jsCallIOS"
    let scriptStr = "function fun(){window.webkit.messageHandlers.\(baiduMessage).postMessage(\"\(baiduButtonId)\");}(function(){var btn=document.getElementById(\"\(baiduButtonId)\");btn.addEventListener('click',fun,false);}());"
    let userScript = WKUserScript(source: scriptStr, injectionTime: .atDocumentEnd, forMainFrameOnly: true)
    let baiduButtonId1 = "back2"
    let baiduMessage1 = "jsCallIOS"
    let scriptStr1 = "function fun(){window.webkit.messageHandlers.\(baiduMessage1).postMessage(\"\(baiduButtonId1)\");}(function(){var btn=document.getElementById(\"\(baiduButtonId1)\");btn.addEventListener('click',fun,false);}());"
    let userScript1 = WKUserScript(source: scriptStr1, injectionTime: .atDocumentEnd, forMainFrameOnly: true)
    webView.configuration.userContentController.addUserScript(userScript1)
    webView.configuration.userContentController.addUserScript(userScript)
    webView.configuration.userContentController.add(self, name: baiduMessage)   
  func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
    print(message.body)
    let mess = message.body as! String
    if mess == "back"  {
    }
    if mess == "back2" {

    }
}

4.為webview添加加載進(jìn)度條和獲取標(biāo)題 在viewDidLoad中添加

    webView.addObserver(self, forKeyPath: "title", options: .new, context: nil)
    webView.addObserver(self, forKeyPath: "estimatedProgress", options: .new, context: nil)

實(shí)現(xiàn)觀察方法

 //添加觀察者方法
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
    //設(shè)置進(jìn)度條
    if keyPath == "estimatedProgress"{
        progressView.alpha = 1.0
        progressView.setProgress(Float(webView.estimatedProgress), animated: true)
        if webView.estimatedProgress >= 1.0 {
            UIView.animate(withDuration: 0.3, delay: 0.1, options: .curveEaseOut, animations: {
                self.progressView.alpha = 0
            }, completion: { (finish) in
                self.progressView.setProgress(0.0, animated: false)
            })
        }
    }
        
        //重設(shè)標(biāo)題
    else if keyPath == "title" {
        self.title = self.webView.title
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末发皿,一起剝皮案震驚了整個(gè)濱河市崔慧,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌雳窟,老刑警劉巖尊浪,帶你破解...
    沈念sama閱讀 221,198評(píng)論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異封救,居然都是意外死亡拇涤,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門誉结,熙熙樓的掌柜王于貴愁眉苦臉地迎上來鹅士,“玉大人,你說我怎么就攤上這事惩坑〉糁眩” “怎么了?”我有些...
    開封第一講書人閱讀 167,643評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵以舒,是天一觀的道長(zhǎng)趾痘。 經(jīng)常有香客問我,道長(zhǎng)蔓钟,這世上最難降的妖魔是什么永票? 我笑而不...
    開封第一講書人閱讀 59,495評(píng)論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上侣集,老公的妹妹穿的比我還像新娘键俱。我一直安慰自己,他們只是感情好世分,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,502評(píng)論 6 397
  • 文/花漫 我一把揭開白布编振。 她就那樣靜靜地躺著,像睡著了一般臭埋。 火紅的嫁衣襯著肌膚如雪踪央。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,156評(píng)論 1 308
  • 那天瓢阴,我揣著相機(jī)與錄音杯瞻,去河邊找鬼。 笑死炫掐,一個(gè)胖子當(dāng)著我的面吹牛魁莉,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播募胃,決...
    沈念sama閱讀 40,743評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼旗唁,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了痹束?” 一聲冷哼從身側(cè)響起检疫,我...
    開封第一講書人閱讀 39,659評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎祷嘶,沒想到半個(gè)月后屎媳,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,200評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡论巍,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,282評(píng)論 3 340
  • 正文 我和宋清朗相戀三年烛谊,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,424評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖粤铭,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情双泪,我是刑警寧澤,帶...
    沈念sama閱讀 36,107評(píng)論 5 349
  • 正文 年R本政府宣布密似,位于F島的核電站焙矛,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏残腌。R本人自食惡果不足惜村斟,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,789評(píng)論 3 333
  • 文/蒙蒙 一剪返、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧邓梅,春花似錦、人聲如沸邑滨。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽掖看。三九已至匣距,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間哎壳,已是汗流浹背毅待。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評(píng)論 1 271
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留归榕,地道東北人尸红。 一個(gè)月前我還...
    沈念sama閱讀 48,798評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像刹泄,于是被迫代替她去往敵國(guó)和親外里。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,435評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容

  • 本文只討論你已經(jīng)成功實(shí)現(xiàn)客戶端->支付寶支付流程特石,僅僅是支付完成后無法返回自己的APP的問題盅蝗。 如果你的支付流程是...
    魔力雙魚閱讀 14,624評(píng)論 3 12
  • 1、WKWebView 白屏問題WKWebView 自詡擁有更快的加載速度姆蘸,更低的內(nèi)存占用墩莫,但實(shí)際上 WKWebV...
    無名感恩閱讀 2,137評(píng)論 0 3
  • WKWebView 是蘋果在 WWDC 2014 上推出的新一代 webView 組件,用以替代 UIKit 中笨...
    Aiana閱讀 4,590評(píng)論 1 8
  • 轉(zhuǎn)載:http://www.cnblogs.com/NSong/p/6489802.html 導(dǎo)語 WKWebVi...
    李小威閱讀 4,861評(píng)論 8 9
  • 人與人之間最大的差別在哪里逞敷。 拖延------導(dǎo)致你做的事情會(huì)一天到一天狂秦,到最后的期限就沒有盡力地完成領(lǐng)導(dǎo)布置,導(dǎo)...
    江公子plus閱讀 177評(píng)論 0 1