为什么转换 String
到URL
在 Swift 4.2 中然后转换 URL
回到String
使用 url.path
即使我使用 utf-8 编码,也要更改特殊字符的编码,例如德语变音符号 (ä, ö, ü)?
我写了一些示例代码来说明我的问题。我将字符串编码为 base64 以表明存在差异。
我对特殊字符和 swift 也有类似 Unresolved 问题 here .
示例代码
let string = "/path/to/file"
let stringUmlauts = "/path/to/file/with/umlauts/testäöü"
let base64 = Data(string.utf8).base64EncodedString()
let base64Umlauts = Data(stringUmlauts.utf8).base64EncodedString()
print(base64, base64Umlauts)
let url = URL(fileURLWithPath: string)
let urlUmlauts = URL(fileURLWithPath: stringUmlauts)
let base64Url = Data(url.path.utf8).base64EncodedString()
let base64UrlUmlauts = Data(urlUmlauts.path.utf8).base64EncodedString()
print(base64Url, base64UrlUmlauts)
输出
base64
和 base64Url
字符串保持不变,但 base64Umlauts
和 base64UrlUmlauts
是不同的。
"L3BhdGgvdG8vZmlsZQ==" for
base64
"L3BhdGgvdG8vZmlsZQ==" for
base64Url
"L3BhdGgvdG8vZmlsZS93aXRoL3VtbGF1dHMvdGVzdMOkw7bDvA==" for
base64Umlauts
"L3BhdGgvdG8vZmlsZS93aXRoL3VtbGF1dHMvdGVzdGHMiG/MiHXMiA==" for
base64UrlUmlauts
当我把 base64Umlauts
和 base64UrlUmlauts
字符串转换成在线 Base64 解码器,它们都显示 /path/to/file/with/umlauts/testäöü
,但是 ä, ö, ü
是不同的(不是视觉上的)。
最佳答案
stringUmlauts.utf8
使用 Unicode 字符 äöü
。
但是 urlUmlauts.path.utf8
使用 Unicode 字符 aou
,每个字符后跟组合 ¨
。
这就是您获得不同 base64 编码的原因 - 字符看起来相同但实际上编码不同。
真正有趣的是 Array(stringUmlauts)
和 Array(urlUmlauts.path)
是一样的。在您对完全相同的 String
值执行 UTF-8 编码之前,差异不会出现。
由于 base64 编码无关紧要,这里有一个更简洁的测试:
let stringUmlauts = "/path/to/file/with/umlauts/testäöü"
let urlUmlauts = URL(fileURLWithPath: stringUmlauts)
print(stringUmlauts, urlUmlauts.path) // Show the same
let rawStr = stringUmlauts
let urlStr = urlUmlauts.path
print(rawStr == urlStr) // true
print(Array(rawStr) == Array(urlStr)) // true
print(Array(rawStr.utf8) == Array(urlStr.utf8)) // false!!!
那么两个相等字符串的UTF-8编码有何不同呢?
一个解决方案是在 path
的结果上使用 precomposedStringWithCanonicalMapping
。
let urlStr = urlUmlauts.path.precomposedStringWithCanonicalMapping
现在你得到 true
来自:
print(Array(rawStr.utf8) == Array(urlStr.utf8)) // now true
关于ios - Swift URL.path 更改 utf-8 字符的编码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53093138/