In an iOS app, it might be useful to provide some information already available on a website without a Link
. In today’s post, we’re going to look at how we can add a webpage to a SwiftUI view.
The source code of the post is available here.
Overview
Target: Create a SwiftUI view that displays a website (I’ll use Apple’s home page https://www.apple.com/ in the demo project).
Unfortunately, there still isn’t a native SwiftUI webview, however, we can create a UIView representable struct to have a UIView version embedded in a SwiftUI view. Continue reading to learn how.
Create a WebView struct
Create a SwiftUI project and add a new file called WebView
. The file type should be Swift source instead of SwiftUI View which might be selected by default.
In this new file, declare a struct WebView
and make it conform to UIViewRepresentable
. This is a protocol in SwiftUI (so you need to import SwiftUI first if you haven't done so), with which we can define a UIView as in UIKit and use its instances as SwiftUI views. Later we’ll need WKWebView
and related configurations from WebKit
to populate a UIView, so we need to import WebKit as well.
import SwiftUI
import WebKit
struct WebView: UIViewRepresentable {}
Conformance
After declaring the struct you might get an error, reminding you the type WebView
does not conform to the protocol UIViewRepresentable
. This is because the protocol defined two functions that needs to be implemented:
makeUIView(context) -> UIViewType
As the name suggests, it’s used to make, or define a UIView that would be used as a SwiftUI View. In this case, we can add some configurations to theWKWebView
in UIKit and return it together with the configurations.updateUIView(UIViewType, context)
This function will be used to modify the view further. For instance, after we defined theWKWebView
, we can use it to actually send a URL request to load the view with the webpage presented.
Let’s implement the WebView
as shown below.
Declare an optional URL, so that we can pass in a URL of a website for the URL call.
Implement the
makeUIView
function that returns aWKWebView
. Inside the function, we need to initialize a WKWebView with a configuration of JavaScript content policy. (Set it to true to avoid webpage presentation issues.)Implement the
updateView
function, in which theWKWebView
will be loaded with the URL request call.
import Foundation
import SwiftUI
import WebKit
struct WebView: UIViewRepresentable {
let url: URL?
func makeUIView(context: Context) -> WKWebView {
let prefs = WKWebpagePreferences()
prefs.allowsContentJavaScript = true
let config = WKWebViewConfiguration()
config.defaultWebpagePreferences = prefs
return WKWebView(
frame: .zero,
configuration: config)
}
func updateUIView(_ uiView: WKWebView, context: Context) {
guard let myURL = url else {
return
}
let request = URLRequest(url: myURL)
uiView.load(request)
}
}
Back to SwiftUI
Now let’s open the ContentView
file. Declare a URL property for the website. You can initiate a URL instance with the parameter of String.
private let url = URL(string: "https://www.apple.com/")
Then within the body
property, simply add a WebView
and pass the URL from above.
WebView(url: url)
Now you should be able to see the website in the preview. If you’d like to have the website shown in the safe area (such as the dynamic island or top-notch area), you can add a modifier .ignoresSafeArea()
struct ContentView: View {
private let url = URL(string: "https://www.apple.com/")
var body: some View {
ZStack {
WebView(url: url)
//.ignoresSafeArea()
}
}
}