2

I'm using Smooch library for integration chat into the app. In addition, I've implemented Universal Links.

Programming language - Swift / iOS version - 12.4+ / Smooch SDK version 7.12

Problem:

  • When I am tapping on the link from Smooch chat it opens me Safari browser instead webView!!! Universal link works correctly, I can be redirected by tapping on the link from other Apps (WhatsApp, Safari, telegram ...)

But just taping in the link from the smooch chat redirects me to the Safari browser. How I can stay in the App?

Here main VC where I'm loading webView and button with Smooch chat:

override func viewDidLoad() {
    super.viewDidLoad()
    if let data = userDefaults.dictionary(forKey: "data"){
        responseData = data
    }
    loadWebKit()
    checkToken()
    initSmooch()
    setupChatBtnView()
}


//showing smooch chat view
@IBAction func chatBtnDidPress(_ sender: UIButton) {
    Smooch.show()

}

//chat button design
func setupChatBtnView(){
    chatBtnOutlet.layer.cornerRadius = chatBtnOutlet.bounds.self.width / 2.0
    chatBtnOutlet.clipsToBounds = true
    chatBtnOutlet.layer.shadowRadius = 1
    chatBtnOutlet.layer.shadowColor = UIColor(red: 255/255, green: 170/255, blue: 0/255, alpha: 0.5).cgColor
    chatBtnOutlet.layer.shadowOpacity = 0.5
    chatBtnOutlet.layer.shadowOffset = CGSize(width: 0.0, height: 3.0)
    chatBtnOutlet.layer.masksToBounds = false
}

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(true)
    Smooch.close()
}

//webkit view url load and adding js event listeners
func loadWebKit(){
    webView.navigationDelegate = self
    webView.configuration.userContentController.add(self, name: "finishLoading")
    webView.configuration.userContentController.add(self, name: "logout")
    webView.isHidden = true
    activityIndicator.isHidden = false

    if appDelegate.externalUrl == nil {
        webView.load(URLRequest(url: URL(string: "https://example.com")!))
    } else {
        deepLinkURL = self.appDelegate.externalUrl!
        let urlRequest = URLRequest(url: deepLinkURL!)
        self.webView.load(urlRequest)
        isFromDeepLing = true
        webView.isHidden = true
        activityIndicator.isHidden = false
        print(urlRequest)

    }
}

//when loading url finish call a js functions
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
    guard let dataForJS = userDefaults.string(forKey: "dataJs") else {
        self.webView.isHidden = false
        self.activityIndicator.isHidden = true
        return
    }

    if !isFromDeepLing {
        webView.evaluateJavaScript("handleNativeLogin('\(dataForJS)')") { (result, error) in
            self.webView.isHidden = false
            self.activityIndicator.isHidden = true
        }
    } else {
        if !isUsedDeepLink {
            webView.evaluateJavaScript("handleNativeLogin('\(dataForJS)')") { (result, error) in
            }
            webView.isHidden = true
            activityIndicator.isHidden = false
            DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) {
                let urlRequest = URLRequest(url: self.deepLinkURL!)
                self.webView.load(urlRequest)
                self.isUsedDeepLink = true
            }
        } else {
            self.webView.isHidden = false
            self.activityIndicator.isHidden = true
        }
    }
}

//segue to login screen and logout from smooch
func goToLoginScreen(){
    Smooch.logout {(error:Error?, userInfo:[AnyHashable : Any]?) in

    }
    userDefaults.removeObject(forKey: "data")
    performSegue(withIdentifier: "loginViewController", sender: self);
}

// check if token is valid . if not, go to login screen
func checkToken(){
    if let token = userDefaults.dictionary(forKey: "data")?["access_token"]{
        serverManager.checkToken(token: token as! String) { (code) in
            if(code == "200"){
                print("token is valid")
            }else if(code == "401"){
                print("token expierd")
                self.goToLoginScreen()
            }
        }
    }
}

// connect to smooch service , init and login
func initSmooch(){
    guard let appId = responseData["smoochAppId"] ,let userId = responseData["smoochUserId"], let smoochToken = responseData["smoochJWTToken"] else {
        chatBtnOutlet.isHidden = true
        return
    }
    Smooch.initWith(SKTSettings(appId: appId as! String)) { (error:Error?, userInfo:[AnyHashable : Any]?) in
        if(error == nil){
            print("smooch init success")
            Smooch.login(userId as! String , jwt: smoochToken as! String, completionHandler: { (error:Error?, userInfo: [AnyHashable : Any]?) in
                if(error == nil){
                    print("smooch user login success")
                }else{
                     print("smooch user login failed")
                }
            })
        }else{
             print("smooch init failed")
        }
    }
}

// listen to js event
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
    if(message.name == "finishLoading"){
        print("finishLoading")

    }else if (message.name == "logout"){
        userDefaults.set(false, forKey: "isLoggedIn")
        self.goToLoginScreen()
    }
}

And here appDelegate where I'm using Universal link:

 // MARK: - Deep Linking

func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {

    guard userActivity.activityType == NSUserActivityTypeBrowsingWeb,
        let url = userActivity.webpageURL else { return false }

    var viewController = UIViewController()

    let userDefaults = UserDefaults.standard
    let isLoggedIn = userDefaults.bool(forKey: "isLoggedIn")

    if url.path == "/login" || isLoggedIn == false {
        viewController = self.getDestinationLogin(for: url)
    } else {
        viewController = self.getDestinationMain(for: url)
    }
    externalUrl = url
    window?.rootViewController = viewController
    window?.makeKeyAndVisible()
    return (parseAppLinks(from: url) != nil)
}

 func getDestinationLogin(for url: URL) -> UIViewController {
    let storyboard = UIStoryboard(name: "Main", bundle: .main)
    let loginVC = storyboard.instantiateViewController(withIdentifier: "loginViewController") as? LoginViewController
    return loginVC!
}

func getDestinationMain(for url: URL) -> UIViewController {
    let storyboard = UIStoryboard(name: "Main", bundle: .main)
    let mainVC = storyboard.instantiateViewController(withIdentifier: "MainViewController") as? MainViewController
    let userDefaults = UserDefaults.standard
    userDefaults.set(true, forKey: "isLoggedIn")

    return mainVC!
}

private func parseAppLinks(from url: URL) -> String? {
   guard let components = URLComponents(url: url, resolvingAgainstBaseURL: true)  else { return .none }
   guard let urlString = components.queryItems?.first?.value else { return .none }

   return urlString
}
  • It looks like this is an open issue with the Smooch library, please see here https://github.com/smooch/smooch-ios/issues/33. This link is integrated with the rest of the text showing in the chat message? Can you please share some code so I can see how you trying to have the link open with the WebView? Thanks. – shbedev Nov 22 '19 at 08:05
  • Wow, this issue has opened 5 years ago... I've edited my answer with code samples. Thanks @Sam – Nikita Koniukh Nov 24 '19 at 06:37

0 Answers0