How to show in-app web browser in iOS apps

May 07, 2023#ios

In iOS, an in-app browser is a component of an app that allows users to view web content within the app, rather than opening the default browser app. This can provide a more seamless user experience and make it easier for users to access web content without leaving the app.

WebKit.WKWebView

WKWebView is a class in iOS and macOS that provides a modern, efficient, and feature-rich way to display web content in an app. It was introduced in iOS 8 and macOS 10.10 as a replacement for the older UIWebView class, and offers significant performance improvements and new features.

WKWebView is based on the WebKit engine, which is also used by Apple’s Safari browser. It provides a number of advantages over UIWebView, including faster JavaScript performance, improved scrolling and zooming, and support for modern web technologies such as HTML5 and CSS3.

import UIKit
import WebKit

class ViewController: UIViewController, WKNavigationDelegate {
    
    var webView: WKWebView!

    override func viewDidLoad() {
        super.viewDidLoad()
        
        webView = WKWebView(frame: view.bounds)
        webView.navigationDelegate = self
        view.addSubview(webView)
        
        if let url = URL(string: "https://www.example.com") {
            let request = URLRequest(url: url)
            webView.load(request)
        }
    }
    
    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        print("Finished loading")
    }
    
    func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
        print("Navigation failed with error: \(error.localizedDescription)")
    }
}

SafariServices.SFSafariViewController

SFSafariViewController is a view controller provided by the SafariServices framework that allows you to display web content in your app using Safari’s rendering engine, while still staying within your app.

SFSafariViewController provides a complete Safari browsing experience within an app. It includes features such as URL completion, bookmarks, and reader mode, and provides a consistent user interface with Safari.

class ViewController: UIViewController, SFSafariViewControllerDelegate {
    
    var safariVC: SFSafariViewController?

    override func viewDidLoad() {
        super.viewDidLoad()
        
        if let url = URL(string: "https://www.example.com") {
            safariVC = SFSafariViewController(url: url)
            safariVC?.delegate = self
            present(safariVC!, animated: true, completion: nil)
        }
    }
    
    func safariViewControllerDidFinish(_ controller: SFSafariViewController) {
        print("Safari view controller finished")
    }
    
    func safariViewController(_ controller: SFSafariViewController, didCompleteInitialLoad didLoadSuccessfully: Bool) {
        print("Safari view controller completed initial load with success: \(didLoadSuccessfully)")
    }
}

AuthenticationServices.ASWebAuthenticationSession

ASWebAuthenticationSession is a class provided by the AuthenticationServices framework that allows you to authenticate a user with a web service, such as signing in with Apple, using a web-based login flow.

import AuthenticationServices

class ViewController: UIViewController {

    var authSession: ASWebAuthenticationSession?

    override func viewDidLoad() {
        super.viewDidLoad()

        let authURL = URL(string: "https://www.example.com/authenticate")!
        let callbackURLScheme = "myapp://auth-callback"

        authSession = ASWebAuthenticationSession(url: authURL, callbackURLScheme: callbackURLScheme) { (url, error) in
            guard error == nil, let url = url else {
                print("Authentication failed: \(error?.localizedDescription ?? "unknown error")")
                return
            }

            // Handle the authentication success and retrieve the access token from the URL
            let components = URLComponents(url: url, resolvingAgainstBaseURL: true)
            let accessToken = components?.queryItems?.first(where: { $0.name == "access_token" })?.value
            print("Access token: \(accessToken ?? "none")")
        }
        
        authSession?.presentationContextProvider = self
        authSession?.start()
    }
}

UIKit.UIWebView

UIWebView is a deprecated class that was used in older versions of iOS for displaying web content. Apple recommends using WKWebView instead, which is a more modern and performant class. However, if you still need to use UIWebView for some reason, here’s a basic overview of how to use it:

class ViewController: UIViewController, UIWebViewDelegate {

    var webView: UIWebView!

    override func viewDidLoad() {
        super.viewDidLoad()

        webView = UIWebView(frame: view.bounds)
        webView.delegate = self
        view.addSubview(webView)

        let url = URL(string: "https://www.example.com")!
        let request = URLRequest(url: url)
        webView.loadRequest(request)
    }

    // UIWebViewDelegate callback for page loading
    func webViewDidFinishLoad(_ webView: UIWebView) {
        print("Web page finished loading!")
    }
}