SDWebImage: Cache-Control Header is not used - sdwebimage

I'm loading my images in my UICollectionView with UIImageView+WebCache category. I'm using the option SDWebImageRefreshCached:
[cell.imageView
setImageWithURL:url
placeholderImage:nil
options:SDWebImageRefreshCached | SDWebImageRetryFailed
completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType)
{
if (error) NSLog(#"Error loading image");
}
The Cache-Control of the image is public, max-age=604772. If I activate the airplane mode, I get the "Error loading image" message.
Why is SDWebImage trying to connect the web server every time, although the max-age is set to 1 week?

SDWebImageRefreshCached ignores the cached image and will always try to get a fresh image from the url. Omit SDWebImageRefreshCached and the cached image will be used

Related

iOS print without allowing UIPrintInteractionController to appear

I am researching a potential app for a client, and I had a question I wasn't able to find the answer on. What I would like to do is print automatically, without having the UIPrintInteractionController get displayed. An important point I should make is this will not be a production app. I know that otherwise this could violate the user's privacy to just print without the user's consent, but again this will not be a public app on the App Store. One app I found that seems to be able to this is Printer Pro. The user is prompted to print a test page, and the page prints without the UIPrintInteractionController appearing - this app is on the store, so I'm assuming there's a legal way to do it. Anyone know how this is done?
As far as I know it is not possible to print in iOS7 without invoking the UIPrintInteractionController and displaying the system print dialog.
However, iOS8 now provides a provision for printing directly to a print without showing the dialog. The basic idea is that you obtain a UIPrinter object and use this in conjunction with the new - printToPrinter:completionHandler: method of the UIPrintInteractionController to print without showing the dialog.
Obtaining the UIPrinter object for your printer can be accomplished in a couple of ways.
The most straightforward is to use the new UIPrinterPickerController. But this would show a dialog and so doesn’t meet your needs.
The alternative is to create a printer via its URL using the UIPrinter method
+ printerWithURL:. I’m not entirely clear how to obtain this URL but it may be contained in the printer’s HTML admin pages. And I believe you can obtain it programmatically using the Bonjour API. More info here:
https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/NetServices/Introduction.html#//apple_ref/doc/uid/10000119i
Bonjour is a service discovery API which includes discovery of IPP printers, which the is the protocol used by AirPrint.
As for how the Printer Pro app is able to print without a dialog in iOS7, I would guess they are interacting with the printer at a very low level (e.g. raw HTTP posts, etc.).
Follow these steps to Print the Documents without prompting..
First Search for Devices Using the Below Code...
if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_7_1) {
UIPrinterPickerController *printPicker = [UIPrinterPickerController printerPickerControllerWithInitiallySelectedPrinter:nil];
[printPicker presentAnimated:YES completionHandler:
^(UIPrinterPickerController *printerPicker, BOOL userDidSelect, NSError *error) {
if (userDidSelect) {
//User selected the item in the UIPrinterPickerController and got the printer details.
[UIPrinterPickerController printerPickerControllerWithInitiallySelectedPrinter:printerPicker.selectedPrinter];
// Here you will get the printer and printer details.ie,
// printerPicker.selectedPrinter, printerPicker.selectedPrinter.displayName, printerPicker.selectedPrinter.URL etc. So you can display the printer name in your label text or button title.
NSURL *printerURL = printerPicker.selectedPrinter.URL;
NSLog(#"printerURL--->%#",printerURL.absoluteString);
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:[printerURL absoluteString] forKey:#"printURL"];
[defaults synchronize];
}
}];
}
And Print the Documents by without prompting by using the below code...
if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_7_1) {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
UIPrinter *currentPrinterObj = [UIPrinter printerWithURL:[NSURL URLWithString:[defaults stringForKey:[defaults stringForKey:#"printURL"]]]];
UIPrintInteractionController *controller = [UIPrintInteractionController sharedPrintController];
if(currentPrinterObj) {
[controller printToPrinter:currentPrinterObj completionHandler:^(UIPrintInteractionController *printController, BOOL completed, NSError *error) {
if(completed) {
} else {
NSLog(#"FAILED! due to error in domain %# with error code %u", error.domain, error.code);
}
}];
}
}

Storing NSData in app build-path with ASIHTTPRequest

I am using ASIHTTPRequest to download tiles to be used in my MKMapView. Testing the code it downloads whatever I download into a NSData variable. (My files average 50mb) Note that this is basically almost the same as this unanswered question.
I have found that I can directly download the file from my webserver into a file e.g.:
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setDownloadDestinationPath:#"/Users/ben/Desktop/my_file.txt"];
For mapview I need the files in a folder called Tiles which is inside my app's build. It ends up in this directory:
/var/mobile/Applications/887F4691-3B75-448F-9384-31EBF4E3B63E/MyApp.app/Tiles
Which I found out when I called:
NSLog(#"%#",[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"Tiles"]);
So what I am trying to do now is download these files (take note the plural) and put them in in the Tiles folder. To start with, I can either ZIP these images together to extract later on my device and place in the Tiles folder, or I can just go ahead and download all the images separately (which seems easier since I already know all the file-names)
I tried this piece of code and it gives me an error. It is in my mapview's viewDidLoad just before I load the tiles. Take note it is only there for testing the download-code and will later be place somewhere else to be triggered by a button.
Here is the code:
NSURL *url = [NSURL URLWithString:#"http://...my-website.../25.png"];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setDownloadDestinationPath:[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"Tiles"]]; // THE PROBLEMATIC LINE
[request startSynchronous];
NSError *error = [request error];
if(!error)
{
NSLog(#"Loaded Map");
}
else
{
NSLog(#"Error occured while loading map");
NSLog(#"%#",error);
}
And this appears in the console:
2011-06-26 21:12:09.651 MyApp[5309:707] Error occured while loading map
2011-06-26 21:12:09.669 MyApp[5309:707] Error Domain=ASIHTTPRequestErrorDomain Code=8 "Failed to delete file at path '/var/mobile/Applications/887F4691-3B75-448F-9384-31EBF4E3B63E/MyApp.app/Tiles'" UserInfo=0x184b20 {NSUnderlyingError=0x1d4ac0 "The operation couldn’t be completed. (Cocoa error 513.)", NSLocalizedDescription=Failed to delete file at path '/var/mobile/Applications/887F4691-3B75-448F-9384-31EBF4E3B63E/MyApp.app/Tiles'}
So how can I store the downloaded file in a directory on the iPhone where I can find and use it later?
Thanks for the trouble.
You can't write directly into your application bundle. You should use a directory inside your app's sandbox, such as /Documents or /Library/Caches. See Getting paths to standard application directories for how to get these paths.

How to change the character encoding in UIWebView?

Summary of the problem: When browsing non-English sites that does not explicitly specify the correct character encoding with UIWebView on the iOS, the page cannot be displayed correctly.
Detailed explanation: As the loadRequest: method in UIWebView will use the encoding specified in the charset header sent from the web server or the charset written in the HTML meta tag, and default to iso-8859-1 (well, I am not too sure about this) when charset is not specified, which cause non-English sites cannot display properly.
I have tried to Google for a way to change the charset that the UIWebView use, but the only way is to use the loadData:MIMEType:textEncodingName:baseURL: method to specify the encoding name.
However, it is not a good idea to use loadData:MIMEType:textEncodingName:baseURL: + NSURLConnection instead of loadRequest:, because UIWebView won't call the delegate method webView:shouldStartLoadWithRequest:navigationType: for frames, and even if we found a way to get notified when UIWebView load a frame, we cannot call loadData:MIMEType:textEncodingName:baseURL: to load the frame content, because it will load the frame as the outer page if we do that.
Besides, I have tried to use a javascript hack, but seems that property is read-only and cannot be changed.
[webView stringByEvaluatingJavaScriptFromString:#"document.characterSet='utf-8';"];
Another workaround is inserting a meta tag to the HTML, and ask UIWebView to load the modified code, but the frame problem mentioned above also apply here.
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
Question: Is there any better solution that can change the character encoding in a loaded webpage in UIWebView, and handle frames properly?
You can do this by manually loading the HTML, modifying it, and then loading the modified content into the UIWebView.
manually load the HTML from the page that doesn't include the meta tag, into a string (e.g. use NSURLConnection)
using string manipulation, insert your appropriate encoding meta tag into the manually loaded HTML
set the HTML in your web view to the modified string using loadHTMLString:
Now, this will work fine for a web page that contains no links. If it contains links, then you will find that after they click on a link, the new page will not have your modification in place. Therefore, you will need to manually intercept all of the clicks. Here's how you can do that:
Implement a UIWebView delegate
Implement the method webView:shouldStartLoadWithRequest:navigationType:
In your delegate method, load the URL manually and modify the content before setting it into the UIWebView, as above.
This is what I do,
first find out if it is text, if it is, I get the data, set the encoding and load it using UIWebView>loadData:MIMEType:textEncodingName:baseURL.
Here is the code:
Get the MIMEType sending a synchronous HEAD request.
We want to use a HEAD HTTP request which generally is fast enough.
And we want to make the request synchronously for two reasons, we need the request's result to continue, and we want to avoid concurrent request problems like this.
NSMutableURLRequest *headRequest = [NSMutableURLRequest requestWithURL:url];
[headRequest setHTTPMethod:#"HEAD"];
NSHTTPURLResponse *headResponse;
NSError *error = nil;
[NSURLConnection sendSynchronousRequest:headRequest
returningResponse:&headResponse
error:&error];
if (error != nil) {
NSLog(#"loadURLWithString %#",[error localizedDescription]);
}
NSString *mimeType = [headResponse MIMEType];
 
 
Then if it is text, load it with UIWebView>loadData:MIMEType:textEncodingName:baseURL
To maintain the application responsive, it is recommended to put the following code into a block and run it inside a GCD queue.
if([mimeType rangeOfString:#"text"
options:NSCaseInsensitiveSearch].location == 0) {
[wview loadData:[NSData dataWithContentsOfURL: url] MIMEType:mimeType
textEncodingName:encoding baseURL:nil];

iPhone RSS Reader, get image from rss feed

i've a problem.
I've an app that download rss feed from a website. It works all fine, but i want to set image in table view where the articles appear. How can i get image from RSS Feed? I need the code.
For title, description i've done it perfectly, but i'm not able to recover image.
P.S. : sorry for my english, i'm italian :)
Ok, so I presume you have the URL of the image. You can do this:
//Normal text setting code
//Normal text setting code
NSString *imageURLString = [rssFeed objectForKey:#img"];
NSURL *imageURL = [NSURL URLWithString:imageURLString];
NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
cell.imageView.image = [UIImage imageWithData:imageData];
That is the quick and filthy method. It's running in your UI thread etc, so it's going to be a terrible user experience. You can fiddle with performance on your own terms, but I'd suggest one of the following:
Load all your data asynchronously and fill the data as it becomes available
Load all of your data in a secondary thread, but show a loading spinner
For both of the above, you would put your images into an NSArray and then call them by doing cell.imageView.image = [myImageArray objectAtIndex:indexPath.row];
The best solution however (and most complicated) though is called 'lazy loading'.
If you want to do lazy loading (the way facebook and twitter do it) you should check this out: LazyTableImages.
Happy coding, Zane
There is a plugin for it.
WP RSS Images Plugin
http://wordpress.org/extend/plugins/wp-rss-images/
After downloading it and succesfully installing it you need to parse the enclosure tag.
It will be in enclosure element with the attribute of "url". If you need I can post the code also.

Using TwitPic API from ObjectiveC/iPhone

There's a similar question on here about this which I've read and I've tried to follow the advice given there... and I think I'm 95% complete but the remaining 5%... well you know ;-)
So I'm trying to call the twitPic API to upload an image and I've got the image contained in a UIImageView which I'm displaying on the screen (I can see it so it's definitely there). My code to form the API call looks like this:
NSURL *url = [NSURL URLWithString:#"http://twitpic.com/api/upload"];
NSString *username = #"myUsername";
NSString *password = #"myPassword";
NSData *twitpicImage = UIImagePNGRepresentation(imageView.image);
// Now, set up the post data:
ASIFormDataRequest *request = [[[ASIFormDataRequest alloc] initWithURL:url] autorelease];
[request setPostValue:twitpicImage forKey:#"media"];
[request setPostValue:username forKey:#"username"];
[request setPostValue:password forKey:#"password"];
// Initiate the WebService request
[request start];
I get an error back from it stating 'image not found'.
Is it obvious what I'm doing wrong? Any hints at all? I'm only a week deep in ObjectiveC so it's quite likely it's a real newbie error.
On the same track - it's not clear to me how I can capture a success or failure properly in code here - I'm currently dumping the 'request responseString' to an alert which isn't the best thing - how can I check the result properly?
I've also seen the use of 'NSLog' - which I suspect is a debugging/console logging tool - but I can't see the output from this anywhere in XCode - it doesn't SEEM to be shown in the debugger - any clues at all?!
Sorry if the above is really dumb - I can take a little ridicule - but I'm kind of isolated with my iPhone adventures - no one to bounce anything off etc - so I'm venting it all off here ;-)
Cheers,
Jamie.
You need to use the setData method to copy the image data into the post, like this:
[request setData:twitPicImage forKey:#"media"];
You're making a synchronous call, which is going to stall your app while you upload all that image data - you might want to switch to using an NSOperationQueue, or the ASINetworkQueue subclass that allows you to show a progress bar.
You should be able to see NSLog output in the debugger window of XCode. Make sure you've switched to this (control top left with a spray can on). You can also launch the console.