Kingfisher 低数据模式(Low Data Mode)适配指南:用 `.lowDataMode` 选项自动降级加载低分辨率图片

发布时间:2026/9/12 6:27:26
Kingfisher 低数据模式(Low Data Mode)适配指南:用 `.lowDataMode` 选项自动降级加载低分辨率图片 Kingfisher 低数据模式Low Data Mode适配指南用.lowDataMode选项自动降级加载低分辨率图片【免费下载链接】KingfisherA lightweight, pure-Swift library for downloading and caching images from the web.项目地址: https://gitcode.com/GitHub_Trending/ki/Kingfisher导读自 iOS 13 起Apple 为系统加入了「低数据模式」Low Data Mode允许用户在蜂窝网络与 Wi-Fi 环境下主动限制数据流量消耗。Kingfisher 针对该场景提供了开箱即用的支持通过为图片加载请求指定一个「低数据模式替代源」通常是低分辨率版本或本地占位图Kingfisher 会在系统限制数据访问时自动切换加载目标从而在保证图片功能可用的前提下显著节省流量。读完本文你将掌握.lowDataMode选项的完整用法、底层切换原理以及如何在 SwiftUI 与 UIKit 中落地这一能力。什么是低数据模式Low Data Mode低数据模式是 iOS 13 及后续系统版本macOS 10.15、watchOS 6.0、tvOS 13.0 起同样适用提供的一种系统级流量控制开关。用户在系统设置中开启后系统会倾向于减少后台与前台的数据传输部分请求甚至会被系统直接以「受限」原因拦截。对图片类 App 而言低数据模式最常见的表现是高清大图请求被系统判定为「受限网络访问」而失败对应的URLError的networkUnavailableReason为.constrained。如果 App 不做任何处理用户会直接看到图片加载失败。Kingfisher 的解决方案是为每个图片加载任务额外准备一个「低数据模式源」在受限失败发生时自动降级而不是让用户面对一个加载失败的图片占位符。核心 API.lowDataMode选项低数据模式支持在 Kingfisher 中通过KingfisherOptionsInfoItem的一个 case 开启其定义位于 Sources/General/KingfisherOptionsInfo.swift/// Specifies the Source to load when the user enables Low Data Mode and the original source fails due to the data /// constraint. case lowDataMode(Source?)它的语义非常明确关联值是一个可空的Source。传入Source时Kingfisher 会为原始请求设置allowsConstrainedNetworkAccess false即不允许受限网络访问当原始请求因受限失败后改用该Source重新发起加载传入nil或完全不设置该选项时Kingfisher 会忽略设备的低数据模式设置完全按照系统默认行为加载原始源。在链式 API 中KFOptionsSetter提供了对应的便捷方法lowDataModeSource(_:)见 Sources/General/KFOptionsSetter.swiftpublic func lowDataModeSource(_ source: Source?) - Self { options.lowDataModeSource source return self }命名说明部分文档示例中使用.lowDataSource(...)写法而当前仓库源码中该选项的实际 case 名为.lowDataMode(Source?)见上述KingfisherOptionsInfoItem定义与 解析逻辑。本文示例一律采用与源码一致的可编译写法请以.lowDataMode为准。实战一网络低分辨率 URL 作为降级源最典型的使用场景是正常状态下加载高清大图低数据模式下自动切换为服务器上的低分辨率版本。核心代码如下imageView.kf.setImage( with: highResolutionURL, options: [ .lowDataMode(.network(lowResolutionURL)) ] )其行为过程是设备未开启低数据模式时直接使用highResolutionURL加载图片设备处于低数据模式且highResolutionURL未命中缓存此时请求被系统以.constrained原因拦截时Kingfisher 自动改用lowResolutionURL加载低分辨率版本以节省流量若highResolutionURL命中了缓存则仍然直接使用缓存结果不会触发降级加载。需要注意的是降级源同样会参与 Kingfisher 的缓存体系因此首次在低数据模式下加载成功后后续再次进入该模式时可能直接命中缓存连低分辨率请求都无需再次发出。实战二本地图片 Provider 作为降级源.lowDataMode的关联值是Source而非单纯的 URL这意味着你可以传入任意满足Source协议的来源包括各类ImageDataProvider。这样在低数据模式下可以完全避免发起任何网络下载直接使用本地存储的图片如内置占位图、离线包中的缩略图这对于弱网或完全离线场景尤为实用imageView.kf.setImage( with: highResolutionURL, options: [ .lowDataMode( .provider(LocalFileImageDataProvider(fileURL: localFileURL)) ) ] )LocalFileImageDataProvider定义于 Sources/General/ImageSource/ImageDataProvider.swift其初始化参数为fileURL本地图片文件 URL必填cacheKey缓存键默认取fileURL的absoluteStringloadingQueue文件读取执行的队列默认使用DispatchQueue.global(qos: .userInitiated)。与直接使用UIImage(contentsOfFile:)不同经由LocalFileImageDataProvider加载的本地图片同样会走完 Kingfisher 的完整管线——包括应用ImageProcessor处理器、存入ImageCache缓存等因此可以获得与网络图一致的后续处理能力。顺带一提仓库还提供了Base64ImageDataProvider等其它内置 Provider见 ImageDataProvider.swift同样可以作为降级源传入。底层原理受限请求如何被识别并切换低数据模式的整个降级链路由三处源码共同实现理解它们有助于排查问题1. 请求阶段关闭受限网络访问在 Sources/Networking/ImageDownloader.swift 中当用户设置了lowDataModeSource且系统版本支持时Kingfisher 会显式声明原始请求不允许受限网络访问var request URLRequest(url: url, cachePolicy: .reloadIgnoringLocalCacheData, timeoutInterval: downloadTimeout) request.httpShouldUsePipelining requestsUsePipelining if #available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *), options.lowDataModeSource ! nil { request.allowsConstrainedNetworkAccess false }allowsConstrainedNetworkAccess false意味着当系统处于低数据模式时该请求会被系统判定为「受约束」而失败从而让 Kingfisher 有机会感知到低数据模式状态而不是静默使用系统默认行为。2. 错误识别阶段判断是否为受限失败在 Sources/General/KingfisherError.swift 中Kingfisher 封装了对「受限」错误的判定var isLowDataModeConstrained: Bool { if #available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *), case .responseError(reason: .URLSessionError(let sessionError)) self, let urlError sessionError as? URLError, urlError.networkUnavailableReason .constrained { return true } return false }只有当底层URLError的networkUnavailableReason恰好等于.constrained时才会被判定为低数据模式受限失败进而触发降级逻辑——其它类型的网络错误不会误入降级分支。3. 切换阶段用降级源重新发起加载在 Sources/General/KingfisherManager.swift 中failCurrentSource对受限失败做了特殊处理——它优先于alternativeSources备用源列表逻辑执行// When low data mode constrained error, retry with the low data mode source instead of use alternative on fly. guard !error.isLowDataModeConstrained else { if let source retrievingContext.options.lowDataModeSource { retrievingContext.options.lowDataModeSource nil startNewRetrieveTask(with: source, retryContext: retryContext, downloadTaskUpdated: downloadTaskUpdated) } else { // This should not happen. completionHandler?(.failure(error)) } return }这段代码有两个值得注意的细节受限失败时Kingfisher 会取走并清空lowDataModeSource后重新发起加载确保降级源自身加载失败时不会再陷入递归切换降级源加载失败后Kingfisher 仍会继续走alternativeSources等后续逻辑因此该特性可以与alternativeSources、retryStrategy等选项共存组合使用。测试验证降级行为有据可依Kingfisher 仓库在 Tests/KingfisherTests/ImageViewExtensionTests.swift 中提供了testLowDataModeSource测试用例完整覆盖了降级链路available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) MainActor func testLowDataModeSource() { let exp expectation(description: #function) let url testURLs[0] stub(url, data: testImageData) // Stub a failure of .constrained. It is what happens when an image downloading fails when low data mode on. let brokenURL testURLs[1] let error URLError( .notConnectedToInternet, userInfo: [NSURLErrorNetworkUnavailableReasonKey: URLError.NetworkUnavailableReason.constrained.rawValue] ) stub(brokenURL, error: error) imageView.kf.setImage(with: .network(brokenURL), options: [.lowDataMode(.network(url))]) { result in XCTAssertNotNil(result.value) XCTAssertEqual(result.value?.source.url, url) XCTAssertEqual(result.value?.originalSource.url, brokenURL) exp.fulfill() } waitForExpectations(timeout: 1, handler: nil) }该测试通过伪造一个networkUnavailableReason .constrained的URLError来模拟低数据模式受限失败随后断言加载最终成功、实际图片来自降级源url、而originalSource仍是原始地址brokenURL。这一断言同时印证了「降级后原始来源信息仍可通过originalSource追溯」的行为。注意事项与默认行为未设置选项时的默认行为如果不指定.lowDataMode选项无论设备是否开启低数据模式Kingfisher 都会按照系统默认行为加载原始源不会主动降级也不会因受限失败自动重试版本可用性该特性依赖系统对allowsConstrainedNetworkAccess与URLError.NetworkUnavailableReason的支持仅适用于 macOS 10.15 / iOS 13.0 / watchOS 6.0 / tvOS 13.0 及以上的系统版本代码内部已通过#available做兼容保护与备用源的区别alternativeSources是「原始源失败后按顺序尝试其它源」的通用机制而.lowDataMode专门针对受限网络失败且具有更高优先级见 KingfisherManager.swift 的注释降级源会进入缓存低分辨率降级图加载成功后同样写入 Kingfisher 缓存可配合transition、processor等既有选项一起使用实现平滑过渡显示。小结Kingfisher 的低数据模式支持用一句话概括就是给图片加载任务多准备一条「省流量退路」。通过imageView.kf.setImage(with:options:)中的.lowDataMode(.network(...))或.lowDataMode(.provider(...))即可在系统级流量限制下自动切换低分辨率网络图或本地图既保护了用户流量也避免了图片加载失败的糟糕体验。其背后由ImageDownloader的请求属性设置、KingfisherError的错误分类与KingfisherManager的降级切换三部分协同完成并有官方测试用例背书可以放心在生产环境中使用。【免费下载链接】KingfisherA lightweight, pure-Swift library for downloading and caching images from the web.项目地址: https://gitcode.com/GitHub_Trending/ki/Kingfisher创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询