SwiftUI中WKWebView与UIViewRepresentable无法预览问题及解决方案
Xcode 14.2 SwiftUI预览报错“cannot preview file, invalid preview service message”的解决办法
问题描述
使用Xcode 14.2开发SwiftUI项目时,代码在真机上可正常运行,但所有视图均无法预览,预览窗口仅提示“cannot preview file, invalid preview service message”,无具体错误详情(项目中未使用持久化数据相关代码,可忽略)。
解决办法
将Xcode升级至14.3.1即可解决该预览报错问题。
参考代码
import SwiftUI import WebKit @main struct TestCitrixSwiftUIApp: App { let persistenceController = PersistenceController.shared let classFromEntryPoint = ClassFromEntryPoint() var body: some Scene { WindowGroup { ContentView() .environment(\.managedObjectContext, persistenceController.container.viewContext) .environmentObject(classFromEntryPoint) } } } struct ContentView: View { @EnvironmentObject var classFromEntryPoint: ClassFromEntryPoint @State var cookies: [HTTPCookie] = [] var body: some View { VStack { TextField("Insert exact url", text: $classFromEntryPoint.siteUrl) .textFieldStyle(RoundedBorderTextFieldStyle()) .padding() .submitLabel(.go) .onSubmit { classFromEntryPoint.loadValidUrl() } let _ = print("input: \(classFromEntryPoint.siteUrl)") if let url = URL(string: classFromEntryPoint.siteUrl) { LoadingWebView(url: url, shouldReload: $classFromEntryPoint.shouldReload, cookies: $cookies) .edgesIgnoringSafeArea(.all) } else { Spacer() Text("Not a valid URL") Spacer() } } } } struct LoadingWebView: View { let url: URL @State private var isLoading = true @State private var error: Error? = nil @Binding var shouldReload: Bool @Binding var cookies: [HTTPCookie] var body: some View { ZStack { WebView(url: url, isLoading: $isLoading, error: $error, shouldReload: $shouldReload, cookies: $cookies) .edgesIgnoringSafeArea(.all) if isLoading { ProgressView() } } } } struct WebView: UIViewRepresentable { let url: URL @Binding var isLoading: Bool @Binding var error: Error? @Binding var shouldReload: Bool @Binding var cookies: [HTTPCookie] func makeCoordinator() -> Coordinator { Coordinator(self) } func makeUIView(context: Context) -> WKWebView { let wkwebView = WKWebView() wkwebView.navigationDelegate = context.coordinator return wkwebView } func updateUIView(_ uiView: WKWebView, context: Context) { if shouldReload { uiView.load(URLRequest(url: url)) DispatchQueue.main.async { self.shouldReload = false } } } class Coordinator: NSObject, WKNavigationDelegate { var parent: WebView init(_ parent: WebView) { self.parent = parent } func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) { parent.isLoading = true } func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { parent.isLoading = false webView.configuration.websiteDataStore.httpCookieStore.getAllCookies { cookies in self.parent.cookies = cookies //foundamental print("found: \(cookies.count) cookies") } } func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) { parent.isLoading = false parent.error = error } } } class ClassFromEntryPoint: ObservableObject { @Published var siteUrl: String = "https://google.it" @Published var shouldReload: Bool = false init() { loadValidUrl() } func loadValidUrl() { let trimmedUrl = siteUrl.trimmingCharacters(in: .whitespacesAndNewlines) if !trimmedUrl.hasPrefix("http://") && !trimmedUrl.hasPrefix("https://") { siteUrl = "https://" + trimmedUrl } else { siteUrl = trimmedUrl } shouldReload.toggle() } } // Preview struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() .environmentObject(ClassFromEntryPoint()) } }
内容的提问来源于stack exchange,提问作者biggreentree
相关产品推荐
相关产品推荐

