在 Swift 中,大家經常會用 URL 來初始化一個路徑,比如網頁的鏈接。比如這樣:
1 2 3 4 5 6 |
…… @IBAction func goToWeb(_ sender: NSButton) { let url = URL(string: "https://v2mm.tech/category/80/logcg-input-method") NSWorkspace.shared.open(url!) } …… |
當用戶點擊按鈕(比如說這個幫助按鈕),那麼一下子就幫用戶打開默認的瀏覽器,並打開指定的頁面(這裡是個論壇)。
那麼,如果你的鏈接是這樣的: "HTTPS://v2mm.tech/topic/618/怎樣優雅地使用落格輸入法的點劃功能" 那麼很不幸,崩潰。
崩潰的原因是 NSWorkspace.共享.打開(url!) 這一句,再具體一點就是 url 這個變量遇到了空值——說白了就是空指針。為什麼會這樣呢?
顯然,這個 URL 對像沒有初始化成功。
URL 不能處理中文字符
我們必須用其他的辦法來讓他初始化——畢竟,瀏覽器是支持這樣打開一個鏈接的,你也不可能去要求網站提供商改變他們的頁面鏈接,這個時候就要用到 % 大法了。
百分比編碼
也就是常說的百分號編碼,它能夠讓 URL ,也就是你的鏈接支持一些奇奇怪怪的字符——比如中文。所以,上文中我們那個字符串,也可以是這樣: HTTPS://v2mm.tech/topic/618/%D4%F5%D1%F9%D3%C5%D1%C5%B5%D8%CA%B9%D3%C3%C2%E4%B8%F1%CA%E4%C8%EB%B7%A8%B5%C4%B5%E3%BB%AE%B9%A6 這個和上文中的帶有中文的鏈接是等價的。其實,你有時候經常會在一些跳轉網站頁面看到一長串這樣的百分號,其實他們就是把那個要跳轉的鏈接完全編碼成了百分號格式,包括那些 /// : HTTPS%3一個%2F%2Fv2mm.高科技%2Ftopic%2F618%2F%D4%F5%D1%F9%D3%C5%D1%C5%B5%D8%CA%B9%D3%C3%C2%E4%B8%F1%CA%E4%C8%EB%B7%A8%B5%C4%B5%E3%BB%AE%B9%A6%C4%DC
這樣一來,這個的 URL 都變成了沒有意義的文本串,就避免了在 URL 路徑里傳參時出現歧義。
那麼
該怎麼用代碼來實現這種編碼呢?
現成的 API 可以用,如下:
1 |
String.addingPercentEncoding(withAllowedCharacters: CharacterSet.capitalizedLetters) |
不過你要注意,這樣的編碼,會讓整個字符串被編碼,所以我們只需要編碼中文部分即可,那麼具體到本文中的例子,就是這樣的:
1 2 3 4 5 |
@IBAction func more(_ sender:Any?) { let url = URL(string: "https://v2mm.tech/topic/618/"+"怎样优雅地使用落格输入法的点划功能".addingPercentEncoding(withAllowedCharacters: CharacterSet.capitalizedLetters)!) NSWorkspace.shared.open(url!) } |
延伸閱讀
https://zh.wikipedia.org/zh-cn/百分号编码
http://web.chacuo.net/charseturlencode
本文由 落格博客 原創撰寫:落格博客 » URL 遇到 中文字符 無法初始化
轉載請保留出處和原文鏈接:https://www.logcg.com/archives/2765.html
插一句,如果域名中有中文,就要改用 punycode 編碼 ~(≧▽≦)/~啦啦啦
哦原來是這樣……我就特別討厭中文域名,輸入域名的時候還得來回切換……