beginnercoder
beginnercoder

Reputation: 133

How to open Safari View Controller from a Webview (swift)

I have an app that is currently using a webview and when certain links are clicked in the webview, it opens those links in Safari. I now want to implement the Safari View Controller(SVC) instead of booting it to the Safari app. I have done research and looked at examples on the SVC; however, all I see are ones that open the SVC from the click of a button. Does anyone have any suggestions for me to look at or to try?

Here is some of my code:

func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool {
    if navigationType == UIWebViewNavigationType.LinkClicked {
        let host = request.URL!.host!;
        if (host != "www.example.com"){
            return true
        } else {
            UIApplication.sharedApplication().openURL(request.URL!)
            return false
        }
    return true

}

func showLinksClicked() {

    let safariVC = SFSafariViewController(URL: NSURL(string: "www.example.com")!)
    self.presentViewController(safariVC, animated: true, completion: nil)
    safariVC.delegate = self    }

func safariViewControllerDidFinish(controller: SFSafariViewController) {
    controller.dismissViewControllerAnimated(true, completion: nil)
}

Upvotes: 12

Views: 34119

Answers (7)

Vinoth Anandan
Vinoth Anandan

Reputation: 1287

import SafariServices

class ViewController: UIViewController, SFSafariViewControllerDelegate {

 override func viewDidLoad() {
     super.viewDidLoad()
     DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
         let url = URL(string: "http://www.google.com")!
         let controller = SFSafariViewController(url: url)
         self.present(controller, animated: true, completion: nil)
         controller.delegate = self
     }
 }

 func safariViewControllerDidFinish(_ controller: SFSafariViewController) {
     dismiss(animated: true)
 }
}

Upvotes: 1

Bhumit Mehta
Bhumit Mehta

Reputation: 16318

If I am understanding correctly you are loading a page on webview which has certain links now when user clicks on link you want to open those page in SVC. You can detect link click in webview using following delegate method and then open SVC from there.

EDIT

Based on edited question I can see that you are not calling showLinksClicked func , you can call this function as I have updated in following code and it should work.

func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool {
    if navigationType == UIWebViewNavigationType.LinkClicked {
       self.showLinksClicked()
       return false

    }
    return true;
}


func showLinksClicked() {

    let safariVC = SFSafariViewController(url: URL(string: "www.google.com")!)
    present(safariVC, animated: true, completion: nil)
    safariVC.delegate = self
}

func safariViewControllerDidFinish(controller: SFSafariViewController) {
    controller.dismissViewControllerAnimated(true, completion: nil)
}

Upvotes: 18

Azharhussain Shaikh
Azharhussain Shaikh

Reputation: 1664

Swift 4.2

This is how you can open-up Safari browser within your application.

import SafariServices

whenever you want to open, like wise on

@IBAction func btnOpenWebTapped(_ sender: UIButton) {
    self.openWeb(contentLink: "https://www.google.com")
}

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    self.openWeb(contentLink: "https://www.google.com")
}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
     self.openWeb(contentLink: "https://www.google.com")
}

by write the custom function be like and you can customise the properties of the SFSafariViewController, preferredBarTintColor, preferredControlTintColor, dismissButtonStyle, barCollapsingEnabled

func openWeb(contentLink : String){
     let url = URL(string: contentLink)!
     let controller = SFSafariViewController(url: url)
     controller.preferredBarTintColor = UIColor.darkGray
     controller.preferredControlTintColor = UIColor.groupTableViewBackground
     controller.dismissButtonStyle = .close
     controller.configuration.barCollapsingEnabled = true
     self.present(controller, animated: true, completion: nil)
     controller.delegate = self
}

last and the most important thing is don't forget to bind the delegate of the SFSafariViewController with your view controller. you can do this by below mentioned extension code.

extension YourViewController: SFSafariViewControllerDelegate
{
    func safariViewControllerDidFinish(_ controller: SFSafariViewController) {
        controller.dismiss(animated: true, completion: nil)
    }
}

Happy coding Thank you :)

Upvotes: 1

Anup Gupta
Anup Gupta

Reputation: 2083

Solution For Swift 4

Step 1:

import Safari Service In you Class

import SafariServices

Step 2:

Import SFSafariViewControllerDelegate in With your View Controller

class ViewController: UIViewController,SFSafariViewControllerDelegate {...}

Step 3:

Create A function to Open Safari View Controller.

 func openSafariVC() {

            let safariVC = SFSafariViewController(url: NSURL(string: "https://www.google.com")! as URL)
            self.present(safariVC, animated: true, completion: nil)
            safariVC.delegate = self
        }

        func safariViewControllerDidFinish(_ controller: SFSafariViewController) {
            controller.dismiss(animated: true, completion: nil)
        }

Step 4:

call the function openSafariVC

openSafariVC()

Note: Don't forget To Add Navigation Controller with your View Controller.

Now your SafariVC is ready to open your Link within an app without Using UIWebView Oe WKWebView

Upvotes: 3

vikzilla
vikzilla

Reputation: 4138

For Swift 3:

First, import SafariServices and integrate the delegate into your class:

import SafariServices

class YourViewController: SFSafariViewControllerDelegate {

Then, to open Safari with the specified url:

let url = URL(string: "http://www,google.com")!
let controller = SFSafariViewController(url: url)
self.present(controller, animated: true, completion: nil)
controller.delegate = self

And now you can implement the delegate callback to dismiss safari when the user is finished:

func safariViewControllerDidFinish(_ controller: SFSafariViewController) {
    controller.dismiss(animated: true, completion: nil)
}

Upvotes: 14

Dipen Patel
Dipen Patel

Reputation: 933

Follow the steps :

On your controller file(e.g. ViewController.swift) import SafarriServices.

import SafariServices

Then where you want to open link write

let controller = SFSafariViewController(URL: NSURL(string: "https://www.google.co.uk")!)
self.presentViewController(controller, animated: true, completion: nil)
controller = self

Upvotes: 2

onemillion
onemillion

Reputation: 712

This piece of code will allow you to do this.

let safariVC = SFSafariViewController(URL: NSURL(string: "https://www.google.co.uk")!)
self.presentViewController(safariVC, animated: true, completion: nil)
safariVC.delegate = self

You may need to add this to the top of the class as well:

import SafariServices

Upvotes: 11

Related Questions