Swift Combine 网络受限时从备用 URL 请求数据 从入门到精通十四

Combine 系列

  1. Swift Combine 从入门到精通一
  2. Swift Combine 发布者订阅者操作者 从入门到精通二
  3. Swift Combine 管道 从入门到精通三
  4. Swift Combine 发布者publisher的生命周期 从入门到精通四
  5. Swift Combine 操作符operations和Subjects发布者的生命周期 从入门到精通五
  6. Swift Combine 订阅者Subscriber的生命周期 从入门到精通六
  7. Swift 使用 Combine 进行开发 从入门到精通七
  8. Swift 使用 Combine 管道和线程进行开发 从入门到精通八
  9. Swift Combine 使用 sink, assign 创建一个订阅者 从入门到精通九
  10. Swift Combine 使用 dataTaskPublisher 发起网络请求 从入门到精通十
  11. Swift Combine 用 Future 来封装异步请求 从入门到精通十一
  12. Swift Combine 有序的异步操作 从入门到精通十二
  13. Swift Combine 使用 flatMap 和 catch错误处理 从入门到精通十三
    在这里插入图片描述

1. 使用 flatMap 和 catch 在不取消管道的情况下处理错误

目的: flatMap 操作符可以与 catch 一起使用,以持续处理新发布的值上的错误。

flatMap 是用于处理持续事件流中错误的操作符。

你提供一个闭包给 flatMap,该闭包可以获取所传入的值,并创建一个一次性的发布者,完成可能失败的工作。 这方面的一个例子是从网络请求数据,然后将其解码。 你可以引入一个 catch 操作符,以捕获任何错误并提供适当的值。

当你想要保持对上游发布者的更新时,这是一个完美的机制,因为它创建一次性的发布者或短管道,发送一个单一的值,然后完成每一个传入的值。 所创建的一次性发布者的完成事件在 flatMap 中终止,并且不会传递给下游订阅者。

一个使用 dataTaskPublisher 的这样的例子:

let remoteDataPublisher = Just(self.testURL!)  // 1
    .flatMap { url in  // 2
        URLSession.shared.dataTaskPublisher(for: url)  // 3
        .tryMap { data, response -> Data in  // 4
            guard let httpResponse = response as? HTTPURLResponse,
                httpResponse.statusCode == 200 else {
                    throw TestFailureCondition.invalidServerResponse
            }
            return data
        }
        .decode(type: PostmanEchoTimeStampCheckResponse.self, decoder: JSONDecoder())  // 5
        .catch {_ in  // 6
            return Just(PostmanEchoTimeStampCheckResponse(valid: false))
        }
    }
    .eraseToAnyPublisher()

  1. Just 以传入一个 URL 作为示例启动此发布者。
  2. flatMap 以 URL 作为输入,闭包继续创建一次性发布者管道。
  3. dataTaskPublisher 使用输入的 url 发出请求。
  4. 输出的结果(一个 (Data, URLResponse) 元组)流入 tryMap 以解析其他错误。
  5. decode 尝试将返回的数据转换为本地定义的类型。
  6. 如果其中任何一个失败,catch 将把错误转换为一个默认的值。 在这个例子中,是具有预设好 valid = false 属性的对象。

2. 网络受限时从备用 URL 请求数据

目的: 在 Apple 的 WWDC 2019 演示 Advances in Networking, Part 1 中,使用 tryCatchtryMap 操作符提供了示例模式,以响应网络受到限制的特殊错误。

