我正在开发一个应用程序(swift),我需要在UIWebView中加载一个网页。在UIWebView中有一个<img src="http://www.example.com/uploads/43454.jpg" />
元素。
在这种情况下一切正常,但问题是我的 43454.jpg 图像每次都可以为 5-10 MB。因此,当UIWebView加载时,它会继续加载图像约2分钟。另外,这个<img>
标签可以有随机来源,即22234.jpg
、98734.jpg
、33123.jpg
等等。
因此,为了解决这种情况,我尝试使用以下方法:
-
列出我们需要在UIWebView中显示的所有可能的图像,在应用程序启动时下载并缓存它们(为此目的使用翠鸟库)。
-
当我的 UIWebView 最初加载我的 URL 时,它没有任何元素
src
属性<img>
,但有一个data-image-name="22234.jpg"
属性值对。 -
现在,当 UIWebView 完成加载其内容时,从
data-image-name
属性中获取图像名称值。
检查缓存中的该图像 ,并使用缓存中的该图像更新
<img>
元素的 src 属性。
这样UIWebView就不会一遍又一遍地下载图像。
注意:假设 UIWebView 自动管理资源缓存。所有其他文件类型*.js
,*.css
被正确缓存,而不是一遍又一遍地加载。图像也是如此,不知道为什么。
如果这种方法看起来没问题,那么我应该如何完成它(Swift 2.2)?
任何快速的帮助将不胜感激。谢谢
在我的一个项目中,这似乎是相同的情况。我有完全相同的情况。我将在此处粘贴我的代码,也许它可以帮助您找出解决方案。
-
一旦我的应用程序加载,我就会创建一个图像 URL 数组并将其传递给
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()
在我的 Web 视图 屏幕上,我最初加载了我的 Web 视图,然后使用以下代码检查缓存中的特定图像,如果找到,则将其转换为 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)');")! } }
希望对您有所帮助。
听起来你基本上是在说"我提前知道图像是什么,所以我不想每次都等待UIWebView从服务器加载它们。 我希望 html 改用我的本地副本。
虽然这是一个黑客,但我的第一个想法是:
- 有 2 个 UIWebViews:一个对用户可见,另一个是隐藏的。
- "触发"隐藏的UIWebView中的真实页面。 当 HTML 到达您时...
- 创建一个新字符串,该字符串是该 HTML 的副本,但图像标记表示
<img src="http://...
替换为<img src="file://...
并指向磁盘上的正确图像。 - 现在告诉可见的 UIWebView 加载您在步骤 3 中构建的 HTML 字符串。