hema
hema

Reputation: 1

WKwebview in swift

I have one viewController in xib and I m adding web view programatically and I have added a background colour to view and added a activityIndiactor to xib,Basically I want to show this view and activityIndicator when web view is getting loaded and once web view is finished I want to hide the view and stop activityIndicator and when I click any action in web view so then again show view and start activityLoader.I have pasted my code below any suggestion if any mistake I have done please free to guide me to achieve the above scenario and help me.

Running this below code is see dark view and no activityIndiator loading when web view is loading.

    //
    //  CustomWebViewController.swift
    //  WibmoPay
    //
    //  Created by Hemavathi on 10/07/18.
    //

    import UIKit
    import WebKit

    let kJavascriptFileName = "WibmoPayWebKitPostData"

    class CustomWebViewController: UIViewController,WKUIDelegate {
        @IBOutlet weak var LoadingView: UIView!
        var webView: WKWebView!
        var merchantDetails: WPMerchantDetails?
        var postedParams = false
        @IBOutlet weak var loadActivityIndicator: UIActivityIndicatorView!

        override func viewDidLoad() {
            super.viewDidLoad()
            self.navigationItem.hidesBackButton = true
            self.navigationItem.title = "Pay"
            let cancelBarBtn = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(CustomWebViewController.cancelTransaction(_:)))
            self.navigationItem.setRightBarButton(cancelBarBtn, animated: true)
            self.configureWebView()
        }

        /*
         Dismiss the controller and return from sdk to app
         */
        @objc private func cancelTransaction(_ sender: UIButton) {
            self.dismiss(animated: true, completion: nil)
        }

        /*
         Injected JavaScript html for showing webview
         */
        private func configureWebView(){
            let webConfiguration = WKWebViewConfiguration()
            self.webView = WKWebView(frame: self.LoadingView.frame,configuration: webConfiguration)
            self.LoadingView.addSubview(self.webView)
            webView.addSubview(self.loadActivityIndicator)
            webView.contentMode = .scaleToFill
            //webView.allowsBackForwardNavigationGestures = false
            //webView.autoresizesSubviews = true
            webView.scrollView.bounces = false
            //webView.scrollView.isScrollEnabled = false
            //automaticallyAdjustsScrollViewInsets = true
            webView.navigationDelegate = self

            let frameworkBundle = Bundle(for: WibmoPaySdk.self)
            let resourceBundle = Bundle(url: frameworkBundle.url(forResource: "WibmoPay", withExtension: "bundle")!)
            let javascriptFilePath = resourceBundle?.path(forResource: kJavascriptFileName, ofType: "html")
            let javascriptFileContents = try? String(contentsOfFile: javascriptFilePath!)
            self.webView.navigationDelegate = self
            self.webView.loadHTMLString(javascriptFileContents!, baseURL: frameworkBundle.bundleURL)
        }
    }

    /*
     WKWebView delegates
     */
    extension CustomWebViewController : WKNavigationDelegate {

        /*
         when URL is completed loaded this method is invoked
         */
        func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
            if postedParams == false {
                self.makePostRequest()
            }
            self.loadActivityIndicator.stopAnimating()
            self.LoadingView.isHidden = false
        }

        func makePostRequest() {
            var url = ""
            let postString: [String : String] = [SDKConstant.KEY_REQUEST_PARAM_CHECKSUM : merchantDetails!.generateCheckSumUsingSHA512,
                                                 SDKConstant.KEY_REQUEST_PARAM_MERCHANT_NAME :  merchantDetails!.merchantName,
                                                 SDKConstant.KEY_REQUEST_PARAM_MERCHANT_TXN_ID : merchantDetails!.merchantTxnId,
                                                 SDKConstant.KEY_REQUEST_PARAM_MERCHANT_AMOUNT : merchantDetails!.merchantTxnAmount,
                                                 SDKConstant.KEY_REQUEST_PARAM_MERCHANT_MESSAGE : merchantDetails!.merchantMessage,
                                                 SDKConstant.KEY_REQUEST_PARAM_MERCHANT_PAYMENT_OPTION : merchantDetails!.merchantPaymentOption,
                                                 SDKConstant.KEY_REQUEST_PARAM_PAYER_NAME : merchantDetails!.payerName,
                                                 SDKConstant.KEY_REQUEST_PARAM_PAYER_MOBILE_NO : merchantDetails!.payerMobile,
                                                 SDKConstant.KEY_REQUEST_PARAM_PAYER_EMAIL_ID : merchantDetails!.payerEmailId]

            var postParams = ""
            for param in postString {
                if let urlEncodedValue = param.value.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) {
                    postParams += "\(param.key):'\(urlEncodedValue)',"
                }
            }
            postParams = String(postParams.dropLast())
            if let wibmoPayURL = WibmoPaySdk.sdkManager.wibmoPayUrl{
            print("URL:\(String(describing: wibmoPayURL))")
            url = "\(wibmoPayURL)\(SDKConstant.API_PAYMENT_URL)"
            }else{
                WibmoPayError.inCorrectMerchantDetails(missingData: "URL is empty")
            }
            let jsEvaluator = "post('\(url)',{\(postParams)});"
            print(jsEvaluator)
            self.webView.evaluateJavaScript(jsEvaluator) { (result, error) in
                if let error = error {
                    print(error)
                }
            }
            postedParams = true

            print("webView URL:\(String(describing: webView.url))")
        }

        func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
            self.loadActivityIndicator.startAnimating()
            self.LoadingView.isHidden = true
            print("\(String(describing: webView.url))")
            var merchantName: String!
            var orderId: String!
            var merchantTxnId: String!
            var status: String!
            var paymentMode: String!
            var amount: String!
            var commission: String!
            var channel: String!

            if let redirectedUrl = webView.url, let merchantCbUrl = merchantDetails?.merchantCallbackUrl {
                if(redirectedUrl.absoluteString.hasPrefix(merchantCbUrl)) {
                    print("redirect url matching\(String(describing: redirectedUrl.host))")
                    if let responseData = redirectedUrl.query {
                        let params = responseData.components(separatedBy: "&")
                        for param in params {
                            let keyValue = param.components(separatedBy: "=")
                            print("keyValue\(String(describing: keyValue))")

                            if keyValue.first == "merchant_name"{
                                merchantName = keyValue.last
                                print(keyValue , "keyValue.first = \(merchantName)")
                                continue
                            } else if keyValue.first == "order_id"{
                                orderId = keyValue.last
                                print(keyValue , "keyValue.first = \(orderId)")
                                continue
                            } else if keyValue.first == "merchant_txn_id"{
                                merchantTxnId = keyValue.last
                                print(keyValue , "keyValue.first = \(merchantTxnId)")
                                continue
                            } else if keyValue.first == "status"{
                                status = keyValue.last
                                print(keyValue , "keyValue.first = \(status)")
                                continue
                            } else if keyValue.first == "payment_mode"{
                                paymentMode = keyValue.last
                                print(keyValue , "keyValue.first = \(paymentMode)")
                                continue
                            } else if keyValue.first == "amount"{
                                amount = keyValue.last
                                print(keyValue , "keyValue.first = \(amount)")
                                continue
                            }else if keyValue.first == "commission"{
                                commission = keyValue.last
                                print(keyValue , "keyValue.first = \(commission)")
                                continue
                            }else if keyValue.first == "channel"{
                                channel = keyValue.last
                                print(keyValue , "keyValue.first = \(channel)")
                                continue
                            } else {
                                print("key and value missing")
                            }
                        }

                        let merchantResponse = WibmoPayResponse(merchant_name: merchantName, order_id: orderId, merchant_txn_id: merchantTxnId, status: status, payment_mode: paymentMode, amount: amount, commission: commission, channel: channel)
                        WibmoPaySdk.sdkManager.transactionCompletionBlock?(merchantResponse,nil)
                        print("send data success")
                        self.webView!.stopLoading()
                        self.dismiss(animated: true, completion: nil)
                    }
                }else{
                    print("redirectedUrl not matching")
                }
            }
        }

    //    func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
    //        self.loadActivityIndicator.stopAnimating()
    //    }

        override var shouldAutorotate: Bool{
            return false
        }

    }

Some times I experience this error "Could not signal service com.apple.WebKit.WebContent: 113: Could not find specified service".with blank white screen showing up then I need to forcefully cancel to finish it. please help me solving this error and to achieve above senario, Any help would be appreciated. Thanks In Advance

Upvotes: 0

Views: 658

Answers (1)

shivi_shub
shivi_shub

Reputation: 1058

You can implement more delegates methods-

func webView(WKWebView,didCommit: WKNavigation!)

Called when the web view begins to receive web content.

func webView(WKWebView, didReceiveServerRedirectForProvisionalNavigation: WKNavigation!)

Called when a web view receives a server.

func webView(WKWebView, didFail: WKNavigation!, withError: Error)

Called when an error occurs during navigation.

Show and hide the view and activity indicAtor accordingly.

Upvotes: 3

Related Questions