iOS 开发注意:在 iOS 17 中 URL 的行为有所更改

这里每天分享一个 iOS 的新知识,快来关注我吧

前言

Xcode 15 以及 iOS 17 已经发布一段时间了,作为开发者,需要关注的是哪些 API 有所改动,特别是底层的 API,影响面可能会比较广,今天讲一个关于 URL 对象的 API 更改。

当我们打开 URL 的初始化方法的官方文档 developer.apple.com/documentati...

For apps linked on or after iOS 17 and aligned OS versions, URL parsing has updated from the obsolete RFC 1738/1808 parsing to the same RFC 3986 parsing as URLComponents. This unifies the parsing behaviors of the URL and URLComponents APIs. Now, URL automatically percent- and IDNA-encodes invalid characters to help create a valid URL.

翻译一下就是 URL 解析已从过时的 RFC 1738/1808 解析更新为与 URLComponents 相同的 RFC 3986 解析。

什么是 RFC

RFC 是 Request for Comments 的首字母缩写,是互联网工程任务组 (IETF)的对于 URL 的规范出的文档,其中包含有关互联网和计算机网络相关主题(如路由、寻址和传输技术)的规范和组织说明。

针对新的标准,个人或团体可以向委员会提交内容,委员会工作组经过一系列审核并通过之后,RFC 生产中心 (RPC) 会为 RFC 分配一个唯一编号,并通过 RFC 编辑器发布。RFC 发布后,它永远不会更改。我们前面提到的 RFC 1738/1808RFC 3986 就是他们发布的其中一个标准。

苹果的支持

在 iOS 17 之前,URL 初始化时支持的是较久的 RFC 1738/1808 标准,但是 URLComponents 支持的是 RFC 3986 标准,两个标准不同导致 iOS 开发者在某些时候比较困惑,所以苹果在今年的更新中,终于把标准统一了,统一支持 RFC 3986 标准。

变化是什么?

在 iOS 17 之前,URL(string: "Not an URL") 会返回 nil,因为这是一个无效的 URL 格式,但是在 iOS 17 上,这段代码将会返回 Not%an%URL,相当于是把中间的空格进行了一次 encode。

csharp 复制代码
// iOS 16
let validURL = URL(string: "https://google.com") // 返回 https://google.com
let url = URL(string: "Not an URL")              // 返回 nil

// iOS 17
let validURL = URL(string: "https://google.com") // 返回 https://google.com
let url = URL(string: "Not an URL")              // 返回 Not%an%URL

新的行为对于老的项目可能不太友好,甚至可能出现非预期的行为,比如,之前可能会有这样的判断:

typescript 复制代码
if let url = URL(string: "Not an URL") {
    // url 有效
}

但这段代码在 Xcode 15 中 iOS 17 上也会走进去,因此可能导致非预期的后果。

如何兼容

Apple 在 iOS 17 的 URL 初始化方法中,添加了一个带有 Bool (默认值 true)的新参数 encodingInvalidCharacters,这个参数代表是否 encoding 掉无效的字符,如果传 false,URL 的行为将会和 iOS 16 上一致。

swift 复制代码
public init?(string: String, encodingInvalidCharacters: Bool)

使用效果如下:

csharp 复制代码
// iOS 16
let url = URL(string: "Not an URL") // => nil

// iOS 17
let url = URL(string: "Not an URL", encodingInvalidCharacters: false) // => nil

如果你不想改变 URL 的默认行为,从而兼容以前的代码,需要把之前使用 URL 初始化的方法加上 encodingInvalidCharacters: false 参数。

结论

虽然苹果使 URL 支持了新的标准,和 URLComponents 保持了一致,这是好事,但是一刀切直接把默认行为改掉,这点还是比较坑的。更保守的做法应该是开一个新的方法来支持新标准,并且将老的方法标记为过期,慢慢过渡。不得不说,苹果还是那个有些坑开发者的苹果。

这里每天分享一个 iOS 的新知识,快来关注我吧

本文同步自微信公众号 "iOS新知",每天准时分享一个新知识,这里只是同步,想要及时学到就来关注我吧!

相关推荐
用户093 小时前
如何避免写垃圾代码:iOS开发篇
ios·swiftui·swift
HarderCoder4 小时前
Swift 语法速通:iOS 开发必会的 8 大核心概念(图解+类比)
swift
HarderCoder4 小时前
Swift 6 并发编程:深入理解 `@unchecked Sendable` 的合法使用与陷阱
swift
HarderCoder5 小时前
Swift 6.0 协议扩展:解锁协议新特性,写出更优雅、更高效的代码
swift
HarderCoder17 小时前
iOS 知识积累第一弹:从 struct 到 APP 生命周期的全景复盘
ios
叽哥1 天前
Flutter Riverpod上手指南
android·flutter·ios
HarderCoder2 天前
Swift 6 并发时代,如何优雅地“抢救”你的单例?
swift
zhangmeng2 天前
FlutterBoost在iOS26真机运行崩溃问题
flutter·app·swift
HarderCoder2 天前
SwiftUI 踩坑记:onAppear / task 不回调?90% 撞上了“空壳视图”!
swift
HarderCoder2 天前
@isolated(any) 深度解析:Swift 并发中的“隔离追踪器”
swift