Swift, SwiftUI

Using SafariViewController to Open URLs in SwiftUI

One of the most common functionalities in mobile applications is opening a URL in a browser. In SwiftUI, this can be achieved by using the SafariViewController.

Suppose you are building a social media application that allows users to share links to interesting articles or websites. Rather than directing your users to a web browser, you can use SafariViewController to display the articles within your app. This provides a seamless browsing experience to your users and keeps them within your app.

In some cases, you may need more control over the presentation and behavior of the SafariViewController in your SwiftUI app. In these cases, you can use the UIViewControllerRepresentable protocol to wrap a UIKit view controller and use it in your SwiftUI app.

To display a SafariViewController using UIViewControllerRepresentable, follow the steps below:

  • Create a new file named SafariView.swift and add the following code:
import SafariServices
import SwiftUI

struct SafariView: UIViewControllerRepresentable {
  let url: URL
  func makeUIViewController(context: UIViewControllerRepresentableContext<SafariView>)
    -> SFSafariViewController
  {
    return SFSafariViewController(url: url)
  }

  func updateUIViewController(
    _ uiViewController: SFSafariViewController,
    context: UIViewControllerRepresentableContext<SafariView>
  ) {
    // Update the view controller when necessary
  }
}

The code defines a SafariView struct that conforms to the UIViewControllerRepresentable protocol. This allows us to use a SFSafariViewController within our SwiftUI app. The SafariView struct takes a url parameter which is the URL to be displayed in the SafariViewController.

The makeUIViewController method creates and returns an instance of SFSafariViewController with the specified url. The updateUIViewController method is called whenever the view controller needs to be updated, such as when the url parameter changes. In our case, we don’t need to update the view controller as there won’t be any changes.

In our SwiftUI view, we can use SafariView as a destination for a NavigationLink by passing an instance of SafariView with the appropriate url parameter.

  • In your SwiftUI view, create a list of articles and wrap each article in a NavigationLink. When the user taps on an article, it should present the SafariViewController.
struct ContentView: View {
  let articles = [
    Article(
      title: "The Power of Habit",
      url: URL(string: "https://www.nytimes.com/2012/02/19/magazine/shopping-habits.html")!),
    Article(
      title: "The Art of Procrastination",
      url: URL(
        string: "https://www.nytimes.com/2012/03/25/opinion/sunday/the-art-of-procrastination.html")!
    ),
    Article(
      title: "The Science of Happiness",
      url: URL(string: "https://greatergood.berkeley.edu/article/item/the_science_of_happiness/")!),
  ]

  var body: some View {
    NavigationView {
      List(articles) { article in
        NavigationLink(destination: SafariView(url: article.url)) {
          Text(article.title)
        }
      }
      .navigationBarTitle(Text("Articles"))
    }
  }
}

struct Article {
  let title: String
  let url: URL
}

With these simple steps, you can easily open a URL in SafariViewController in SwiftUI using UIViewControllerRepresentable. This provides you with more control over the presentation and behavior of the SafariViewController in your app.

In addition to opening URLs, SafariViewController also provides features like sharing, bookmarking, and navigation controls. This means that your users can easily share web content, bookmark their favorite sites, and navigate back and forth between web pages without ever leaving your app.

Overall, SafariViewController is a powerful tool that can enhance the user experience of your app by providing a seamless browsing experience to your users. By using UIViewControllerRepresentable, you can easily integrate SafariViewController into your SwiftUI app and provide your users with a secure and consistent browsing experience.