Swift 什么样的URL不符合RFC 3986,但符合RFC 1808、RFC 1738和RFC 2732?
国防部说: 返回初始化的URL组件对象,如果无法解析URL,则返回nil 知道:Swift 什么样的URL不符合RFC 3986,但符合RFC 1808、RFC 1738和RFC 2732?,swift,url,nsurl,rfc3986,nsurlcomponents,Swift,Url,Nsurl,Rfc3986,Nsurlcomponents,国防部说: 返回初始化的URL组件对象,如果无法解析URL,则返回nil 知道: Swift URL/NSURL用于基于RFC 1808、RFC 1738和RFC 2732的URL: Swift URLComponents/NSURLComponents用于基于RFC 3986的URL: 我假设当URL符合RFC 1808/1738/2732但不符合RFC 3986时,URLComponents的初始化将失败那是什么类型的URL?有什么例子吗? P>我有不同的暗示可能与不同的保留字符有关:
- Swift URL/NSURL用于基于RFC 1808、RFC 1738和RFC 2732的URL:
- Swift URLComponents/NSURLComponents用于基于RFC 3986的URL:
URLComponents
的初始化将失败那是什么类型的URL?有什么例子吗?
<> P>我有不同的暗示可能与不同的保留字符有关:
让我们从它的源代码中探索它,因为SWIFT基金会是开源的。
URLComponents
初始值设定项在和中实现,并且只调用NSURLComponents
的初始值设定项NSURLComponents
初始值设定项在中实现,只需调用\u CFURLComponentsCreateWithURL
\u CFURLComponentsCreateWithURL
在中实现,并执行以下操作:
- 带有
CFURLCopyAbsoluteURL
- 使用
创建失败,调用:\u CFURLComponentsCreateWithString
+a failable\u CFURIParserParseURIReference
\u CFURIParserURLStringIsValid
CFURLCopyAbsoluteURL
在中实现,仅在以下情况下失败:
#如果部署_目标| MACOSX |部署_目标|嵌入式
if(base&&CFURLIsFileReferenceURL(base)&&CFURLHasDirectoryPath(base)){
//16695827-如果基本URL是一个不以斜杠结尾的文件引用URL,我们必须先将其转换为文件路径URL,然后才能使其成为绝对URL。
base=CFURLCreateFilePathURL(alloc,base,NULL);
如果(!base){
//无法将文件引用URL转换为文件路径URL--失败将为空
返回NULL;
}
}
#恩迪夫
CFURLCreateFilePathURL
的实现在中,我的理解是,只有在没有方案或路径的情况下才会失败,这应该是不可能的,因为我们之前使用CFURLIsFileReferenceURL
测试了文件方案或文件存在性\u CFURIParserParseURIReference
是在中实现的,只有当URL长度超过2 GB时才会失败,我认为这与RFC规范无关\u CFURIParserValidateComponent
,并因无效字符或转义序列而失败这可能是最相关的部分。https://
或简单的a://
),我们使用保留字符来提供示例,例如:
//好的
让url=url(字符串:“a://@”)!
//撞车
让components=URLComponents(url:url,resolvingAgainstBaseURL:true)!
尝试URLComponents
的替代初始值设定项也将失败,因此不要试图认为这是不同的:
//崩溃
让components=URLComponents(字符串:url.absoluteString)!
结论
“a://@”
是有效NSURL但无效RFC 3986的一个示例
另一方面,一些Swift人士似乎希望将来统一对URL和URL组件的支持(不再有RFC差异): //未来实施说明:
//NSURL(真正的CFURL,它提供了它的实现)在处理一些更深奥(和一些不那么深奥)的字符串时有很多怪癖。我们希望将大部分内容转移到更现代的NSURL组件上,但二进制兼容问题使这一点变得困难。
//希望很快,我们可以将下面对NSURL的部分委托改为对NSURL组件的委托。它不能零碎地完成,因为否则我们将从API得到不一致的结果
我不确定他们打算怎么做,因为这意味着
URL(字符串:“a://@”)
会失败,或者URLComponents(字符串:“a://@”)
会成功。这真的很有趣,谢谢!还帮助我摆脱了代码覆盖率报告中困扰我的一行红色代码——尽管这是一个边缘案例!