使用URLSession发起网络请求导致的 实体机测试,而非模拟机 在虚拟机正常,但是实体机就会错误 后台服务在本地也可能不是 解决方案 如果你符合上面的情形,那你应该适合我一样的新手,其实这个问题和Xcode
因为我们的Alamofire是对苹果URLSession的封装,所以在探索Alamofire之前,我们来看看URLSession的必备基础 一、请求网络的基本格式 URLSession.shared.dataTask 请求成果或者失败都会回来闭包 其实闭包只是一层封装,真正来的是URLSession的代理 其实在这个过程中,我们省略一个重要的东西: URLSessionConfiguration 二、URLSessionConfiguration : Int64, totalBytesExpectedToWrite: Int64) 下载完成之后就回调URLSessionDownloadDelegate代理 func urlSession(_ session : URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) 易错易忽略点 上面这么设置 希望读者能够对URLSession更了解一些!
URLSession:task:didCompleteWithError: will * still be called. */ - (void)URLSession:(NSURLSession * if (delegate) { [delegate URLSession:session downloadTask:downloadTask didFinishDownloadingToURL: - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)taskdidCompleteWithError:(NSError ---- 3. - (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask 一旦你继续下载任务,session会调用它的代理方法URLSession:downloadTask:didResumeAtOffset:expectedTotalBytes:其中的downloadTask
. - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task willPerformHTTPRedirection ---- 3. - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task needNewBodyStream:( ---- 4. - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didSendBodyData:(int64 This * information is also available as properties of the task. */ - (void)URLSession:(NSURLSession ---- 5. - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError
. - (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse not be called for background upload tasks (which cannot be converted to download tasks). */ - (void)URLSession No * future messages will be sent to the data task. */ - (void)URLSession:(NSURLSession *)session dataTask ---- 3. - (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData discontiguous, you should use * [NSData enumerateByteRangesUsingBlock:] to access it. */ - (void)URLSession
URLSession 使用步骤 创建请求资源的 URL。 创建 URLRequest,设置请求参数。 创建 URLSessionConfiguration 用于设置 URLSession 的工作模式和网络设置。 创建 URLSession。 创建URLSession let session = URLSession(configuration: config) // 4. ,这样data返回的就是总数据的一段,此时需要用一个全局的Data进行追加存储 func urlSession(_ session: URLSession, dataTask: URLSessionDataTask } } extension ViewController: URLSessionTaskDelegate { // 上传进去 func urlSession(_ session: URLSession
让我们看看一些使用URLSession.shared单例的代码: class DataLoader { enum Result { case data(Data) 抽象成一个协议 我们的首要任务是将URLSession中我们需要的部分转移到一个协议中,然后我们可以在测试中轻松地模拟。 让我们创建一个NetworkEngine协议并使URLSession遵循它: protocol NetworkEngine { typealias Handler = (Data? -> Void func performRequest(for url: URL, completionHandler: @escaping Handler) } extension URLSession 我们将使用URLSession.shared作为默认参数,这样我们就可以保持向后的兼容性和与以前一样的便利。
创建一个方法来下载文件,这里使用URLSession以方便观察下载的情况。 这里需要遵守URLSessionDownloadDelegate,并实现代理方法,否则会报错。 func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten 这个就在刚才URLSession的代理方法里面设置strokeEnd的地方设置percentageLabel的text就好了。 这里注意设置text也需要在主线程里面。 with: url) downloadTask.resume() } func urlSession(_ session: URLSession, downloadTask with: url) downloadTask.resume() } func urlSession(_ session: URLSession, downloadTask
delegate func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) count) 总数据\(Int(dataTask.countOfBytesExpectedToReceive))") } func urlSession(_ session: URLSession, func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive response: URLResponse , completionHandler: @escaping (URLSession.ResponseDisposition) -> Void) { completionHandler(Foundation.URLSession.ResponseDisposition.allow contentLength = self.totalLength } } } 收到响应数据后 func urlSession(_ session: URLSession, dataTask
对于每一个完成的后台Task调用该Session的Delegate中的URLSession:downloadTask:didFinishDownloadingToURL:(成功的话) 和URLSession :task:didCompleteWithError:(成功或者失败都会调用)方法做处理,以上的回调代码块可以在这里调用 - (void)URLSession:(NSURLSession *)session 对于所有其他认证方案,会话仅调用URLSession:task:didReceiveChallenge:completionHandler:方法。 会话委托的URLSession:didReceiveChallenge:completionHandler:方法不针对非会话级别的挑战进行调用。 对于pipelined的请求,流任务将只允许读取,并且对象将立即发送委托消息URLSession:writeClosedForStreamTask :.
创建URLSession对象在设置了代理服务器参数后,我们可以使用配置好的URLSessionConfiguration对象来创建URLSession对象。 创建URLSession对象时,可以传入一个代理对象,用于处理代理服务器的认证等操作.3. 创建URLSession对象在设置了代理服务器参数后,我们可以使用配置好的URLSessionConfiguration对象来创建URLSession对象。 创建URLSession对象时,可以传入一个代理对象,用于处理代理服务器的认证等操作.三、Swift中的数据传输实现通过设置好网络代理后,我们可以使用Swift中的URLSession对象来实现数据的传输 接收网络响应在发送网络请求后,URLSession对象会自动处理网络响应。
RxSwift框架中,将 URLSession 进行了封装,在 URLSession+Rx.swift文件下,可以找到 RxSwift 为我们提供了四种方法 ? 首先是 response 方法 func requestResponse() -> Void { let url = URL(string: urlString) URLSession.shared.rx.response response方法返回结果 data 方法 func requestData() -> Void { let url = URL(string: urlString) URLSession.shared.rx.data 最后来看下 json 方法 func requestJson() -> Void { let url = URL(string: urlString) URLSession.shared.rx.json
代理3 // 被服务器重定向的时候调用 - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask * 代理4 //https认证 - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task 代理9 //上面的代理如果设置为NSURLSessionResponseBecomeDownload,则会调用这个方法 - (void)URLSession:(NSURLSession *)session 代理10 //当我们获取到数据就会调用,会被反复调用,请求到的数据就在这被拼装完整 - (void)URLSession:(NSURLSession *)session dataTask 从urlsession那转发到这 - (void)URLSession:(__unused NSURLSession *)session task:(NSURLSessionTask
二、Swift 网络请求基础 在 Swift 中,URLSession 是处理网络请求的核心类。它提供了同步和异步两种方式来发送请求,并支持多种配置选项(如代理、超时时间等)。 然而,URLSession 的主要功能是发送请求和接收响应数据,对于响应数据的解析(尤其是 HTML/XML 数据)并不擅长。这正是 Kanna 的用武之地。 以下是一个简单的 Swift 网络请求示例,展示如何使用 URLSession 发送 GET 请求并接收数据: import Foundation func fetchData(from urlString "Unknown data")") } } 这个示例展示了如何使用 URLSession 发送网络请求并接收响应数据。 通过结合 URLSession 和 Kanna,我们可以高效地完成这一任务。
manager.securityPolicy = securityPolicy 方法二、如果你的网络请求类也和我一样是直接继承的AFHTTPSessionManager 那么也可以重写下面的方法来解决 OC: - (void)URLSession NSURLCredential alloc] initWithTrust:challenge.protectionSpace.serverTrust]) } swift: public override func urlSession (_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?)
二、Swift 网络请求基础在 Swift 中,URLSession 是处理网络请求的核心类。它提供了同步和异步两种方式来发送请求,并支持多种配置选项(如代理、超时时间等)。 然而,URLSession 的主要功能是发送请求和接收响应数据,对于响应数据的解析(尤其是 HTML/XML 数据)并不擅长。这正是 Kanna 的用武之地。 以下是一个简单的 Swift 网络请求示例,展示如何使用 URLSession 发送 GET 请求并接收数据:import Foundationfunc fetchData(from urlString "Unknown data")") }}这个示例展示了如何使用 URLSession 发送网络请求并接收响应数据。然而,如果响应数据是 HTML/XML 格式,我们还需要进一步解析这些数据。 通过结合 URLSession 和 Kanna,我们可以高效地完成这一任务。
. - (void)URLSession:(NSURLSession *)session didBecomeInvalidWithError:(nullable NSError *)error; 先看代理方法 when it has been * explicitly invalidated, in which case the error parameter will be nil. */ - (void)URLSession typedef void (^AFURLSessionDidBecomeInvalidBlock)(NSURLSession *session, NSError *error); - (void)URLSession ---- 2. - (void)URLSession:(NSURLSession *)sessiondidReceiveChallenge:(NSURLAuthenticationChallenge * - (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
forHTTPHeaderField:@"Authorization"]; } 对于经过302重定向的链接,则需要如下修改: 打开SDWebImageDownloader.m类,修改- (void)URLSession NSURLRequest *)request completionHandler:(void (^)(NSURLRequest * _Nullable))completionHandler方法如下: - (void)URLSession customRequest.allHTTPHeaderFields = self.HTTPHeaders; if ([dataOperation respondsToSelector:@selector(URLSession :task:willPerformHTTPRedirection:newRequest:completionHandler:)]) { [dataOperation URLSession
* task= [defaultSession dataTaskWithRequest:request]; [task resume]; 实现代理方法如下: //开始接受数据 -(void)URLSession NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data{ NSLog(@"=======%@",data); } //接受数据结束 -(void)URLSession nil]; [[backgroundSession downloadTaskWithRequest:request]resume]; 在下面的回调方法中可以进行下载进度的监听: - (void)URLSession completionHandler{ NSLog(@"1111"); } 之后应用程序在后台会调用NSURLSesstion代理的如下方法来通知下载结果: //此方法无论成功失败都会调用 -(void)URLSession didCompleteWithError:(NSError *)error{ NSLog(@"完成:error%@",error); } //此方法只有下载成功才会调用 文件放在location位置 -(void)URLSession
URLSession 建议通过连接迁移来优化网络切换场景下的 TCP 连接重建,降低网络的延迟。 import UIKit class ViewController: UIViewController { lazy var session: URLSession = { let ,App可以采用不同的策略来利用这些网络通道 configuration.multipathServiceType = .handover let session = URLSession