我正在开发一个app(swift),我需要在UIWebView中加载一个网页。在UIWebView中,有一个<img src="http://www.example.com/uploads/43454.jpg" />
元素。
在这种情况下一切正常,但问题是我的43454.jpg图像每次都可以是5-10兆字节。因此,当UIWebView加载时,它会继续加载图像大约2分钟。此外,此<img>
代码可以包含随机来源,即22234.jpg
,98734.jpg
,33123.jpg
等。
因此,为了解决这种情况,我尝试使用以下方法:
列出我们需要在UIWebView中显示的所有可能图像,在应用程序启动时下载并缓存它们(为此目的使用Kingfisher库)。
当我的UIWebView最初加载我的网址时,它没有任何内容<img>
元素src
属性,但有一个data-image-name="22234.jpg"
属性 - 值对。< / p>
现在,当UIWebView完成加载其内容时,请从data-image-name
属性中获取图像名称值。
检查缓存中的该图像,并使用缓存中的该图像更新<img>
元素的src属性。
这样UIWebView就不会一遍又一遍地下载图像。
注意:假设UIWebView自动管理资源缓存。所有其他文件类型*.js
,*.css
正在被正确缓存,而不是一次又一次地加载。同样不适用于图像,不知道为什么。
如果这种方法似乎没问题,那么我应该如何实现它(Swift 2.2)?
任何快速帮助将不胜感激。感谢
答案 0 :(得分:1)
在我的一个项目中,这似乎是相同的情况。我有完全相同的情况。我将在此处粘贴我的代码,可能会帮助您找到解决方案。
我的应用加载后,我会创建一个图像网址数组并将其传递给Kingfisher
库,以下载并缓存所有图像(到磁盘)。
for url in response {
let URL = NSURL(string: url as! String)!
self.PlanImagesArray.append(URL)
}
let prefetcher = ImagePrefetcher(
urls: self.PlanImagesArray,
optionsInfo: nil,
progressBlock: {
(skippedResources, failedResources, completedResources) -> () in
print("progress resources are prefetched: \(completedResources)")
print("progress resources are failedResources: \(failedResources)")
print("progress resources are skippedResources: \(skippedResources)")
},
completionHandler: {
(skippedResources, failedResources, completedResources) -> () in
print("These resources are prefetched: \(completedResources)")
print("These resources are failedResources: \(failedResources)")
print("These resources are skippedResources: \(skippedResources)")
self.activityLoadingIndicator.stopAnimating()
})
prefetcher.start()
在我的网页视图屏幕上,我最初加载了我的网页视图,然后使用以下代码检查缓存中的特定图像,如果发现将其转换为base64字符串并将其放回src
属性元素。
func webViewDidFinishLoad(webView : UIWebView) {
//UIApplication.sharedApplication().networkActivityIndicatorVisible = false
print("webViewDidFinishLoad")
let xlinkHref = webView.stringByEvaluatingJavaScriptFromString("document.getElementById('background_image').getAttribute('xlink:href')")
//print("xlink:href before = \(webView.stringByEvaluatingJavaScriptFromString("document.getElementById('background_image').getAttribute('xlink:href')"))")
if xlinkHref == "" {
let imageCacheKey = webView.stringByEvaluatingJavaScriptFromString("document.getElementById('background_image').getAttribute('data-cache-key')")
let imageCachePath = ImageCache.defaultCache.cachePathForKey(imageCacheKey! as String)
var strBase64:String = ""
webView.stringByEvaluatingJavaScriptFromString(
"var script = document.createElement('script');" +
"script.type = 'text/javascript';" +
"script.text = \"function setAttributeOnFly(elemName, attName, attValue) { " +
"document.getElementById(elemName).setAttribute(attName, attValue);" +
"}\";" +
"document.getElementsByTagName('head')[0].appendChild(script);"
)!
if(imageCachePath != "") {
ImageCache.defaultCache.retrieveImageForKey(imageCacheKey! as String, options: nil) { (imageCacheObject, imageCacheType) -> () in
let imageData:NSData = UIImageJPEGRepresentation(imageCacheObject!, 100)!
strBase64 = "data:image/jpg;base64," + imageData.base64EncodedStringWithOptions(.EncodingEndLineWithCarriageReturn)
webView.stringByEvaluatingJavaScriptFromString("setAttributeOnFly('background_image', 'xlink:href', '\(strBase64)');")!
}
} else {
webView.stringByEvaluatingJavaScriptFromString("setAttributeOnFly('background_image', 'xlink:href', '\(imageCacheKey)');")!
}
}
希望它有所帮助。
答案 1 :(得分:0)
听起来你基本上是在说#34;我知道图像是提前的,所以我不想等待UIWebView每次都从服务器加载它们。我希望html使用我的本地副本。&#34;
虽然它是一个黑客,但我的第一个想法是:
<img src="http://...
替换为<img src=\"file://...
并指向磁盘上正确图像的图像标记。