Swift中URL處理中的注意點

搶手的哥發表於2018-01-25

日常的開發當中,網路請求是不可或缺的。而在網路訪問請求中,經常會遇到有中文空格字元的情況,直接用這些字串去訪問是無法正常訪問,需要我們做進一步的處理。

一般處理

let urlString = "http://10.0.3.86/中文/main.html#/help"
複製程式碼

比如以上的url,想使用webview進行訪問或者是原生髮起http請求,都需要進行轉碼處理。 有人會問,這有什麼難的?拿起鍵盤就是幹

就是幹.png

OC:
NSString* encodedString = [urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

Swift:
let encodedString = urlString.addingPercentEscapes(using: .utf8)

複製程式碼

一敲程式碼,emmmmm~~ Xcode發警告了,該方法已經過期,用下面的方法替代,於是緊接著:

OC:
NSString* encodedString = [urtString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];

Swift:
let encodedString = urlString.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)
複製程式碼

OK,轉碼處理一下,再訪問轉碼之後的url。 what?還是不能正常訪問? 我們來看看轉碼之後的url是什麼:

image.png
原來是因為最後的#被轉碼成了%23 前端開發的小夥伴說這個#不能動,只能我們不轉碼。不轉碼那麼夾雜中文字元怎麼辦呢?—— 修改引數所以我們的需求變化成:除了url裡面的#不動,其他該轉碼的都轉碼

NSMutableCharacterSet *set  = [[NSCharacterSet URLQueryAllowedCharacterSet] mutableCopy];
[set addCharactersInString:@"#"];
NSString *encodedString     = [urlSring stringByAddingPercentEncodingWithAllowedCharacters:set];
複製程式碼

如上手動修改轉碼引數,OK 可以了。 Swift如法炮製

let charSet = CharacterSet.urlQueryAllowed as! NSMutableCharacterSet
charSet.addCharacters(in: "#")
let encodingString = urlStr.addingPercentEncoding(withAllowedCharacters: charSet as CharacterSet)
複製程式碼

雖然語言不一樣,但是思路一樣。emmmm...你會驚人的發現,根本不管用!!!

wc.png

原因分析

問題是出在let charSet = CharacterSet.urlQueryAllowed as! NSMutableCharacterSet這一行,在swift語言中,Foundation框架中的很多class都重新用struct重寫了,比如NSString和String,NSUrl和URL,如果要使用類似於OC一些特性,有時候需要as來強轉成對應的NS開頭的類。強轉的過程中,CharacterSet應該轉成NSCharacterSet,而不應該是NSMutableCharacterSet,也就是說子類指標指向了父類物件,父類裡面沒有子類的方法,所以執行charSet.addCharacters(in: "#")的時候,無法正確新增。

Swift正確的寫法

順著原因一路分析,應該這麼寫:

方法一:
let charSet = CharacterSet.urlQueryAllowed as NSCharacterSet
let mutSet = charSet.mutableCopy() as! NSMutableCharacterSet
mutSet.addCharacters(in: "#")
let encodingURL = urlStr.addingPercentEncoding(withAllowedCharacters: mutSet as CharacterSet)
複製程式碼

當然還有其他寫法:

方法二:
let charSet = NSMutableCharacterSet()
charSet.formUnion(with: CharacterSet.urlQueryAllowed)
charSet.addCharacters(in: "#")
let encodingURL = urlStr.addingPercentEncoding(withAllowedCharacters: charSet as CharacterSet)
複製程式碼

方法一和二本質是一樣的,其實沿用的OC的思想,先構造一個可變物件,再加入自定義的字元。如果要像OC這麼搞,那麼蘋果設計swift的意義何在?換句話說,swift用結構體寫重寫這個類一定考慮到這個問題,那就應該有相應的處理方法。

查閱官方文件吧,少年!

image.png
果不其然,找到一個方法,用來插入字元。 所以還有第三種寫法:

方法三:
var charSet = CharacterSet.urlQueryAllowed
charSet.insert(charactersIn: "#")
let encodingURL = urlStr.addingPercentEncoding(withAllowedCharacters: charSet )
複製程式碼

我們來看一下最終結果

結果.png
OK,符合需求!

相關文章