swiftui-webkit
4
总安装量
3
周安装量
#49020
全站排名
安装命令
npx skills add https://github.com/makgunay/claude-swift-skills --skill swiftui-webkit
Agent 安装分布
opencode
3
claude-code
3
codex
3
cursor
3
gemini-cli
2
github-copilot
2
Skill 文档
SwiftUI WebKit Integration
Native WebView struct for SwiftUI. Replaces the old WKWebView + Representable bridge pattern.
Critical Constraints
- â DO NOT use
WKWebView+UIViewRepresentableorNSViewRepresentableâ â UseWebViewstruct directly - â DO NOT use
WKWebViewConfigurationâ â UseWebPage.Configuration - â DO NOT use
WKNavigationDelegateâ â UseWebPage.NavigationDecidingprotocol - â DO NOT use
evaluateJavaScript(_:)â â Usepage.callJavaScript(_:)(async/await) - â DO NOT use
WKUserContentControllerfor message passing â â UsecallJavaScriptwith arguments
Basic WebView
import SwiftUI
import WebKit
struct ContentView: View {
var body: some View {
WebView(url: URL(string: "https://www.apple.com"))
.frame(height: 400)
}
}
WebView with WebPage (Full Control)
struct BrowserView: View {
@State private var page = WebPage()
var body: some View {
NavigationStack {
WebView(page)
.navigationTitle(page.title)
}
.onAppear {
if let url = URL(string: "https://www.apple.com") {
let _ = page.load(URLRequest(url: url))
}
}
}
}
Text Search
struct SearchableWebView: View {
@State private var searchVisible = true
var body: some View {
WebView(url: URL(string: "https://www.apple.com"))
.findNavigator(isPresented: $searchVisible)
}
}
WebPage Configuration
var config = WebPage.Configuration()
config.loadsSubresources = true
config.defaultNavigationPreferences.allowsContentJavaScript = true
config.websiteDataStore = .default() // Persistent
// config.websiteDataStore = .nonPersistent() // Ephemeral
let page = WebPage(configuration: config)
page.customUserAgent = "MyApp/1.0"
Loading Content
// URL
page.load(URLRequest(url: url))
// HTML string
page.load(html: "<h1>Hello</h1>", baseURL: URL(string: "https://example.com")!)
// Data
page.load(data, mimeType: "text/html", characterEncoding: .utf8, baseURL: baseURL)
// Navigation
page.reload(fromOrigin: false)
page.stopLoading()
// Back/Forward
if let backItem = page.backForwardList.backItem {
page.load(backItem)
}
JavaScript Execution
// Basic
let title = try await page.callJavaScript("document.title")
// With arguments
let script = """
function findElement(selector) {
return document.querySelector(selector)?.textContent;
}
return findElement(selector);
"""
let result = try await page.callJavaScript(script, arguments: ["selector": ".main-content h1"])
// In specific content world
import WebKit
let result = try await page.callJavaScript("document.title", contentWorld: .page)
Navigation Events
.onChange(of: page.currentNavigationEvent) { _, newEvent in
if let event = newEvent {
switch event.state {
case .started: isLoading = true
case .finished, .failed: isLoading = false
default: break
}
}
}
Custom Navigation Decisions
struct MyNavigationDecider: WebPage.NavigationDeciding {
func decidePolicyFor(navigationAction: WebPage.NavigationAction) async -> WebPage.NavigationPreferences? {
if let url = navigationAction.request.url, url.host == "blocked.com" {
return nil // Block navigation
}
var prefs = WebPage.NavigationPreferences()
prefs.allowsContentJavaScript = true
return prefs
}
func decidePolicyFor(navigationResponse: WebPage.NavigationResponse) async -> Bool {
if let http = navigationResponse.response as? HTTPURLResponse {
return http.statusCode == 200
}
return true
}
}
let page = WebPage(configuration: config, navigationDecider: MyNavigationDecider())
Custom URL Scheme Handler
struct MySchemeHandler: URLSchemeHandler {
func start(task: URLSchemeTask) {
guard let url = task.request.url, url.scheme == "myapp" else {
task.didFailWithError(URLError(.badURL)); return
}
let html = "<html><body><h1>Custom Content</h1></body></html>"
let response = URLResponse(url: url, mimeType: "text/html",
expectedContentLength: -1, textEncodingName: "utf-8")
task.didReceive(response)
task.didReceive(Data(html.utf8))
task.didFinish()
}
func stop(task: URLSchemeTask) { }
}
var config = WebPage.Configuration()
config.setURLSchemeHandler(MySchemeHandler(), forURLScheme: "myapp")
Content Capture
// Snapshot
let image = try await page.snapshot(WKSnapshotConfiguration())
// PDF
let pdfData = try await page.pdf(configuration: WKPDFConfiguration())
// Web Archive
let archiveData = try await page.webArchiveData()
View Modifiers
WebView(url: url)
.webViewBackForwardNavigationGestures(.disabled)
.webViewMagnificationGestures(.enabled)
.webViewLinkPreviews(.disabled)
.webViewTextSelection(.enabled)
.webViewContentBackground(.color(.systemBackground))
.webViewElementFullscreenBehavior(.enabled)