尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
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),仅供参考
RELATED

相关推荐

SpringBoot校园服装租赁系统开发实战

SpringBoot校园服装租赁系统开发实战

1. 项目概述:校园服装租赁系统的技术实现校园服装租赁系统是为高校学生活动、文艺演出等场景设计的服装管理平台。我在实际开发中发现,这类系统需要解决三个核心问题:服装库存的动态管理、租赁流程的自动化处理以及多角色权限的精细控制。基于…

📅 2026/9/12 6:27:38
Redis安装与配置:从基础部署到生产环境优化

Redis安装与配置:从基础部署到生产环境优化

1. Redis安装方案选型与准备在Linux环境下安装Redis主要有两种主流方式:通过系统包管理器(如yum)安装和源码编译安装。我们先对比分析这两种方式的优劣:包管理器安装(yum)优点:一键安装、自动解…

📅 2026/9/12 6:22:34
工业级机器人摄像头:运动控制+实时视觉+闭环决策实战

工业级机器人摄像头:运动控制+实时视觉+闭环决策实战

1. 从“Cmara Robtica”这个词开始,我们到底在谈什么?“Cmara Robtica”——西班牙语,直译是“机器人摄像头”。但这个词在真实工程场景里,从来不是字面意思的简单叠加。它不等于“一个装了轮子的监控头”,也不代表“带…

📅 2026/9/12 6:22:34
MORE NEWS

更多资讯

📰

Golang核心特性与高并发实践指南

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

📰

低代码平台DIY模块开发:uniapp+vue3实战解析

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

📰

DeepSeek-MoE-16b-chat 基于 Transformers 的双卡显存部署与推理调用实战

DeepSeek-MoE-16b-chat 基于 Transformers 的双卡显存部署与推理调用实战 【免费下载链接】self-llm 《开源大模型食用指南》针对中国宝宝量身打造的基于Linux环境快速微调(全参数/Lora)、部署国内外开源大模型(LLM)/多模态大模型…

📰

170+本极客时间电子书都躺在这一个仓库里,你先该读哪本?

170本极客时间电子书都躺在这一个仓库里,你先该读哪本? 【免费下载链接】geektime-books :books: 极客时间电子书 项目地址: https://gitcode.com/GitHub_Trending/ge/geektime-books 这个叫 geektime-books 的开源仓库里,整整齐齐躺着…

📰

如何用 k3d 搭建本地 Kubernetes 集群部署并测试 Homepage

如何用 k3d 搭建本地 Kubernetes 集群部署并测试 Homepage 【免费下载链接】homepage A highly customizable homepage (or startpage / application dashboard) with Docker and service API integrations. 项目地址: https://gitcode.com/GitHub_Trending/ho/homepage …

📰

安卓期末大作业点餐平台App:架构设计与答辩高分指南

简介:面向Android课程设计与期末大作业的高分参考项目,内容为点餐平台App完整源码,附带文档说明与作业报告,适合需要完成安卓期末大作业、课程设计或想了解完整项目结构的学生参考。压缩包内共303个文件,大小91.74MB&a…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