美文网首页
Swift - 网络 URLSession

Swift - 网络 URLSession

作者: H_Zimi | 来源:发表于2019-08-16 14:26 被阅读0次

    问:Swift的网络请求怎么实现?
    答:用AFNetworkingAlamofire这些框架啊,快速、好用、数据解析难度低。
    是的,第三方网络框架真的好用,好用到我们都快忘了原生API是怎么玩了,但万丈高楼平地起,原生API我们还是有必要掌握的,能让我们更容易、更深入理解AFNetworkingAlamofire等框架,写这篇文章的目的是对Swift的原生API URLSession的复习

    基本网络请求:

    • 先做一点准备工作,iOS从9.0版本开始添加了对应用数据传输的安全性要求(ATS),我们在这里简单的设置一下关闭ATS
      • info.plist中添加一个key:App Transport Security Settings,类型为字典;
      • 再在这字典下添加另一个key:Allow Arbitrary Loads,类型为Boolean类型,值为YES
      • 网上对于解决ATS问题的方法有很多,这里不做赘述;
    // Swift简单网络请求
    let urlString = "http://rap2api.taobao.org/app/mock/228467/api/friend/list"
    URLSession.shared.dataTask(with: URL(string: urlString)!) { (data, response, error) in
        if error != nil {
            print("\(String(describing: error))")
        }
        print("\(String(describing: response))")
    }.resume()
    
    //OC 网络请求
    NSString *urlString = [NSString stringWithFormat:@"http://rap2api.taobao.org/app/mock/228467/api/friend/list"];
    [[[NSURLSession sharedSession] dataTaskWithURL:[NSURL URLWithString:urlString] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        if (!error) {
            NSLog(@"%@",error);
        }
        NSLog(@"%@", response);
    }] resume];
    
    • resume重启连接网络请求,默认是挂起状态,而在AFNetworkingAlamofire中我们不需要关心这一步,它们已经帮我们做了这一步的处理;
    • dataTask创建网络会话任务
      • uploadTask文件上传任务
      • downloadTask文件下载任务
      • streamTask用于对通过URLSession创建的TCP/IP流执行读写操作

    网络请求配置 - Configuration

    一、模式
    open class var `default`: URLSessionConfiguration { get }
    
    open class var ephemeral: URLSessionConfiguration { get }
    
    @available(iOS 8.0, *)
    open class func background(withIdentifier identifier: String) -> URLSessionConfiguration
    
    • default默认配置,会本地存储凭据、缓存和cookie
    • ephemeral临时会话,不会将cookie、缓存或凭据储存到本地只会放到内存中,当应用程序退出后数据也会消失,可以用于实现“秘密浏览”;
    • background建立后台会话,可以在应用程序挂起、退出、崩溃的情况下运行上传和下载任务,后台另起一个线程。另外,系统会根据设备的负载程度决定分配下载的资源,因此有可能会很慢甚至超时失败;
      • background需要有一个唯一标识符identifier用于标识任务

    后台执行任务的时候注意点

    • 苹果官方文档提供的后台任务的四步操作
    //Listing 1 Creating a background URL session
    private lazy var urlSession: URLSession = {
        let config = URLSessionConfiguration.background(withIdentifier: "MySession")
        config.isDiscretionary = true
        config.sessionSendsLaunchEvents = true
        return URLSession(configuration: config, delegate: self, delegateQueue: nil)
    }()
    
    //Listing 2 Creating a download task from a URL session
    let backgroundTask = urlSession.downloadTask(with: url)
    backgroundTask.earliestBeginDate = Date().addingTimeInterval(60 * 60)
    backgroundTask.countOfBytesClientExpectsToSend = 200
    backgroundTask.countOfBytesClientExpectsToReceive = 500 * 1024
    backgroundTask.resume()
    
    //Listing 3 Storing the background download completion handler sent to the application delegate
    var backgroundCompletionHandler: (() -> Void)?
    func application(_ application: UIApplication,
                     handleEventsForBackgroundURLSession identifier: String,
                     completionHandler: @escaping () -> Void) {
        backgroundCompletionHandler = completionHandler
    }
    
    //Listing 4 Executing the background URL session completion handler on the main queue
    func urlSessionDidFinishEvents(forBackgroundURLSession session: URLSession) {
        DispatchQueue.main.async {
            guard let appDelegate = UIApplication.shared.delegate as? AppDelegate,
                let backgroundCompletionHandler =
                appDelegate.backgroundCompletionHandler else {
                    return
            }
            backgroundCompletionHandler()
        }
    }
    
    • 给我们的信息是后台任务创建并执行还不够,还需要开启权限
    • 在任务完成,系统将执行在AppDelegate中保存的闭包backgroundCompletionHandler回调,更新屏幕

    PS: 官方文档查看方法:

    二、请求缓存策略
    public enum CachePolicy : UInt {
       //默认策略
       case useProtocolCachePolicy 
       //指定应从原始源加载URL加载的数据, 没有本地缓存数据
       case reloadIgnoringLocalCacheData 
       //指定不仅应忽略本地缓存数据,而且应指示代理和其他中间人在协议允许的情况下忽略其缓存。未实现
       case reloadIgnoringLocalAndRemoteCacheData
       //与reloadIgnoringLocalCacheData相同
       public static var reloadIgnoringCacheData: NSURLRequest.CachePolicy { get }
        //指定应使用现有缓存数据来满足URL加载请求,不管其生命周期或到期日期。 但是,如果缓存中没有与URL加载请求相对应的现有数据,则从原始源加载URL
       case returnCacheDataElseLoad
       //指定应使用现有缓存数据来满足URL加载请求,不管其生命周期或到期日期。 但是,如果缓存中没有与URL加载请求相对应的现有数据,则不会尝试从源源加载URL,并且认为加载失败。 此常量指定类似于“脱机”模式的行为。
       case returnCacheDataDontLoad
       //指定可以使用现有缓存数据,前提是源源确认其有效性,否则从原始源加载URL。未实现。
       case reloadRevalidatingCacheData
    }
    
    三、常用的属性
    • identifier后台会话标识符
    • timeoutIntervalForRequest请求超时,如果在设定的超时时间内没有传输数据,将导致超时,并且每当传输数据时都会重置。
    • timeoutIntervalForResource请求超时。 如果在给定超时内无法检索到资源,则会导致超时。
    • networkServiceType网络服务类型
    • allowsCellularAccess是否允许蜂窝网络
    • waitsForConnectivity任务等待网络连接是否可用,后台会话时会忽略,因为后台会话始终等待连接。
    四、安全策略
    • TLSMinimumSupportedProtocol允许最小TLS协议版本
    • TLSMaximumSupportedProtocol允许最大TLS协议版本
    • urlCredentialStorage存储身份验证凭证的库
    五、HTTP策略、代理属性
    • HTTPShouldUsePipelining允许使用HTTP流水线
    • HTTPMaximumConnectionsPerHost给定主机的最大并发持久连接数
    六、Cookie设置
    • HTTPShouldSetCookies是否允许请求包含一个Cookie库中的Cookie
    • HTTPCookieAcceptPolicy确定何时接受Cookie策略
    • HTTPCookieStorage 保存当前会话的 Cookie的库

    这里只是介绍了SwiftURLSession中一些基本的属性的用途,关于URLSessionDataTask做另一篇章来讲。

    PS:鄙人小小码农一枚,限于能力,官方文档或许理解有误,文章中有错误、不足之处,欢迎各位大神指正。

    相关文章

      网友评论

          本文标题:Swift - 网络 URLSession

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