最近遇到兩個(gè)bug都是與url encoding有關(guān)。
下載文件,假設(shè)地址是:
https://my.domain.com/download/我的圖片.png
對(duì)應(yīng)的代碼為:
NSString *remoteURL = @"https://my.domain.com/download/我的圖片.png";
// 如果url里含有中文,會(huì)返回nil,需要使用UTF8進(jìn)行encoding
NSURL *url = [NSURL URLWithString: remoteURL];
if(url == nil){
url = [NSURL URLWithString:[remoteURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
}
其實(shí),中文需要編碼這個(gè)不算什么。更坑的是下面這段。因?yàn)橹坝玫氖茿FNetworking 2.x版本,為了適配蘋果的IPv6,升級(jí)為3.x后,下載的代碼是:
NSString *fileName = @"下載的圖片.png";
NSString *documentDir = [NSHomeDirectory()
stringByAppendingPathComponent:@"Documents"];
NSString *localPath = [NSString stringWithFormat: @"%@/%@/%@", documentDir, @"downloadFiles", fileName];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
AFHTTPSessionManager *sessionManager = [AFHTTPSessionManager manager];
AFSecurityPolicy *securityPolicy = [AFSecurityPolicy defaultPolicy];
securityPolicy.allowInvalidCertificates = YES;
securityPolicy.validatesDomainName = NO;
sessionManager.securityPolicy = securityPolicy;
NSURLSessionDownloadTask *downloadTask = [sessionManager downloadTaskWithRequest:request progress:^(NSProgress * _Nonnull downloadProgress) {
// progress
} destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {
// block的返回值,要求返回URL,返回的URL是文件的位置(已經(jīng)encoding)
return [NSURL fileURLWithPath: localPath];
} completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {
// 設(shè)置下載完成的操作, filePath是下載文件的位置
if(!error){
// download success
}else{
// download failed
}
}];
[downloadTask resume];
注意:destination block中返回的是存儲(chǔ)目標(biāo)路徑,fileURLWithPath:會(huì)對(duì)localPath進(jìn)行encoding。
因此,當(dāng)再次打開已經(jīng)保存在本地的圖片(文檔)時(shí),直接使用localPath是不行的。原因就是本文開始提到的URLWithString:遇到中文會(huì)返回nil。所以,如果想要正常讀取已經(jīng)下載的文件,需要按照文章開頭提到的方法對(duì)localPath進(jìn)行encoding,或者直接使用completionHandler中返回的filePath。
那么,問題是可不可以直接不管是不是nil,直接進(jìn)行encoding,然后該干嘛干嘛呢?
答案是不行,這要看下載時(shí)提供的地址是不是已經(jīng)編碼了,如果對(duì)已經(jīng)encoding過的url再次進(jìn)行encoding,就會(huì)導(dǎo)致encoding后的字符串中的 % 會(huì)被再次encoding,當(dāng)然是不能被正確訪問的.