news 2026/9/10 18:32:52

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
如何用 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时,才走本文的路径。包装前需要核对以下三点:

  1. 不支持后台URLSessionAlamofire 不支持配置为后台使用的URLSession(即URLSessionConfigurationidentifiernil)。如果传入的是后台配置,初始化Session时会产生运行时错误。
  2. delegate必须是 Alamofire 的SessionDelegate实例。同一个实例既要作为URLSessiondelegate传入,又要传给Session初始化器。
  3. 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的内部回调队列。文档中 "ASession'sDispatchQueues" 一节说明,自定义rootQueue必须是串行队列,requestQueueserializationQueue则可以是串行或并行。
  • queue:作为URLSessiondelegateQueue传入的OperationQueuemaxConcurrentOperationCount = 1保证串行,underlyingQueue = rootQueue建立OperationQueueDispatchQueue的绑定关系。
  • delegateSessionDelegate实例。它封装了所有URLSessionDelegate相关回调,同时是每个RequestSessionStateProvider。也可以用SessionDelegate(fileManager: .default)这类形式自定义其使用的FileManager
  • configuration:文档建议使用URLSessionConfiguration.af.default作为起点,因为它是 Alamofire 默认添加Accept-EncodingAccept-LanguageUser-Agent请求头的配置,但任何URLSessionConfiguration都可以使用。注意两点:URLSessionConfiguration不是设置AuthorizationContent-Type头的推荐位置(应通过RequestheadersAPI、ParameterEncoderRequestAdapter添加);且URLSessionConfiguration一旦被用于初始化URLSession,之后再修改其属性不再生效。
  • urlSession:按上述 delegate 与队列要求创建的URLSession
  • session:最后把urlSessiondelegaterootQueue三者传给Session初始化器,得到可直接发请求的Session实例。

Session(session:delegate:rootQueue:)的完整参数(含startRequestsImmediatelyrequestSetuprequestQueueserializationQueueinterceptorserverTrustManagerredirectHandlercachedResponseHandlereventMonitors等可选项)可在 Session.swift 中查看。

如何判断前置要求是否满足

初始化器内部有两处运行时检查,对应文档列出的前置要求(见 Session.swift):

precondition(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 delegateQueue's underlyingQueue as rootQueue.")

据此可以这样核对:

  • 如果URLSessionconfiguration.identifiernil(后台配置),初始化即触发第一条precondition的运行时错误,这正是文档所说 "This will lead to a runtime error when theSessionis initialized";
  • 如果传给SessionrootQueueURLSessiondelegateQueueunderlyingQueue不是同一个DispatchQueue实例(注意是===恒等判断,不是同名队列),会触发第二条precondition
  • 反过来,只要Session初始化成功、没有触发上述运行时错误,就说明三条前置要求都已满足。此时可以像使用Session.default一样通过该实例发请求,例如文档示例中的session.request("https://httpbin.org/get")

源码中对该初始化器的注释也重申了这一点:创建URLSession时必须使用特定的delegateQueue值,并把该delegateQueueunderlyingQueue作为rootQueue参数传入。

限制与替代路径

  • 不需要复用已有URLSession时,请使用便捷初始化器。文档对Creating Instances From URLSessions这一节的原话是:由于该初始化器要求较多,"using the convenience initializer is recommended"。便捷初始化器会替你创建URLSessionOperationQueuedelegateQueue,并把自定义rootQueue重新 target 成串行队列以保证安全,例如:

    let session = Session(configuration: URLSessionConfiguration.af.default)

    它同样有后台配置限制(configuration.identifiernil时触发同样的运行时错误)。

  • 后台传输需求不在支持范围内。无论走哪个初始化器,后台URLSessionConfiguration都不被支持,需要后台传输时应保留自己的原生URLSession方案,而不是尝试包装。

  • rootQueue必须串行。这是文档对Session队列的硬性说明,与便捷初始化器内部自动 target 成串行的行为不同——走init(session:)路径时这个约束由你自己在创建队列时保证。

  • 包装完成后,Session级别的其他定制(RequestInterceptorServerTrustManagerRedirectHandlerCachedResponseHandlerEventMonitor等)在两条初始化路径上都可以按各自文档章节添加,与是否包装已有URLSession无关,本文不展开。

【免费下载链接】AlamofireElegant HTTP Networking in Swift项目地址: https://gitcode.com/GitHub_Trending/al/Alamofire

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/10 18:31:17

CANN/GE RT2.0动态Shape执行器特性分析

RT2.0 动态 Shape 执行器特性分析 【免费下载链接】ge GE(Graph Engine)是面向昇腾的图编译器和执行器,提供了计算图优化、多流并行、内存复用和模型下沉等技术手段,加速模型执行效率,减少模型内存占用。 GE 提供对 Py…

作者头像 李华
网站建设 2026/9/10 18:28:34

用金字塔原则做项目计划:从目标到任务树的结构化方法

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华