UIWebView images in application documents folder not refreshing - iphone

I have a UIWebView where I display dynamically generated HTML via
[_webView loadHTMLString:htmlString baseURL:applicationDocumentsDirectory];
The HTML contains images such as <img src="chart1.png">. Each time the HTML is generated, the images are also freshly generated. (I have checked that they are indeed in the right location and updated.) However, after the first run, if I change the data and relaunch my UIWebView, it uses the old images.
I have tried:
[[NSURLCache sharedURLCache] removeAllCachedResponses];
to no avail. (Not surprising, maybe, as this relates to NSURLRequests.)
I know that there is the possibility of absolute URLs, but I have not tried this at it seems cumbersome and I want it to work with these simple relative URLs. The issue is not finding the images but updating them appropriately.
I also know that you could invent some scheme tricking the browser into thinking that the image is dynamic by changing the src to something like chart1.png?1234 where the number is random generated and always unique. This also seems like a useless workaround for an issue that should be simple to solve.
Any ideas?

You should have a proper reference to the image, otherwise it may not work. If you have the image and the html file in the same level then try using something like this,
<img src="./chart1.png">
Or if you want the images inside the folder then refer it using the proper path reference to it.
I hope it works.

hi i was having a similar problem with uiwebview whenever i loaded a previously loaded page old content was displayed. after investigating further i found that uiwebview content is loaded in the background and then displayed after its finished loading; however while it is loading old content is displayed. I fixed my problem by making my own uiwebview loading delegates and adding my own loading symbol insteaad of displaying old content.
-(void)webViewDidStartLoad:(UIWebView *)webView{
webView.hidden = true;
loader.animationImages =[NSArray arrayWithObjects:
[UIImage imageNamed:#"1.png"],
[UIImage imageNamed:#"2.png"],
[UIImage imageNamed:#"3.png"],
[UIImage imageNamed:#"4.png"],
[UIImage imageNamed:#"3.png"],
[UIImage imageNamed:#"2.png"],
[UIImage imageNamed:#"1.png"],
[UIImage imageNamed:#"5.png"]
,nil];
loader.animationDuration = 1.5;
loader.animationRepeatCount = 100;
[loader startAnimating];
}
-(void)webViewDidFinishLoad:(UIWebView *)webView{
[loader stopAnimating];
webView.hidden = false;
}
remember to link the delegates and all that other stuff
i hope this helps :)

You need to provide the absolute path of the image source.
NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString* path = [documentsDirectory stringByAppendingPathComponent:
#"/chart1.png" ];
I hope this works

Related

Append url to image path NSString?

I'm developing an iOS application consisting of a static sqlite database, series of tableviews and tab based detail view where the first view loaded in the detailview is a swipable imageView which loads a series of images.
I've got it working with this code where it looks for the image locally but I'd like to have it load the image from a URL or display a default image if no internet connection is available.
The images are named in the database as (for the example) image.jpg and I'd like all of them to load from the same URL directory (for the example) http://www.someurl.com/images/
Thank you
- (UIImage *) imageAtIndex:(NSUInteger)index {
Image *currentImage = (Image *) [self.images objectAtIndex:index];
NSString *path = [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:#"%#",[[currentImage filename] stringByDeletingPathExtension]] ofType:#"jpg"];
return [UIImage imageWithContentsOfFile:path];
}
The process for this is really very simple:
Try to download your image data using NSURLConnection
If successful, create a UIImage from the data
If either of the above fails, switch over to your placeholder/built-in image
Display the resulting image
I advise you have some sort of placeholder while the image is downloading, since that can take quite a while.
Don't bother with reachability; it's not 100% reliable, whereas actually trying the download is.
Avoid doing this on a background thread or queue. NSURLConnection is asynchronous out of the box to make this easier for you. There are a ton of third-party frameworks that try to simplify working with connections if you wish, though.
NSString *urlStr = [#"http://www.someurl.com/images/" stringByAppendingString:[currentImage filename]];
NSURL *url = [NSURL URLWithString:urlStr];
NSData *imageData = [NSData dataWithContentsOfURL:url];
UIImage *image = [[UIImage alloc] initWithData:data];
Or something like that...
If the image is large or the internet connection is slow, the NSData initialization might take some time. Consider getting the images data in a background thread, or use some existing framework for that like SDWebImage

UIImageView with setImage: Image is not Visible on Debugger Device

I'm trying to show an image with following method:
[myImageView setImage:[UIImage imageNamed:#"myImage.png"]];
And it's working just fine with the iPhone simulator. However, when I debug on the device, the image is not visible.
Clearly it's about resolution because the resolution of my image is much more higher than UIImageView's(and it has to be...) and also when I use an image with same resolution of UIImageView, it's working fine on device, too.
I tried what said here but it didn't solve my problem.
What do you suggest to make UIImageView work with larger images than its frame?
Thanks in advance.
If image resolution is your problem, try the solution provided here. Else, try the sample PhotoScroller in Apple's Reference Library. It provides a way to display big images in chunks (tiles). That should do what you want.
Do this,
myImageView=[[UIImageView alloc]initWithFrame:CGRectMake(50,50,200,300)];
[myImageView setImage:[UIImage imageNamed:#"myImage.png"]];
[self.view addSubView:myImageView];
It will work.
This is the simplest issue that can occur sometimes. It is because of the image name case sensitivity required in the device while the simulator ignore the case sensitivity for the image name.
So, make sure your image name in the bungle is exactly the same what you are specified here. Not even on capital or small letter difference. Just check the image name - "myImage.png"
Please let me know if you still have any problem in the UIImageView image display.
Since I'm downloading images to show in runtime, I'm getting the application main bundle path with this code below:
NSString *path = [NSString stringWithFormat:#"%#", [[NSBundle mainBundle] executablePath]];
NSArray *parts = [path componentsSeparatedByString:#"/"];
NSString *pathToSave = [path substringToIndex:([path length] - [[NSString stringWithFormat:#"%#", [parts objectAtIndex:[parts count]-1]] length])];
And I save images with this code:
NSString *url = [NSString stringWithFormat:#"%#", [imageURLs objectAtIndex:0]];
NSString *filename = [url lastPathComponent];
NSData *thedata = [NSData dataWithContentsOfURL:[NSURL URLWithString:url]];
NSString *localFilePath = [NSString stringWithFormat:#"%#%i%#", pathToSave, [[NSString stringWithFormat:#"%#", [element child:#"id"]] intValue], filename];
[thedata writeToFile:localFilePath atomically:YES];
When I manually download an image and add to project, [UIImageView setImage:] did work this time. So I realized that there's something wrong with saving images from URL.
The reason I didn't think this should be the problem is that it's working just fine with the iOS simulator.
I'll take a look at that issue, however since my application name contains special characters like "İ" (Turkish) I think that might be the reason, the application might not be able to save to correct path.

Xcode UIWEBVIEW download , save HTML file and show

I want to download a page and show this in WEBVIEW local, but the images are missing. The images are only shown, when I'm online, in offline mode they are missing. How can I solve this? This is the code I used up until now:
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
{
NSURL *url = [NSURL URLWithString:#"http://livedemo00.template-help.com/wt_37587/index.html"];
//[WEBVIEW loadRequest:reqURL];
// Determile cache file path
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *filePath = [NSString stringWithFormat:#"%#/%#", [paths objectAtIndex:0],#"index.html"];
// Download and write to file
NSData *urlData = [NSData dataWithContentsOfURL:url];
[urlData writeToFile:filePath atomically:YES];
// Load file in UIWebView
[WEBVIEW loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:filePath]]];
[super viewDidLoad];
}
I've been meaning to write this up for a few weeks now, and this question finally got me to do it. See Drop-in offline caching for UIWebView (and NSURLProtocol).
The short answer, in my experience, is that the easiest solution is to use an NSURLProtocol to intercept NSURLConnection requests (including the ones made by UIWebView) and write the results to disk. If the request is made when you're offline, just read the response from disk and replay it. This is extremely transparent to the rest of the application, and avoids all kinds of edge-cases related to subclassing NSURLCache. (For more information on how to subclass NSURLCache see Substituting local data for remote UIWebView requests on Cocoa With Love, and AFCache.)
My NSURLProtocol approach is very simple, and is not a general-purpose caching solution. It's just intended to assist a UIWebView when you're offline. But for that, I think it solves the problem well.

How to get path to add number of Images that are in the resource to be displayed in the WebView in objective-c

I am added image to my application but I want to display them into my web view. I tried but not succeeded. how can I set the path for those images in html in image tag and how to display them.
Please help me out of this.
Thank you,
Madan Mohan.
Are you just displaying the images individually or do you have an HTML file that references them?
To get a URL to the files directly:
NSString *pathForImage = [[NSBundle mainBundle] pathForResource:#"image" ofType:#"png"];
NSURL *URL = [NSURL fileURLWithPath:pathForImage];
If you're loading an HTML file that references the images (such as by including an <img src="image.png">, with no path info) then:
[webView loadHTMLString:htmlString
baseURL:[[NSBundle mainBundle] resourceURL]];
EDIT: so, supposing you had image.png in your application bundle as a resource, then you could do:
[webView loadHTMLString:#"<html><body><img src=\"image.png\"></body></html>"
baseURL:[[NSBundle mainBundle] resourceURL]];
In your HTML for the webview do
<img src="imagename">
Where imagename is the filename of the image. The iPhone doesn't have any folder structures or anything like that. That means that even if you have groups or folders set up in XCode, at runtime they are all lumped into one, giant directory.
If that doesn't work right away, look at what your are setting your base url to be. It might be that you need to set the baseURL to nil to remind the phone to look locally.
The following code sample might fix the problem for you.. Good luck!
NSData * image = [[NSMutableData alloc] initWithContentsOfFile:#"image.png"];
[self.webView loadData:image MIMEType:#"image/png" textEncodingName:nil baseURL:nil];
[image release];
[self.view addSubView:webView];

Emailing full screen of iPhone app

I am developing an iPhone app for creating images using built in graphics and user defined text.
I want to be able to have my app, with built in graphics and user defined text, which can then be sent as a single image (much like a screenshot) to the email app to be emailed.
Is there a way to do this without taking a screenshot, leaving the app, going into the Photos app, selecting the screenshot, and emailing it from there?
Ultimately I would like to be able to have a button in my app that the user could tap, and the whole screen would be captured and sent directly to the mail app.
Any pointers gratefully accepted!
To expand upon Brent's answer, the following code will grab a screenshot and save it out to the Documents directory as a PNG called screenshot.png:
UIWindow *screenWindow = [[UIApplication sharedApplication] keyWindow];
UIGraphicsBeginImageContext(screenWindow.frame.size);
[screenWindow.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *screenshot = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
NSData *screenshotPNG = UIImagePNGRepresentation(screenshot);
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSError *error = nil;
[screenshotPNG writeToFile:[documentsDirectory stringByAppendingPathComponent:#"screenshot.png"] options:NSAtomicWrite error:&error];
This is a little crude, as it will leave a blank spot near the top of the screen for the title bar, and doesn't appear to grab the content from CAEAGLLayers.
Also, I don't believe you can use the standard mailto:// URL construction, followed by openURL, to send MIME-encoded attachments. Maybe the 3.0 SDK fixes this, but I've yet to play with it. You may need to use something like sksmtpmessage to send the message directly from within your application.
There's also the private API UIGetScreenImage. It is used like so:
CGImageRef UIGetScreenImage();
#interface UIImage (ScreenImage)
+ (UIImage *)imageWithScreenContents;
#end
#implementation UIImage (ScreenImage)
+ (UIImage *)imageWithScreenContents
{
CGImageRef cgScreen = UIGetScreenImage();
if (cgScreen) {
UIImage *result = [UIImage imageWithCGImage:cgScreen];
CGImageRelease(cgScreen);
return result;
}
return nil;
}
#end
This function may be combined with UIImagePNGRepresentation to produce a PNG.
Apple is now allowing applications to use the;
CGImageRef UIGetScreenImage(void);
function. Although you must remember that it returns a retained CGImageRef and you'll have to manage your memory accordingly.
They also say that, "...a future release of iPhone OS may provide a public API equivalent of this functionality. At such time, all applications using UIGetScreenImage() will be required to adopt the public API."
skpsmtpmessage is great. If fact, it's so good, I went and cloned it and added sample project on github. The sample GUI below adds a few bells and whistles, like a progress bar and some other goodies, but it basically maintains the core skpsmtpmessage code.
http://github.com/kailoa/iphone-smtp/tree/master
I have no idea if this will work, but you can try creating a bitmap-backed graphics context, then getting your root view's Core Animation layer and calling its -renderInContext: method. That might do it, but I've never tried it.
Perhaps, though, you should consider a different approach. Is it just that you've written a bunch of custom drawing code that's visible on screen and you want to be able to draw into a file or memory buffer too? If so, perhaps you should factor that drawing code out of your view and into a separate object that your view simply uses. That would allow you to very easily draw it both ways.
In OS 3.0, you can use MFMailComposeViewController:
MFMailComposeViewController *picker = [[MFMailComposeViewController alloc] init];
picker.mailComposeDelegate = self;
[picker addAttachmentData:screenshotPNG mimeType:#"image/png" fileName:#"PNGfromMyApp"];