ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

如何用 Alamofire 的 Session 包装已有的 URLSession 并检查前置要求

如何用 Alamofire 的 Session 包装已有的 URLSession 并检查前置要求 如何用 Alamofire 的 Session 包装已有的 URLSession 并检查前置要求【免费下载链接】AlamofireElegant HTTP Networking in Swift项目地址: https://gitcode.com/GitHub_Trending/al/Alamofire如果你的项目里已经存在一个自行创建的URLSession实例而你又想在它上面使用 Alamofire 的Request体系重试、拦截器、响应序列化等就不必丢弃它重新创建——Alamofire 的Session提供了init(session:delegate:rootQueue:)初始化器可以直接包装一个已有的URLSession。但这个初始化器带有一个便捷初始化器init(configuration:...)所没有的前置要求不满足时会在初始化时触发运行时错误。本文按 AdvancedUsage.md 中 Creating Instances FromURLSessions 一节的说明给出完整的包装步骤并逐条核对前置要求。前提依赖与平台要求先确认工程满足 README.md 中的 Requirements 表平台iOS 10.0 / macOS 10.12 / tvOS 10.0 / watchOS 3.0工具链Swift 6.0 / Xcode 16.0。以 Swift Package Manager 为例在Package.swift或 Xcode 的 Package 列表中声明依赖dependencies: [ .package(url: https://github.com/Alamofire/Alamofire.git, .upToNextMajor(from: 5.11.0)) ]通常依赖Alamofiretarget.product(name: Alamofire, package: Alamofire)包装前先核对三条前置要求官方文档明确指出除了便捷初始化器之外Session也可以直接从URLSession初始化但该初始化器有若干要求因此文档推荐大多数场景使用便捷初始化器。只有确实需要接管一个已有的URLSession时才走本文的路径。包装前需要核对以下三点不支持后台URLSession。Alamofire 不支持配置为后台使用的URLSession即URLSessionConfiguration的identifier非nil。如果传入的是后台配置初始化Session时会产生运行时错误。delegate必须是 Alamofire 的SessionDelegate实例。同一个实例既要作为URLSession的delegate传入又要传给Session初始化器。delegateQueue必须是一个自定义OperationQueue并且满足该队列是串行队列maxConcurrentOperationCount 1该队列必须有underlyingQueue指向的DispatchQueue这个DispatchQueue必须作为rootQueue参数传给Session初始化器。包装已有 URLSession 的步骤以下代码块来自 AdvancedUsage.md 的 Creating Instances FromURLSessions 一节可直接按原样使用let rootQueue DispatchQueue(label: org.alamofire.customQueue) let queue OperationQueue() queue.maxConcurrentOperationCount 1 queue.underlyingQueue rootQueue let delegate SessionDelegate() let configuration URLSessionConfiguration.af.default let urlSession URLSession(configuration: configuration, delegate: delegate, delegateQueue: queue) let session Session(session: urlSession, delegate: delegate, rootQueue: rootQueue)逐行对应上面的要求rootQueue自定义的串行DispatchQueue稍后作为Session的内部回调队列。文档中 ASessionsDispatchQueues 一节说明自定义rootQueue必须是串行队列requestQueue和serializationQueue则可以是串行或并行。queue作为URLSession的delegateQueue传入的OperationQueuemaxConcurrentOperationCount 1保证串行underlyingQueue rootQueue建立OperationQueue与DispatchQueue的绑定关系。delegateSessionDelegate实例。它封装了所有URLSessionDelegate相关回调同时是每个Request的SessionStateProvider。也可以用SessionDelegate(fileManager: .default)这类形式自定义其使用的FileManager。configuration文档建议使用URLSessionConfiguration.af.default作为起点因为它是 Alamofire 默认添加Accept-Encoding、Accept-Language和User-Agent请求头的配置但任何URLSessionConfiguration都可以使用。注意两点URLSessionConfiguration不是设置Authorization或Content-Type头的推荐位置应通过Request的headersAPI、ParameterEncoder或RequestAdapter添加且URLSessionConfiguration一旦被用于初始化URLSession之后再修改其属性不再生效。urlSession按上述 delegate 与队列要求创建的URLSession。session最后把urlSession、delegate、rootQueue三者传给Session初始化器得到可直接发请求的Session实例。Session(session:delegate:rootQueue:)的完整参数含startRequestsImmediately、requestSetup、requestQueue、serializationQueue、interceptor、serverTrustManager、redirectHandler、cachedResponseHandler、eventMonitors等可选项可在 Session.swift 中查看。如何判断前置要求是否满足初始化器内部有两处运行时检查对应文档列出的前置要求见 Session.swiftprecondition(session.configuration.identifier nil, Alamofire does not support background URLSessionConfigurations.) precondition(session.delegateQueue.underlyingQueue rootQueue, Session(session:) initializer must be passed the DispatchQueue used as the delegateQueues underlyingQueue as rootQueue.)据此可以这样核对如果URLSession的configuration.identifier非nil后台配置初始化即触发第一条precondition的运行时错误这正是文档所说 This will lead to a runtime error when theSessionis initialized如果传给Session的rootQueue与URLSession的delegateQueue的underlyingQueue不是同一个DispatchQueue实例注意是恒等判断不是同名队列会触发第二条precondition反过来只要Session初始化成功、没有触发上述运行时错误就说明三条前置要求都已满足。此时可以像使用Session.default一样通过该实例发请求例如文档示例中的session.request(https://httpbin.org/get)。源码中对该初始化器的注释也重申了这一点创建URLSession时必须使用特定的delegateQueue值并把该delegateQueue的underlyingQueue作为rootQueue参数传入。限制与替代路径不需要复用已有URLSession时请使用便捷初始化器。文档对Creating Instances From URLSessions这一节的原话是由于该初始化器要求较多using the convenience initializer is recommended。便捷初始化器会替你创建URLSession、OperationQueue和delegateQueue并把自定义rootQueue重新 target 成串行队列以保证安全例如let session Session(configuration: URLSessionConfiguration.af.default)它同样有后台配置限制configuration.identifier非nil时触发同样的运行时错误。后台传输需求不在支持范围内。无论走哪个初始化器后台URLSessionConfiguration都不被支持需要后台传输时应保留自己的原生URLSession方案而不是尝试包装。rootQueue必须串行。这是文档对Session队列的硬性说明与便捷初始化器内部自动 target 成串行的行为不同——走init(session:)路径时这个约束由你自己在创建队列时保证。包装完成后Session级别的其他定制RequestInterceptor、ServerTrustManager、RedirectHandler、CachedResponseHandler、EventMonitor等在两条初始化路径上都可以按各自文档章节添加与是否包装已有URLSession无关本文不展开。【免费下载链接】AlamofireElegant HTTP Networking in Swift项目地址: https://gitcode.com/GitHub_Trending/al/Alamofire创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进