本文轉(zhuǎn)自標(biāo)哥的技術(shù)博客
首先啦租,我們要獲取HTML內(nèi)容农尖,并通過正則表達(dá)式來匹配出所有的<img src="..."/>
的標(biāo)簽:
NSURL *url = [[NSBundle mainBundle] URLForResource:@"test" withExtension:@"html"];
NSString *html = [[NSString alloc] initWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil];
NSRegularExpression regex = [NSRegularExpression regularExpressionWithPattern:@"<img\ssrc[^>]/>" options:NSRegularExpressionAllowCommentsAndWhitespace error:nil];
NSArray *result = [regex matchesInString:html options:NSMatchingReportCompletion range:NSMakeRange(0, html.length)];
接下來,我們需要一個(gè)字典來存儲HTML原始的URL和與之關(guān)聯(lián)的本地URL剧浸。由于使用原始URL的md5值作為文件名字锹引,因此本地路徑也就唯一確定了。這里就將圖片都放到Document下唆香。
NSMutableDictionary *urlDicts = [[NSMutableDictionary alloc] init];
NSString *docPath = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];
然后嫌变,我們需要遍歷所有匹配到的<img src="..."/>
標(biāo)簽,并提取出Src屬性值躬它,也就是我們要的原始URL腾啥。將并該URL存儲下來,以便下一步替換虑凛。
for (NSTextCheckingResult *item in result) {
NSString *imgHtml = [html substringWithRange:[item rangeAtIndex:0]];
NSArray *tmpArray = nil;
if ([imgHtml rangeOfString:@"src=\""].location != NSNotFound) {
tmpArray = [imgHtml componentsSeparatedByString:@"src=\""];
} else if ([imgHtml rangeOfString:@"src="].location != NSNotFound) {
tmpArray = [imgHtml componentsSeparatedByString:@"src="];
}
if (tmpArray.count >= 2) {
NSString *src = tmpArray[1];
NSUInteger loc = [src rangeOfString:@"\""].location;
if (loc != NSNotFound) {
src = [src substringToIndex:loc];
NSLog(@"正確解析出來的SRC為:%@", src);
if (src.length > 0) {
NSString *localPath = [docPath stringByAppendingPathComponent:[self md5:src]];
// 先將鏈接取個(gè)本地名字碑宴,且獲取完整路徑
[urlDicts setObject:localPath forKey:src];
}
}
}
}
下一步,我們需要將HTML中所有的原始src的url值替換成我們app的沙盒中的圖片路徑桑谍,如果該路徑中未存在,則需要去下載圖片祸挪,否則不需要重復(fù)下載锣披。如下:
// 遍歷所有的URL,替換成本地的URL贿条,并異步獲取圖片
for (NSString *src in urlDicts.allKeys) {
NSString *localPath = [urlDicts objectForKey:src];
html = [html stringByReplacingOccurrencesOfString:src withString:localPath];
// 如果已經(jīng)緩存過雹仿,就不需要重復(fù)加載了。
if (![[NSFileManager defaultManager] fileExistsAtPath:localPath]) {
[self downloadImageWithUrl:src];
}
}
下載圖片后整以,還需要將圖片存儲到該原始url對應(yīng)的本地路徑胧辽,也就是Document下,其文件名為原始url的md5值,其他也就可以得出去唯一路徑公黑。這里只貼出存儲代碼邑商,關(guān)于如何下載圖片,查看demo凡蚜。
NSData *data = UIImagePNGRepresentation(image);
NSString *docPath = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];
NSString *localPath = [docPath stringByAppendingPathComponent:[self md5:src]];
if (![data writeToFile:localPath atomically:NO]) {
NSLog(@"寫入本地失斎硕稀:%@", src);
}
難點(diǎn)
這里有幾處難點(diǎn):
如何匹配<img src="..."/>
來查找圖片鏈接
在匹配到以后,如何獲取src的值
在得到src的值以后朝蜘,如何在iOS原生獲取圖片后讓webview加載
這里使用了正則表達(dá)式來匹配查找<img src="..."/>
恶迈,匹配結(jié)果可能有多個(gè),遍歷數(shù)組就可以處理所有的圖片鏈接:
NSRegularExpression(pattern: "<img\ssrc[^>]*/>", options: .AllowCommentsAndWhitespace
存儲圖片到沙盒
通過獲取到HTML中圖片的鏈接后谱醇,我們需要通過ios原生的方式來發(fā)起請求暇仲,加載圖片步做,在加載完成后,我們需要將圖片存儲到沙盒中document下:
func saveImageData(data: NSData, name: String) ->String {
let docPath = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)[0] as NSString
let path = docPath.stringByAppendingPathComponent(name)
// 若已經(jīng)緩存過奈附,就不需要重復(fù)操作了
if NSFileManager.defaultManager().fileExistsAtPath(path) {
return path
}
do {
try data.writeToFile(path, options: NSDataWritingOptions.DataWritingAtomic)
} catch {
print("save image data with name: (name) error")
}
return path
}
驗(yàn)證是否成功
首先我們可以看到test.html中只有兩個(gè)img標(biāo)簽:
1
2
3
4
5
<img src="http://www.jhjcqc.com/ueditor/php/upload/image/20151014/1444783819412910.jpg" />
<img src="http://www.jhjcqc.com/ueditor/php/upload/image/20151014/1444783847836404.jpg" />
在我們替換路徑完成后全度,我們加載webview,然后打印出webview所加載的HTML內(nèi)容中這兩個(gè)<img>
標(biāo)簽的src是否變化桅狠,結(jié)果如下:
1
2
3
4
5
<img src="/Users/huangyibiao/Library/Developer/CoreSimulator/Devices/09692E07-2E79-4070-9537-CFD9F3141B0D/data/Containers/Data/Application/73F6D429-E0FD-4BD4-B0A5-85C1BD179840/Documents/5353c07f4c2ea0471b9f3ee36dedcaac" />
<img src="/Users/huangyibiao/Library/Developer/CoreSimulator/Devices/09692E07-2E79-4070-9537-CFD9F3141B0D/data/Containers/Data/Application/73F6D429-E0FD-4BD4-B0A5-85C1BD179840/Documents/54edea1f2edd444aaba9d0321d786962" />
根據(jù)效果圖讼载,我們可以看到圖片是顯示出來了,這就說明替換成功后仍然可以加載出來圖片中跌,實(shí)驗(yàn)成功咨堤。
源代碼
想要下載源代碼,請移步github下載漩符,內(nèi)有Swift版的工程和ObjC版的工程:https://github.com/CoderJackyHuang/iOSLoadWebViewImage