You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI:移除WebView点击操作,实现计时器自动启动及通知触发

解决方案:自动加载WebView并触发5秒后本地通知

Got it, let's tweak your code to remove the button requirement—so the WebView loads automatically, the timer starts right away, and the notification triggers after 5 seconds. Here's the revised code with key fixes to avoid common pitfalls like duplicate timers:

修改后的完整代码

import SwiftUI
import WebKit
import UserNotifications

struct ContentView: View {
    @State private var showPermissionAlert = false
    
    var body: some View {
        // 移除按钮包装,直接显示WebView
        WebView()
            .edgesIgnoringSafeArea(.all)
            .onAppear {
                // 在视图出现时自动请求通知权限并安排通知
                UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { (isGranted, error) in
                    if isGranted {
                        let content = UNMutableNotificationContent()
                        content.title = "HEAD"
                        content.body = "TEXT"
                        // 创建5秒后触发的一次性通知
                        let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 5, repeats: false)
                        let request = UNNotificationRequest(identifier: "autoNoti", content: content, trigger: trigger)
                        UNUserNotificationCenter.current().add(request, withCompletionHandler: nil)
                    } else {
                        // 权限未授予时显示提示alert(切换到主队列保证UI更新安全)
                        DispatchQueue.main.async {
                            showPermissionAlert = true
                        }
                    }
                }
            }
            .alert(isPresented: $showPermissionAlert) {
                Alert(title: Text("Please Enable Notification Access In Settings Panel !!!"))
            }
    }
}

struct WebView: UIViewRepresentable {
    // 使用Coordinator管理计时器,避免重复创建导致的资源浪费
    class Coordinator: NSObject {
        var timer: Timer?
    }
    
    func makeCoordinator() -> Coordinator {
        Coordinator()
    }
    
    func makeUIView(context: Context) -> WKWebView {
        let webView = WKWebView()
        webView.scrollView.isScrollEnabled = false
        return webView
    }
    
    func updateUIView(_ webView: WKWebView, context: Context) {
        let liveUrlString = "https://your-actual-url-here.com" // 替换为你的真实网页URL
        guard let url = URL(string: liveUrlString), webView.url != url else {
            // 如果WebView已经加载了目标URL,不再重复加载和创建计时器
            return
        }
        
        let request = URLRequest(url: url)
        webView.load(request)
        
        // 先销毁旧计时器(如果存在),再创建新的
        context.coordinator.timer?.invalidate()
        context.coordinator.timer = Timer.scheduledTimer(withTimeInterval: 5.0, repeats: true) { [weak webView] timer in
            guard let webView = webView else {
                timer.invalidate()
                return
            }
            webView.evaluateJavaScript("document.getElementById('ses').value") { (result, error) in
                if let error = error {
                    print("JavaScript evaluation error: \(error.localizedDescription)")
                } else {
                    print("Session value: \(result ?? "No value found")")
                }
            }
        }
    }
    
    // 视图销毁时清理计时器,防止内存泄漏
    static func dismantleUIView(_ webView: WKWebView, coordinator: Coordinator) {
        coordinator.timer?.invalidate()
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

关键修改说明

  • 移除按钮依赖:直接将WebView作为ContentView的主体内容,视图一出现就自动加载网页
  • 自动触发通知逻辑:把通知权限请求和通知创建逻辑移到onAppear修饰符中,无需用户手动点击触发
  • 修复重复计时器问题:使用Coordinator类持有计时器实例,每次加载新URL时先销毁旧计时器,避免多个计时器同时运行;同时在dismantleUIView中清理计时器,防止内存泄漏
  • 线程安全处理:更新showPermissionAlert时切换到主队列,确保UI操作在主线程执行
  • 避免重复加载:添加webView.url != url的判断,防止updateUIView被多次调用时重复加载同一个URL

内容的提问来源于stack exchange,提问作者Game Eagle

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 09:17:37