【问题标题】:Does clicking the back button calls applicationWillTerminate method in IOS?点击后退按钮会调用 IOS 中的 applicationWillTerminate 方法吗?
【发布时间】:2020-04-30 22:46:15
【问题描述】:

我只是想知道在 IOS 中单击后退按钮时是否调用了 applicationWillTerminate() 方法。所以现在,我在我的 ios 应用程序中有这个WKWebView,它加载了一个智能聊天 URL。如果用户对如何使用该应用程序有任何疑问,则可以使用此聊天机器人。我试图实现的是,当用户单击后退按钮并离开其中包含 WKWebView 的 UI 控制器时,不会保存用户与聊天机器人的先前对话。但是,如果从WKWebView 中单击主页按钮并且用户返回应用程序,则对话仍然存在。如果单击后退按钮,如何防止重新加载具有WKWebView 的 UI 控制器?

【问题讨论】:

    标签: ios swift wkwebview reload lifecycle


    【解决方案1】:

    首先,为什么 applicationWillTerminate 会在后退按钮上被调用,这只是为了弹出视图控制器,直到您明确退出应用程序。其次,您应该检查如何清除您的聊天机器人当前会话,这样无论何时您单击返回或在 viewdiddisappear 上,您都会清除聊天机器人会话,因此不会保存对话。我认为无论您使用什么聊天机器人,它们都会缓存对话,直到您从会话中注销或执行一些清理操作。

    -- 更新了 ---- 在自定义类部分 uistoryboard 中使用以下作为 WKWebview 父类

    import Foundation
    import WebKit
    
    class WKCookieWebView : WKWebView {
    
        private let useRedirectCookieHandling: Bool
    
        init(frame: CGRect, configuration: WKWebViewConfiguration, useRedirectCookieHandling: Bool = false) {
            self.useRedirectCookieHandling = useRedirectCookieHandling
            configuration.applicationNameForUserAgent = "Version/8.0.2 Safari/600.2.5"
            super.init(frame: frame, configuration: configuration)
        }
    
        required init?(coder: NSCoder) {
            self.useRedirectCookieHandling = false
            super.init(coder: coder)
        }
    
        override func load(_ request: URLRequest) -> WKNavigation? {
            guard useRedirectCookieHandling else {
                return super.load(request)
            }
    
            requestWithCookieHandling(request, success: { (newRequest , response, data) in
                DispatchQueue.main.async {
                    self.syncCookiesInJS()
                    if let data = data, let response = response {
                        let _ = self.webViewLoad(data: data, response: response)
                    } else {
                        self.syncCookies(newRequest, nil, { (cookieRequest) in
                            let _ = super.load(cookieRequest)
                        })
                    }
                }
            }, failure: {
                // let WKWebView handle the network error
                DispatchQueue.main.async {
                    self.syncCookies(request, nil, { (newRequest) in
                        let _ = super.load(newRequest)
                    })
                }
            })
    
            return nil
        }
    
        private func requestWithCookieHandling(_ request: URLRequest, success: @escaping (URLRequest, HTTPURLResponse?, Data?) -> Void, failure: @escaping () -> Void) {
            let sessionConfig = URLSessionConfiguration.default
            let session = URLSession(configuration: sessionConfig, delegate: self, delegateQueue: nil)
            let task = session.dataTask(with: request) { (data, response, error) in
                if let _ = error {
                    failure()
                } else {
                    if let response = response as? HTTPURLResponse {
    
                        let code = response.statusCode
                        if code == 200 {
                            // for code 200 return data to load data directly
                            success(request, response, data)
    
                        } else if code >= 300 && code <  400  {
                            // for redirect get location in header,and make a new URLRequest
                            guard let location = response.allHeaderFields["Location"] as? String, let redirectURL = URL(string: location) else {
                                failure()
                                return
                            }
    
                            let request = URLRequest(url: redirectURL, cachePolicy: .reloadIgnoringLocalAndRemoteCacheData, timeoutInterval: 5)
                            success(request, nil, nil)
    
                        } else {
                            success(request, response, data)
                        }
                    }
                }
            }
            task.resume()
        }
    
        private func webViewLoad(data: Data, response: URLResponse) -> WKNavigation! {
            guard let url = response.url else {
                return nil
            }
    
            let encode = response.textEncodingName ?? "utf8"
            let mine = response.mimeType ?? "text/html"
    
            return self.load(data, mimeType: mine, characterEncodingName: encode, baseURL: url)
        }
    }
    
    extension WKCookieWebView {
        // sync HTTPCookieStorage cookies to URLRequest
        private func syncCookies(_ request: URLRequest, _ task: URLSessionTask? = nil, _ completion: @escaping (URLRequest) -> Void) {
            var request = request
            var cookiesArray = [HTTPCookie]()
    
            if let task = task {
                HTTPCookieStorage.shared.getCookiesFor(task, completionHandler: { (cookies) in
                    if let cookies = cookies {
                        cookiesArray.append(contentsOf: cookies)
    
                        let cookieDict = HTTPCookie.requestHeaderFields(with: cookiesArray)
                        if let cookieStr = cookieDict["Cookie"] {
                            request.addValue(cookieStr, forHTTPHeaderField: "Cookie")
                        }
                    }
                    completion(request)
                })
            } else  if let url = request.url {
                if let cookies = HTTPCookieStorage.shared.cookies(for: url) {
                    cookiesArray.append(contentsOf: cookies)
                }
                let cookieDict = HTTPCookie.requestHeaderFields(with: cookiesArray)
                if let cookieStr = cookieDict["Cookie"] {
                    request.addValue(cookieStr, forHTTPHeaderField: "Cookie")
                }
                completion(request)
    
            } else {
                if let cookies = HTTPCookieStorage.shared.cookies {
                    cookiesArray.append(contentsOf: cookies)
                }
                let cookieDict = HTTPCookie.requestHeaderFields(with: cookiesArray)
                if let cookieStr = cookieDict["Cookie"] {
                    request.addValue(cookieStr, forHTTPHeaderField: "Cookie")
                }
                completion(request)
            }
        }
    
        // MARK: - JS Cookie handling
        private func syncCookiesInJS(for request: URLRequest? = nil) {
            if let url = request?.url,
                let cookies = HTTPCookieStorage.shared.cookies(for: url) {
                let script = jsCookiesString(for: cookies)
                let cookieScript = WKUserScript(source: script, injectionTime: .atDocumentStart, forMainFrameOnly: false)
                self.configuration.userContentController.addUserScript(cookieScript)
    
            } else if let cookies = HTTPCookieStorage.shared.cookies {
                let script = jsCookiesString(for: cookies)
                let cookieScript = WKUserScript(source: script, injectionTime: .atDocumentStart, forMainFrameOnly: false)
                self.configuration.userContentController.addUserScript(cookieScript)
            }
        }
    
        private func jsCookiesString(for cookies: [HTTPCookie]) -> String {
            var result = ""
            let dateFormatter = DateFormatter()
            dateFormatter.timeZone = TimeZone(abbreviation: "UTC")
            dateFormatter.dateFormat = "EEE, d MMM yyyy HH:mm:ss zzz"
    
            for cookie in cookies {
                result += "document.cookie='\(cookie.name)=\(cookie.value); domain=\(cookie.domain); path=\(cookie.path); "
                if let date = cookie.expiresDate {
                    result += "expires=\(dateFormatter.string(from: date)); "
                }
                if (cookie.isSecure) {
                    result += "secure; "
                }
                result += "'; "
            }
            return result
        }
    }
    
    extension WKCookieWebView : URLSessionTaskDelegate {
    
        func urlSession(_ session: URLSession, task: URLSessionTask, willPerformHTTPRedirection response: HTTPURLResponse, newRequest request: URLRequest, completionHandler: @escaping (URLRequest?) -> Void) {
    
            syncCookies(request) { (newRequest) in
                completionHandler(newRequest)
            }
        }
    }
    
    
    

    【讨论】:

    • 感谢您的回答。可悲的是,即时通讯使用的聊天机器人没有保存任何会话。因此,我需要手动完成。当我单击主页按钮并返回应用程序时,对话仍然存在。但是,如果我单击后退按钮,对话将被清除。我现在想弄清楚,如何防止在单击后退按钮时重新加载WKWebView
    • 好的,让我与您分享课程以帮助您
    • 感谢您的时间和回答。但它仍然对我不起作用。当我单击返回并返回到WKWebView 时,它仍然会重新加载并且之前的对话消失了。
    • 你能分享你的来源吗??
    【解决方案2】:

    applicationWillResignActive 中执行此操作。

    如果只点击home键,APP不会被终止。它仍然存在于后台,因此不会调用 applicationWillTerminate

    【讨论】:

    • 感谢您的回答。但是你知道如果点击返回按钮会调用applicationWillTerminate方法吗?
    • 不,当我们单击返回按钮时 applicationWillTerminate 不被称为@rana
    • @SiddhantNigam 感谢您的回答。但是你知道为什么点击后退按钮时WKWebview 会被重新加载吗?这是否意味着如果 UI 控制器进入后台状态,并且想要回到前台状态,它会被重新加载?
    • 我认为这取决于您何时调用 webView.load()。如果您调用 viewWillAppear/viewDidAppear,它将被重新加载。我认为它不会以其他方式重新加载。 @rana
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-26
    • 2013-12-08
    • 2012-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多