I am Load Html File to webview using load html string method. All works fine. in my code user choose image as profile and choosen image save on fix path and name. when user choose image and when web view reload at that time image show old image. image updated to directory but not show.
This problem only occure in Ipad, In Iphone work fine.
Have any Suggestion.? then please suggest
//My Loading Code
webview.loadHTMLString(invoiceHTML, baseURL: NSURL(string:resumeComposer.HTMLFilePath)! as URL)
//Image Source update to HTML String code
imgPath = URL(fileURLWithPath: folderpathforNormal).appendingPathComponent("ProfileImg.png").path
HTMLContent = HTMLContent?.replacingOccurrences(of: "*userimage*", with: imgPath)
clear the UIWebview cache first like this:
//to remove cache from UIWebview
URLCache.shared.removeAllCachedResponses()
if let cookies = HTTPCookieStorage.shared.cookies {
for cookie in cookies {
HTTPCookieStorage.shared.deleteCookie(cookie)
}
}
Related
All I do is simply:
let html = try String(contentsOf: hereMyUrl)
but the content of html is not the same as it displayed with a browser. Why? I cannot find some tags with specific attributes. I suppose it is loaded later with js. But how to accomplish that with Swift?
However when I try to it with WKWebView:
let wk = WKWebView()
let request = URLRequest(url: URL(string: hereMyUrl)!)
wk.load(request)
wk.evaluateJavaScript("document.documentElement.outerHTML.toString()") { html, error in
print("++++++===")
print(html)
print("++++++===")
}
I get nil there. Why?
You just see your html content with that method. Not Javascript or any other scripts which runs as a program on the html and can change the content during the life cycle of the web page.
I'm using SDWebImages library to get image for thumbnails. It is working seemlesly.
However when I navigate from video to a controller where I play video, I need to show thumbnail once again. I need an image path to pass to the player.
The problem is if I pass the same URL the player will download the image once again. In order to avoid this behaviour i'm trying to get the image from disc which is already stored there by sdwebimages library.
/// get thumbnail from cache
var thumbnail: String?
if (video?.hasThumbnail) {
let urlString = "https://test.com/image/001.png"
if let path = SDImageCache.shared.cachePath(forKey: urlString) {
thumbnail = path
} else {
thumbnail = urlString
}
}
This is working on a simulator, but NOT on the real device.
Please read more about how to use
imageView.sd_setImage(with: URL(string: "http://www.example.com/path/to/image.jpg"), placeholderImage: UIImage(named: "placeholder.png"))
I am working on an app (swift) where i need to load a web page inside UIWebView. Inside that UIWebView there's an <img src="http://www.example.com/uploads/43454.jpg" /> element.
All works fine in this scenario, but the problem is that my 43454.jpg image can be of 5-10 megabytes everytime. So when the UIWebView loads it keeps on loading image for about 2 minutes. Plus this <img> tag can have random sources i.e. 22234.jpg, 98734.jpg, 33123.jpg, and so on.
So to tackle this situation I am trying to use following approach:
List all possible images that we need to show in UIWebView, download and cache them (used Kingfisher library for this purpose) at aplication's startup.
When my UIWebView loads my URL initially, it has nothing in it's <img> elements src attribute, but have a data-image-name="22234.jpg" attribute-value pair.
Now when UIWebView finishes loading its contents, get the image name value from data-image-name attribute.
Check for that image in cache, and update the <img> element's src attribute with that image from cache.
This way UIWebView won't be downloading the image over and over again.
Note: Assuming that UIWebView automatically manages resource cache. All other file types *.js, *.css are being properly cached and not being loaded over and over again. The same doesn't go for images, don't know why.
If this approach seems okay, then how should I accomplish it (Swift 2.2)?
Any quick help will be much appreciated. Thanks
This seems to be the same situation in one of my projects. I had exactly this same scenario. I am going to paste my code here, may be it helps you figure out your solution.
As soon as my app loads I create an array of image URLs and pass it to Kingfisher library to download and cache all images (to disk).
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()
At my web view screen I initially loaded my web view and after that used following code to check for particular image in cache and if found converted it into a base64 string and put it back in src attribute of the element.
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)');")!
}
}
Hope it helps.
It sounds like you're basically saying "I know what the images are ahead of time, so I don't want to wait for the UIWebView to load them from the server every time. I want the html to use my local copies instead."
While it's a hack, my first thought was:
Have 2 UIWebViews: one is visible to the user and the other is hidden.
"Trigger" the real page in the hidden UIWebView. When the HTML reaches you...
Create a new string, that is a copy of that HTML, but with the image tags that say <img src="http://... replaced with <img src=\"file://... and pointing to the correct image(s) on disk.
Now tell the visible UIWebView to load that HTML string you built in step 3.
I have silly problem with loading image from the file. I have two views putted to UITabBarController.
At the first view user can load his image from the Photo Library or Camera. Second view present this photo. This file is on the server. If user doesn't choose his image server sent custom image. If there is uploaded photo it will push user's picture.
When user tap button there is a menu with options. For example we will decide to take picture from the Photo Library. After user took image:
func imagePickerController(picker: UIImagePickerController, didFinishPickingImage image: UIImage!, editingInfo: [NSObject : AnyObject]!) {
self.saveUserImage(userID, imageData: UIImagePNGRepresentation(image)!)
apiManager.userUploadProfile(userID, imageData: UIImagePNGRepresentation(image)!)
userImageView.image = image
}
func saveUserImage(userUUID: String, imageData: NSData) {
let path = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true).last
let savePath = path! + "/\(userUUID)-user.png"
NSFileManager.defaultManager().createFileAtPath(savePath, contents: imageData, attributes: nil)
}
After that point user can see chosen picture and everything is okey. When user change tab, second view will refresh all data on it and again will download all images and data from the server. Unfortunately images that contains old user image doesn't refresh and there is still old photo.
When we come back to the first tab image is going back to old image but after few seconds.
The strangest thing is if I am checking server there is new uploaded image and in the app container it exist too. When I restart the app everything works perfectly.
It looks like this image is saved in the memory and iOS takes old version from RAM or from some other swap. How refresh UIImageView and show current saved image?
EDIT:
There is a method which load the image
func userProfilePicture(userId: String) -> UIImage {
let cacheDirectory = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true).last
let savePath = cacheDirectory! + "/\(userId)-user.png"
if NSFileManager.defaultManager().fileExistsAtPath(savePath) {
if let image = UIImage(named: savePath) {
return image
}
}
return UIImage(named: "test_avatar")!
}
I can't comment but i was facing a similar issue but i have a question, does the picture get uploaded before the user changes tabs, or after? Even if you call the function to update the database, it takes some time to actually "send the new photo/path to the photo to the database". Here are your options, if the picture is not in the server at the time of the switching tabs, implement a loading ui until it has successfully uploaded and the new, updated value, into the database. An easy way to do that would be to use the SVProgressHUD pod and set the default mask type to .clear which disables user interaction. Option 2, is to pass the actual UIImage via a static variable, or in the prepare for segue method, or through a struct, or any other way and set the picture that needs to be refreshed to the uiimage without getting it from the server only when you switch tabs.
Okey, I found the answer. The problem was in initialize UIImage. We have two methods to load image from file.
First one load the image and cache it in memory. Later it use only a reference to this image data in memory:
let image = UIImage(named: savePath)
Second method load image strictly from file every time when user use that function:
let image = UIImage(contentsOfFile: savePath)
Right now it works perfectly :D
Using Photos API(PHImageManager) i am able to get list of photos url and photo object.
When I am trying to use that url in webview , image is not displaying
Consider the following image url which I got from Photos API(PHImageManager)
you just have to take that burl in string and then load that string in webview in viewdidload
like
urlStr = obj["url"] as! String
and then load that url in uiwebview
webview.loadRequest(NSURLRequest(URL: NSURL(string: urlStr)!))