
Swiftui Webkit
Embed and control in-app web content in SwiftUI iOS apps with WebKit loading, navigation gestures, and observable page state.
Install
npx skills add https://github.com/dpearson2699/swift-ios-skills --skill swiftui-webkitWhat is this skill?
- Simple `WebView(url:)` path with optional back-forward navigation gestures
- Controlled loading via `@Observable` `WebPage` models and async `load` streams
- Observe progress, title, and navigation events from embedded pages
- Support URL, HTML string, and raw data loads with MIME and base URL
- Ephemeral pages and custom user-agent patterns for isolated sessions
Adoption & trust: 1.3k installs on skills.sh; 713 GitHub stars; 2/3 security scanners passed (skills.sh audits).
Recommended Skills
Vercel React Native Skillsvercel-labs/agent-skills
Firebase Basicsfirebase/agent-skills
Building Native Uiexpo/skills
Firebase Ai Logic Basicsfirebase/agent-skills
Native Data Fetchingexpo/skills
Firebase Firestorefirebase/agent-skills
Journey fit
Primary fit
Canonical shelf is Build because the skill covers SwiftUI views and WebKit wiring while shipping a mobile product feature. Frontend fits UI composition (`WebView`, observation hooks) rather than backend APIs or agent orchestration.
Common Questions / FAQ
Is Swiftui Webkit safe to install?
skills.sh reports 2 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.
SKILL.md
READMESKILL.md - Swiftui Webkit
# Loading and Observation ## Contents - Simple `WebView(url:)` - Controlled `WebPage` loading - Observing progress and title - Observing navigation events - Ephemeral pages and custom user agents ## Simple `WebView(url:)` Use `WebView(url:)` when the app only needs to display a URL and does not need explicit page control. ```swift import SwiftUI import WebKit struct MarketingPageView: View { let url: URL var body: some View { WebView(url: url) .webViewBackForwardNavigationGestures(.enabled) } } ``` This is the lowest-friction path for embedded content. ## Controlled `WebPage` loading Create a `WebPage` when the app needs to drive loading itself. ```swift @Observable @MainActor final class ArticleModel { let page = WebPage() var lastError: String? func load(_ url: URL) async { do { for try await _ in page.load(URLRequest(url: url)) { } } catch { lastError = error.localizedDescription } } } ``` ```swift struct ArticleDetailView: View { @State private var model = ArticleModel() let url: URL var body: some View { WebView(model.page) .task { await model.load(url) } } } ``` You can also load: - `for try await _ in page.load(url) { }` - `for try await _ in page.load(html: htmlString, baseURL: baseURL) { }` - `for try await _ in page.load(data, mimeType: "text/html", characterEncoding: "utf-8", baseURL: baseURL) { }` ## Observing progress and title `WebPage` is observable, so SwiftUI can bind directly to its state. ```swift struct ReaderView: View { @State private var page = WebPage() var body: some View { WebView(page) .navigationTitle(page.title ?? "Loading") .overlay(alignment: .top) { if page.isLoading { ProgressView(value: page.estimatedProgress) .padding() } } .task { do { for try await _ in page.load(URLRequest(url: URL(string: "https://example.com/docs")!)) { } } catch { // Handle load failure. } } } } ``` Useful properties: - `title` - `url` - `isLoading` - `estimatedProgress` - `themeColor` - `hasOnlySecureContent` - `backForwardList` ## Observing navigation events Use `currentNavigationEvent` for a lightweight current-state view. Use `navigations` to observe the full sequence of navigation events. ```swift @MainActor func observeNavigations(for page: WebPage) { Task { for await event in page.navigations { switch event { case .finished: print("Navigation finished") case .failed(let error), .failedProvisionalNavigation(let error): print("Navigation failed: \(error)") default: break } } } } ``` This is the right place to trigger follow-up work like parsing headings after a finished navigation. ## Ephemeral pages and custom user agents Use `WebPage.Configuration` when you need a nonpersistent page, custom user agent, or tighter loading rules. ```swift @MainActor func makeMetadataPage() -> WebPage { var configuration = WebPage.Configuration() configuration.loadsSubresources = false configuration.defaultNavigationPreferences.allowsContentJavaScript = false configuration.websiteDataStore = .nonPersistent() let page = WebPage(configuration: configuration) page.customUserAgent = "MetadataBot/1.0" return page } ``` Use nonpersistent pages when you want an isolated web session or metadata fetch path without shared cookies or long-lived website data. # Local Content and Custom URL Schemes ## Contents - When to use custom schemes - Registering a scheme handler - Returning responses and data - Loading bundled content - Can