// Generalized Publisher for Adaptive URL Loading
func adaptiveLoader(regularURL: URL, lowDataURL: URL) -> AnyPublisher<Data, Error> {
    var request = URLRequest(url: regularURL)  // 1
    request.allowsConstrainedNetworkAccess = false  // 2
    return URLSession.shared.dataTaskPublisher(for: request)  // 3
        .tryCatch { error -> URLSession.DataTaskPublisher in  // 4
            guard error.networkUnavailableReason == .constrained else {
               throw error
            }
            return URLSession.shared.dataTaskPublisher(for: lowDataURL)  // 5
        .tryMap { data, response -> Data in
            guard let httpResponse = response as? HTTPUrlResponse,  // 6
                   httpResponse.statusCode == 200 else {
                       throw MyNetworkingError.invalidServerResponse
            }
            return data
}
.eraseToAnyPublisher()  // 7

在苹果的 WWDC 中的这个例子,提供了一个函数,接受两个 URL 作为参数 —— 一个主要的 URL 和一个备用的。 它会返回一个发布者,该发布者将请求数据,并在网络受到限制时向备用 URL 请求数据。

  1. request 变量是一个尝试请求数据的 URLRequest
  2. 设置 request.allowsConstrainedNetworkAccess 将导致 dataTaskPublisher 在网络受限时返回错误。
  3. 调用 dataTaskPublisher 发起请求。
  4. tryCatch 用于捕获当前的错误状态并检查特定错误(受限的网络)。
  5. 如果它发现错误,它会使用备用 URL 创建一个新的一次性发布者。
  6. 由此产生的发布者仍可能失败,tryMap 可以基于对应到错误条件的 HTTP 响应码来抛出错误,将此映射为失败。
  7. eraseToAnyPublisher 可在操作符链上进行类型擦除,因此 adaptiveLoader 函数的返回类型为 AnyPublisher<Data, Error>

在示例中,如果从原始请求返回的错误不是网络受限的问题,则它会将 .failure 结束事件传到管道中。 如果错误是网络受限,则 tryCatch 操作符会创建对备用 URL 的新请求。

参考

https://heckj.github.io/swiftui-notes/index_zh-CN.html

代码

https://github.com/heckj/swiftui-notes

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/387056.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

python 基础知识点(蓝桥杯python科目个人复习计划40)

今日复习内容&#xff1a;矩阵乘法&#xff0c;高斯消元 哈哈&#xff0c;我来干回老本行&#xff0c;复习点儿数学类专业学的东西 因为电脑上制作费时间&#xff0c;所以我直接用我的《高等代数》和《数值分析》笔记。 一.矩阵乘法 例题1&#xff1a;矩阵相乘 题目描述&am…

three.js 细一万倍教程 从入门到精通(三)

目录 五、详解PBR材质纹理 5.1、详解PBR物理渲染 5.2、标准网格材质与光照物理效果 5.3、置换贴图与顶点细分设置 5.4、设置粗糙度与粗糙度贴图 5.5、设置金属度与金属贴图 5.6、法线贴图应用 5.7、如何获取各种类型纹理贴图 5.8、纹理加载进度情况 单张图片加载 多…

Java学习手册——第七篇基础语法

Java学习手册——第七篇基础语法 1. 注释2. 顺序语句3. 条件语句3.1 if语句3.2 switch语句 4. 循环语句4.1 for循环4.2 while 语句4.3 do...while语句 本篇为大家快速入门Java基础语法&#xff0c;了解一个语言的基础语法是必要的&#xff0c; 因为我们后期都是需要用这些基础语…

基于CU,PO,RD,IPO矩阵图分析数据资产-自创

术语 数据资产&#xff1a;数据资产是具有价值的数据资源。没有价值的数据资源&#xff0c;通过采集&#xff0c;整理&#xff0c;汇总等加工后&#xff0c;也可以成为具有直接或间接价值的数据资产。传统企业逐渐数字化转型&#xff0c;尤其是互联网企业&#xff0c;都十分重视…

文献速递:肿瘤分割---- 弱监督肝肿瘤分割,使用Couinaud区段标注

文献速递&#xff1a;肿瘤分割---- 弱监督肝肿瘤分割&#xff0c;使用Couinaud区段标注 01 文献速递介绍 肝癌是世界上导致癌症死亡的主要原因之一&#xff0c;也是第二大常见的癌症死因。本稿件于2021年10月28日收到&#xff0c;2021年11月24日修订&#xff0c;2021年12月1…

[Linux开发工具]项目自动化构建工具-make/Makefile

&#x1f4d9; 作者简介 &#xff1a;RO-BERRY &#x1f4d7; 学习方向&#xff1a;致力于C、C、数据结构、TCP/IP、数据库等等一系列知识 &#x1f4d2; 日后方向 : 偏向于CPP开发以及大数据方向&#xff0c;欢迎各位关注&#xff0c;谢谢各位的支持 目录 1.背景2.依赖关系和依…

【制作100个unity游戏之23】实现类似七日杀、森林一样的生存游戏17(附项目源码)

本节最终效果演示 文章目录 本节最终效果演示系列目录前言制作木板UI直接复制和工具一样的即可检查背包是否有指定数量的空插槽 源码完结 系列目录 前言 欢迎来到【制作100个Unity游戏】系列&#xff01;本系列将引导您一步步学习如何使用Unity开发各种类型的游戏。在这第23篇…

品牌之门:概率与潜力的无限延伸

在品牌的世界里&#xff0c;每一个成功的推广都像是打开一扇门&#xff0c;从未知走向已知&#xff0c;从潜在走向显现。这扇门&#xff0c;既是品牌的起点&#xff0c;也是品牌发展的无限可能。 品牌&#xff0c;就像一扇紧闭的门&#xff0c;它静静地矗立在那里&#xff0c;…

toString()、equals()、clone()用法

Java中所有类的对象都可以直接使用Object类中提供的一些方法 1. toString()&#xff1a;返回对象的字符串表示形式&#xff0c;通常在类中重写&#xff0c;以便于返回的是对象的内容 2. equals()&#xff1a;判断两个对象的地址是否相等&#xff0c;直接使用也一样&#xff0c;…

【蓝桥杯】灭鼠先锋

一.题目描述 二.解题思路 博弈论&#xff1a; 只能转移到必胜态的&#xff0c;均为必败态。 可以转移到必败态的&#xff0c;均为必胜肽。 最优的策略是&#xff0c;下一步一定是必败态。 #include<iostream> #include<map> using namespace std;map<string,bo…

【Linux系统学习】6.Linux系统软件安装

实战章节&#xff1a;在Linux上部署各类软件 前言 为什么学习各类软件在Linux上的部署 在前面&#xff0c;我们学习了许多的Linux命令和高级技巧&#xff0c;这些知识点比较零散&#xff0c;进行练习虽然可以基础掌握这些命令和技巧的使用&#xff0c;但是并没有一些具体的实…

C++:priority_queue模拟实现

C&#xff1a;priority_queue模拟实现 什么是priority_queue模拟实现向上调整算法向下调整算法插入与删除 仿函数 什么是priority_queue priority_queue称为优先级队列。优先级队列是一种特殊的队列&#xff0c;其中每个元素都有一个相关的优先级。元素的优先级决定了它们在队…

NSSCTF Round#18 RE GenshinWishSimulator WP

恶搞原神抽卡模拟器 看到软件的界面&#xff0c;大致有三种思路&#xff1a; 修改石头数量一直抽&#xff0c;如果概率正常肯定能抽到&#xff08;但是估计设置的概率是0&#xff09;在源码里找flag的数据把抽卡概率改成100%直接抽出来 Unity逆向&#xff0c;根据经验应该dnsp…

助眠神器小程序源码|白噪音|小睡眠|微信小程序前后端开源

安装要求和说明后端程序运行环境&#xff1a;NginxPHP7.4MySQL5.6 PHP程序扩展安装&#xff1a;sg11 网站运行目录设置为&#xff1a;public 伪静态规则选择&#xff1a;thinkphp 数据库修改文件路径&#xff1a;/config/database.php需要配置后端的小程序配置文件&#xff0c;…

力扣hot1--哈希

推荐一个博客&#xff1a; 一文看懂哈希表并学会使用C STL 中的哈希表_哈希表end函数-CSDN博客 哈希做法&#xff1a; 我们将nums[i]记为key&#xff0c;将i记为value。 判断target-nums[i]是否在哈希表中&#xff0c;如果在说明这两个值之和为target&#xff0c;那么返回这两…

【Java】零基础蓝桥杯算法学习——线性动态规划(一维dp)

线性dp——一维动态规划 1、考虑最后一步可以由哪些状态得到&#xff0c;推出转移方程 2、考虑当前状态与哪些参数有关系&#xff0c;定义几维数组来表示当前状态 3、计算时间复杂度&#xff0c;判断是否需要进行优化。 一维动态规划例题&#xff1a;最大上升子序列问题 Java参…

Linux第48步_编译正点原子的出厂Linux内核源码

编译正点原子的出厂 Linux 内核源码&#xff0c;为后面移植linux做准备。研究对象如下&#xff1a; 1)、linux内核镜像文件“uImage” 路径为“arch/arm/boot”&#xff1b; 2)、设备树文件“stm32mp157d-atk.dtb” 路径为“arch/arm/boot/dts” 3)、默认配置文件“stm32m…

第二部分阶段总结

第二部分阶段总结 1.知识补充1.1 nolocal关键字1.2 yield from1.3 深浅拷贝 2.阶段总结3.考试题 1.知识补充 1.1 nolocal关键字 在之前的课程中&#xff0c;我们学过global关键字。 name rootdef outer():name "武沛齐"def inner():global namename 123inner()…

LeetCode、739. 每日温度【中等,单调栈】

文章目录 前言LeetCode、739. 每日温度【中等&#xff0c;单调栈】题目链接及分类思路单调栈 资料获取 前言 博主介绍&#xff1a;✌目前全网粉丝2W&#xff0c;csdn博客专家、Java领域优质创作者&#xff0c;博客之星、阿里云平台优质作者、专注于Java后端技术领域。 涵盖技…

【每日一题】尾随零

尾随零 目录 思路&#xff1a;代码实现&#xff1a; 思路&#xff1a; 最开始看到这题就只想到规规矩矩的做题&#xff0c;先算阶乘在算0&#xff0c;后来提交时总是提示溢出&#xff0c;不死心&#xff0c;改来改去最后没招了。 后来看题解才知道要看5的个数&#xff01; …