iOS 關於接口NSURL裏邊混合:中文、空格、特殊字符...狀況解決辦法(runtime、NSCharacterSet)

接口裏邊混合:中文空格特殊字符...項目很長時間了,代碼量級很大,想要修改怕是幾天幾夜不能睡覺(稍微誇張);ios

那麼有沒有更高效更安全的解決辦法,不用更改一點代碼,答案是:確定的!!!

解決思路:在執行URLWithString方法的時候,進行處理,那麼就須要運用到runtime上無所不能的,交換方法接口:

引入run time專用頭文件#import <objc/message.h>

method_exchangeImplementations(Method m1, Method m2)

eg:安全

1.www.baidu.com/中文ide

NSURL *url = [NSURL URLWithString:@"www.baidu.com/中文"]; NSLog(@"url=%@",url); 打印出來:url=nill

2.www.baidu.comui

NSURL *url = [NSURL URLWithString:@"www.baidu.com"]; NSLog(@"url=%@",url); 打印出來:url=www.baidu.com

因此這樣兩種狀況在項目中會很常見,下面咱們用分類的方法來解決這件頭痛的事情:
cmd+N
新建一個分類編碼


cateory.png

url.png

(NSUrl + url).png

咱們知道一個類Class調用的時候最早調用的方法是url

加載類的load方法

+ (void)loadspa

開始上代碼:code

// NSURL+url.h // // Created by 竇心東 on 2017/6/2. // Copyright © 2017年 竇心東. All rights reserved. // #import <Foundation/Foundation.h> @interface NSURL (url) +(instancetype)XD_URLWithString:(NSString *)URLString; @end
// // NSURL+url.m // // Created by 竇心東 on 2017/6/2. // Copyright © 2017年 竇心東. All rights reserved. // #import "NSURL+url.h" #import <objc/message.h> @implementation NSURL (url) //加載類的load方法 + (void)load{ NSLog(@"來到這%s",__func__); //1.拿到兩個方法 蘋果原來的URLWithString 和XD_URLWithString 交換兩個方法 //class_getClassMethod獲取類方法 class_getInstanceMethod獲取對象方法 Method URLWithStr = class_getClassMethod([NSURL class], @selector(URLWithString:)); Method XD_URLWithStr = class_getClassMethod([NSURL class], @selector(XD_URLWithString:)); //2.交換這兩個方法 調用A執行B method_exchangeImplementations(URLWithStr, XD_URLWithStr); } +(instancetype)XD_URLWithString:(NSString *)URLString{ //NSURL *url = [NSURL URLWithString:URLString]; //上邊這一句會出現死循環,由於交換機制調用URLWithString執行XD_URLWithString那麼 //直接調用XD_URLWithString,由於剛纔經過了交換,就至關於調用URLWithString,就像大話西遊上移神換影大法😄 NSURL *url = [NSURL XD_URLWithString:URLString]; if (url == nil) { NSString * urlstr = [URLString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLFragmentAllowedCharacterSet]]; url = [NSURL URLWithString:urlstr]; // NSLog(@"該URL爲空") ; return url; }else{ return url; } } @end
// // ViewController.m // Created by 竇心東 on 2017/6/2. // Copyright © 2017年 竇心東. All rights reserved. // #import "ViewController.h" #import <objc/message.h> @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. //建立一個URL 可是有可能爲空 //若是字符串有中文,這個URL就建立不成功,那麼咱們發送請求就會出錯 oc中沒有對URL爲空的監測機制 Swift裏面有可選項 //我須要爲URLWithString這個方法添加一個檢測是否爲空的功能 這個在持續很久的項目中做用特別大,不用改動原來的代碼就能夠實現 NSURL *url = [NSURL URLWithString:@"www.baidu.com/中文"]; NSLog(@"url=%@",url); } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } @end #運行結果: 2017-06-08 11:27:18.051 06-02 [26223:7685365] 來到這+[NSURL(url) load] 2017-06-08 11:27:18.160 06-02[26223:7685365] url=www.baidu.com/%E4%B8%AD%E6%96%87

over
有個方法值得注意:component

[URLString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLFragmentAllowedCharacterSet]];

.對象

@interface NSString (NSURLUtilities)
//Returns a new string made from the receiver by replacing all characters not in the allowedCharacters set with percent encoded characters.
UTF-8 encoding is used to determine the correct percent encoded characters.
Entire URL strings cannot be percent-encoded.
This method is intended to percent-encode an URL component or subcomponent string, NOT the entire URL string.
Any characters in allowedCharacters outside of the 7-bit ASCII range are ignored.
返回一個新的字符串由接收方經過替換全部字符與百分比allowedCharacters集編碼字符。utf - 8編碼被用來肯定正確的百分比編碼字符。不能percent-encoded整個URL字符串。這種方法旨在percent-encode組件或子組件的URL字符串,而不是整個URL字符串。外的任何字符allowedCharacters 7位ASCII範圍將被忽略。

ios7.0及以後開始添加此方法

- (nullable NSString *)stringByAddingPercentEncodingWithAllowedCharacters:(NSCharacterSet *)allowedCharacters NS_AVAILABLE(10_9, 7_0);

.

// Returns a new string made from the receiver by replacing all percent encoded sequences with the matching UTF-8 characters.
返回一個新的字符串由接收方經過替換全部百分比與匹配的utf - 8字符編碼序列。

ios7.0及以後開始添加此屬性

@property (nullable, readonly, copy) NSString *stringByRemovingPercentEncoding NS_AVAILABLE(10_9, 7_0);

.

- (nullable NSString *)stringByAddingPercentEscapesUsingEncoding:(NSStringEncoding)enc

NS_DEPRECATED(10_0, 10_11, 2_0, 9_0, "Use -stringByAddingPercentEncodingWithAllowedCharacters: instead,
which always uses the recommended UTF-8 encoding,
and which encodes for a specific URL component or subcomponent
since each URL component or subcomponent has different rules for what characters are valid.");

ios9.0及以後開始棄用此方法

使用-stringByAddingPercentEncodingWithAllowedCharacters:相反,它老是使用推薦utf - 8編碼,編碼爲一個特定的URL組件或子組件因爲每一個URL組件或子組件有不一樣的規則,什麼角色都是有效的。

.

- (nullable NSString *)stringByReplacingPercentEscapesUsingEncoding:(NSStringEncoding)enc

NS_DEPRECATED(10_0, 10_11, 2_0, 9_0, "Use -stringByRemovingPercentEncoding instead,
which always uses the recommended UTF-8 encoding.");

ios9.0及以後開始棄用此方法

使用-stringByRemovingPercentEncoding相反,老是使用推薦的utf - 8編碼。
@end

推薦文章:
http://www.jianshu.com/p/21a21866e379
http://nshipster.cn/nscharacterset/


NSCharacterSet
相關文章
相關標籤/搜索