Links in SwiftUI

Links in SwiftUI

In Apps, there are many scenarios where you want to open a link, the link can be a web link, a link to an external app like mail, or phone, or any deep link. In this article, we will be take a look at Link API provided by SwiftUI to handle a different kind of links.

Links that directly open in the default web browser or external apps can be made using Link(). For example's sake, let's try a Link with text inits along with a destination URL.

struct ContentView: View {
    var body: some View {
        Link("Show google", destination: URL(string: "https://www.google.com")!) // 1 
    }
}

Code Explanation:

  1. Defining the link with text "Show Google" and destination set to URL of google.com.

Disclaimer: The usage of link force wrapping is highly discouraged in practice but since this is an example and we know that URL is not going to be nil, the link is force wrapped.

Like any other SwiftUI view, you can use view modifiers like .foregroundColor(), .background() and more.

Link("Show google", destination: URL(string: "https://www.google.com")!)
      .foregroundColor(.orange)

If you want something more than text to representing the link, you can Link with a different parameter :

Link(destination: URL(string: "https://www.apple.com")!) {
            HStack {
                Image(systemName: "applelogo")
                Text("Show Apple website")
            }.frame(width: 250, height: 70)
                .foregroundColor(Color.white)
                .background(Color.black)
                .cornerRadius(7)
        }

Here, we have an HStack with the SF symbol of apple icon and a text which says "Show Apple Website". To be a little fancy, we gave it a fixed frame, added corner radius, and changed the background color.

In-App WebView

In the above example, the SwiftUI link opened the article externally in the default browser. But what if you need a link that opens inside the app itself. For that, you need to put WKWebView in a UIViewRepresentable.

import WebKit

struct WebView : UIViewRepresentable {
    @State var url: String // 1 


    func makeUIView(context: Context) -> some UIView {
        let webView = WKWebView(frame: .zero) // 2 
        webView.load(URLRequest(url: URL(string: url)!)) // 3 
        return webView
    }

    func updateUIView(_ uiView: UIViewType, context: Context) {} // 4 
}


struct ContentView: View {
    @State var showWebView = false
    var body: some View {
        Button {
            self.showWebView = true
        } label: {
            Text("Show Web View")
        }.fullScreenCover(isPresented: $showWebView) {
            WebView(url: "https://www.swiftanytime.com")
        }
    }
}
  1. Defining a state variable for getting the URL string

  2. Initializing a WKWebView with frame set to zero.

  3. Loading a URLRequest with URL init where you the state variable URL.

  4. Passing an empty block of code in updateUIView(...) since no updates are been done to WKWebView throughout.

You can customize the webview more but that is topic of another SwiftAnytime article.

Congratulations! Today you learned about two ways to present link in your SwiftUI app - the native way using Link() and the UIKit way via UIViewRepresentable.