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新知",每天准时分享一个新知识,这里只是同步,想要及时学到就来关注我吧!

相关推荐
彩旗工作室2 小时前
将iOS/macOS应用上架至App Store
macos·ios·应用商店·appstore
程序员老刘3 小时前
跨平台开发地图:客户端技术选型指南 | 2025年10月
flutter·react native·客户端
江东小bug王5 小时前
深入解析 iOS 与 macOS 应用程序生命周期(完整指南)
macos·ios
2501_916008898 小时前
iOS 发布全流程详解,从开发到上架的流程与跨平台使用 开心上架 发布实战
android·macos·ios·小程序·uni-app·cocoa·iphone
非专业程序员10 小时前
iOS/Swift:深入理解iOS CoreText API
ios·swift
某柚啊11 小时前
iOS移动端H5键盘弹出时页面布局异常和滚动解决方案
前端·javascript·css·ios·html5
xingxing_F12 小时前
Swift Publisher for Mac 版面设计和编辑工具
开发语言·macos·swift
RollingPin21 小时前
iOS八股文之 RunLoop
ios·多线程·卡顿·ios面试·runloop·ios保活·ios八股文
2501_916007471 天前
iOS 混淆工具链实战,多工具组合完成 IPA 混淆与加固(iOS混淆|IPA加固|无源码混淆|App 防反编译)
android·ios·小程序·https·uni-app·iphone·webview
LinXunFeng1 天前
Flutter webview 崩溃率上升怎么办?我的分析与解决方案
flutter·ios·webview