美文网首页
ios native加载H5图片(转载)

ios native加载H5图片(转载)

作者: petter102 | 来源:发表于2016-06-02 16:55 被阅读747次

    本文转自标哥的技术博客

    首先,我们要获取HTML内容,并通过正则表达式来匹配出所有的<img src="..."/>
    的标签:
    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)];

    接下来,我们需要一个字典来存储HTML原始的URL和与之关联的本地URL。由于使用原始URL的md5值作为文件名字,因此本地路径也就唯一确定了。这里就将图片都放到Document下。

    NSMutableDictionary *urlDicts = [[NSMutableDictionary alloc] init];
    NSString *docPath = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];

    然后,我们需要遍历所有匹配到的<img src="..."/>
    标签,并提取出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]];
          // 先将链接取个本地名字,且获取完整路径
          [urlDicts setObject:localPath forKey:src];
        }
      }
    }
    

    }

    下一步,我们需要将HTML中所有的原始src的url值替换成我们app的沙盒中的图片路径,如果该路径中未存在,则需要去下载图片,否则不需要重复下载。如下:

    // 遍历所有的URL,替换成本地的URL,并异步获取图片
    for (NSString *src in urlDicts.allKeys) {
    NSString *localPath = [urlDicts objectForKey:src];
    html = [html stringByReplacingOccurrencesOfString:src withString:localPath];

    // 如果已经缓存过,就不需要重复加载了。
    if (![[NSFileManager defaultManager] fileExistsAtPath:localPath]) {
      [self downloadImageWithUrl:src];
    }
    

    }

    下载图片后,还需要将图片存储到该原始url对应的本地路径,也就是Document下,其文件名为原始url的md5值,其他也就可以得出去唯一路径。这里只贴出存储代码,关于如何下载图片,查看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);
    }

    难点
    这里有几处难点:
    如何匹配<img src="..."/>
    来查找图片链接
    在匹配到以后,如何获取src的值
    在得到src的值以后,如何在iOS原生获取图片后让webview加载

    这里使用了正则表达式来匹配查找<img src="..."/>
    ,匹配结果可能有多个,遍历数组就可以处理所有的图片链接:

    NSRegularExpression(pattern: "<img\ssrc[^>]*/>", options: .AllowCommentsAndWhitespace

    存储图片到沙盒
    通过获取到HTML中图片的链接后,我们需要通过ios原生的方式来发起请求,加载图片,在加载完成后,我们需要将图片存储到沙盒中document下:

    func saveImageData(data: NSData, name: String) ->String {
    let docPath = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)[0] as NSString

    let path = docPath.stringByAppendingPathComponent(name)

    // 若已经缓存过,就不需要重复操作了
    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
    }

    验证是否成功
    首先我们可以看到test.html中只有两个img标签:

    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内容中这两个<img>
    标签的src是否变化,结果如下:

    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" />

    根据效果图,我们可以看到图片是显示出来了,这就说明替换成功后仍然可以加载出来图片,实验成功。
    源代码
    想要下载源代码,请移步github下载,内有Swift版的工程和ObjC版的工程:https://github.com/CoderJackyHuang/iOSLoadWebViewImage

    相关文章

      网友评论

          本文标题:ios native加载H5图片(转载)

          本文链接:https://www.haomeiwen.com/subject/wodkdttx.html