美文网首页
Fetching Website Data Into Memor

Fetching Website Data Into Memor

作者: 晨阳Xia | 来源:发表于2021-03-03 08:35 被阅读0次
    通过从URL会话创建任务,将接收到的数据直接存储到缓存中

    Overview

    对于于远程服务器的小型交互,可以使用URLSessionDataTask类将相应数据接收到缓存中(与使用URLSessionDownLoadTask类相反,后者将数据直接存储到文件系统中)。数据任务非常适合诸如调用web服务器终结点之类的用途。
    您使用URL会话实例创建任务。如果你的需求很简单,你可以使用URLSession共享实例。如果你想通过代理回调和转移来交互,则需要创建一个回话而不是共享实例。你使用URLSessionConfiguration实例创建会话,同时还要传入实现URLSessionDelegate或其子协议之一的类。可以重复使用会话来创建多个任务,因此对于所需的每个唯一配置请创建一个会话并将其存储为属性。

    Note

    注意不要创建过多的会话。例如您的应用有多个部分需要配置蕾丝的会话,创建一个并分享给他们。
    拥有了一个回话后,你可以使用dataTask()方法之一创建任务。任务以挂起状态创建,可以通过调用resume()来启动。

    Receive Results with a Completion Handler

    提取数据最简单的方法是创建一个使用完成处理程序的任务。通过这种安排,任务会将服务器的响应,数据和可能的错误传递到你提供的完成处理程序块。图一展示了会话和任务之间的关系,以及如何将结果传递到完成处理程序块。
    image.png
    要创建使用完成处理程序的数据任务,请调用URLSession的dataTask(with :)方法。您的完成处理程序需要做三件事:
    1. 验证错误参数为nil,如果不是,则发生了传输错误,处理错误并退出
    2. 检查响应参数来验证状态码是否指示成功,MIME类型是否是期望的值。如果不是,处理服务器错误并退出。
    3. 根据需要使用数据实例
    清单1显示了用于获取URL内容的startLoad()方法。首先使用URLSession类的共享实例来创建一个数据任务,该任务将其结果传递给完成程序块。检查本地和服务器错误后,此处理程序将数据转换为字符串,并使用其填充WKWebView出口。当然,您的应用程序可能还有其他用途来获取数据,例如将其解析为数据模型。
    表单一创建了一个完成处理程序,以接收数据加载结果
    
    func startLoad() {
        let url = URL(string: "https://www.example.com/")!
        let task = URLSession.shared.dataTask(with: url) { data, response, error in
            if let error = error {
                self.handleClientError(error)
                return
            }
            guard let httpResponse = response as? HTTPURLResponse,
                (200...299).contains(httpResponse.statusCode) else {
                self.handleServerError(response)
                return
            }
            if let mimeType = httpResponse.mimeType, mimeType == "text/html",
                let data = data,
                let string = String(data: data, encoding: .utf8) {
                DispatchQueue.main.async {
                    self.webView.loadHTMLString(string, baseURL: url)
                }
            }
        }
        task.resume()
    }
    

    Import

    在与创建任务的队列不同的Grand Central Dispatch队列上调用完成处理程序。因此,任何使用数据或错误来更新UI的工作(例如更新webView)都应明确放置在主队列中,如下所示。

    Receive Transfer Details and Results with a Delegate

    为了在执行任务时获得更高级别的访问权限,在创建数据任务时,您可以在绘画上设置委托,而不是提供完成处理程序。图2显示了这种安排。
    图2实现了代理来接收任务返回的结果
    image.png
    通过这种方式,部分数据在到达时会提供给URLSessionDataDelegate 的urlSession(_:dataTask:didReceive:)方法,直到传输完成或者失败并出现导致。随着专一的进行,委托还会接受其他类型的事件。
    在使用委托方式的时候,你需要创建你自己的URLSession实例,而不是使用URLSession类的简单共享实例。创建一个新会话可以让您将自己的类设置为会话的委托,如清单2所示。
    声明你的类,实现一个或多个委托协议(URLSessionDelegate,URLSessionTaskDelegate,RULSessionDataDelegate,and URLSessionDownloadDelegate).然后使用初始化init(configurationLdelegateLdelegateQueue:)创建URL会话实例。您可以自定义与此初始化程序一起使用的配置实例。例如最好将waitsForConnectivity设置为true,这样,会话将等待适当的连接,而不是在所需的连接不可用时立即失败。
    private lazy var session: URLSession = {
            let configuration = URLSessionCOnfiguration.default
            configuration.waitsForConnectivity = true
            return URLSession(configuratio: configuration, delegate: self. delegateQueue:nil)
    }
    
    清单3显示了一个startLoad()方法,该方法使用此会话来启动数据任务,使用委托回调处理接收到的数据和错误。这个表单实现了三个代理回调:
    • urlSession(_:dataTask:didReceive:completionHandler:)验证响应是否具有成功的HTTP状态代码,并且MIME类型为text / html或text / plain。如果不是上述两者结果之一,任务被取消,否则,他可以继续执行。
    • urlSession(_:dataTask:didReceive :)接收任务接收到的每个Data实例,并将其附加到一个称为ReceivedData的缓冲区中。
    • urlSession(_:task:didcCompleteWIthError:)首先查看是否发生了传输级错误,如果没有错误,他将尝试将ReceiveData缓冲区转换为字符串并将其设置为webView的内容。
    表单3 使用了URL sessiondatatask的委托
    var receivedData: Data?
    
    func startLoad() {
        loadButton.isEnabled = false
        let url = URL(string: "https://www.example.com/")!
        receivedData = Data()
        let task = session.dataTask(with: url)
        task.resume()
    }
    
    // delegate methods
    
    func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive response: URLResponse,
                    completionHandler: @escaping (URLSession.ResponseDisposition) -> Void) {
        guard let response = response as? HTTPURLResponse,
            (200...299).contains(response.statusCode),
            let mimeType = response.mimeType,
            mimeType == "text/html" else {
            completionHandler(.cancel)
            return
        }
        completionHandler(.allow)
    }
    
    func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) {
        self.receivedData?.append(data)
    }
    
    func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
        DispatchQueue.main.async {
            self.loadButton.isEnabled = true
            if let error = error {
                handleClientError(error)
            } else if let receivedData = self.receivedData,
                let string = String(data: receivedData, encoding: .utf8) {
                self.webView.loadHTMLString(string, baseURL: task.currentRequest?.url)
            }
        }
    }
    
    各种委托协议提供了以上代码中所示方法之外的方法,用于处理身份验证挑战,重定向之后和其他特殊情况,在URLSession讨论中,使用URL会话描述了在传输过程中可能发生的各种回调。

    相关文章

      网友评论

          本文标题:Fetching Website Data Into Memor

          本文链接:https://www.haomeiwen.com/subject/uukfqltx.html