iOS - NSURLConnection sendAsynchronousRequest method not getting a response in offline mode - ios

Hey I'm new to iPhone and I have been trying to display image icons on table view cell in offline mode.
Using NSUserDefault i am storing array objects locally in Online mode. I am using a method that creates a NSURLRequest, and sends that request with the NSURLConnection method sendAsynchronousRequest:queue:completionHandler:. Sometimes I am not getting any response using this method, so completionHandler is not calling. So i am not getting any image icon on table. Does anyone know how to fix this?
here is my code :
QuickLinksTab *quickLinksmenu = [[QuickLinksTab alloc] init];
quickLinksmenu = [arrayLinks objectAtIndex:indexPath.row];
cell.lblName.text = quickLinksmenu.title;
NSString *strQuickLink = [NSString stringWithFormat:#"http://%#",quickLinksmenu.iconImage];
NSURL* url = [NSURL URLWithString:strQuickLink];
NSURLRequest* request = [NSURLRequest requestWithURL:url];
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse * response,
NSData * data,
NSError * error) {
if (error)
{
NSLog(#"ERROR CONNECTING DATA FROM SERVER: %#", error.localizedDescription);
}
else{
UIImage* image = [[UIImage alloc] initWithData:data];
// do whatever you want with image
if (image) {
cell.imageIcon.image = image;
}
else{
cell.imageIcon.image = [UIImage imageNamed:#"DefaultPlace.png"];
}
}
}];
QuickLinksTab is my entity class, i am storing quickLinksmenu.title and quickLinksmenu.iconImage locally in my app. I am getting Error message - `
ERROR CONNECTING DATA FROM SERVER:
The Internet connection appears to be offline.
Thanks in Advance.

Related

Instagram photo to UIImageView

can i show an instagram photo on my UIImageView?
I was looking for media id and other options, but i can't find the format and the way to show this image for example:
https://www.instagram.com/p/9W-K0wtq3v/
You can get direct link to image using http://api.instagram.com/oembed?url= . After that, downloading the image from that URL & displaying it in UIImageView is fairly simple. I have edited my answer to this one as it works without integrating Instagram API or parsing the web page for URL to file.
Add the following to methods to your View Controller. I have added explanation in comments.
- (void)getDirectURLToLink:(NSString *)urlStr completionBlock:(void (^)(BOOL succeeded, NSString *imageLink))completionBlock
{
NSURL *url = [NSURL URLWithString:urlStr];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
if ( !error )
{
//Convert data to dictionary as it is JSON. You can view json response for your url at http://paste.ubuntu.com/14437288/
NSError *error1;
NSMutableDictionary * innerJson = [NSJSONSerialization
JSONObjectWithData:data options:kNilOptions error:&error1
];
//Send the direct url to block
completionBlock(YES,[innerJson objectForKey:#"thumbnail_url"]);
} else{
//request failed
completionBlock(NO,nil);
}
}];
}
- (void)downloadImageWithURL:(NSString *)urlStr completionBlock:(void (^)(BOOL succeeded, UIImage *image))completionBlock
{
NSURL *url = [NSURL URLWithString:urlStr];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
if ( !error )
{
//cnvert data to uiimage
UIImage *image = [[UIImage alloc] initWithData:data];
completionBlock(YES,image);
} else{
//download failed
completionBlock(NO,nil);
}
}];
}
(But since sendAsynchronusRequest is deprecated in iOS 9.0, you should use [NSURLSession dataTaskWithURL])
Now you have set up the web request part of the file. To utilize these services, Add following method to your Viewcontroller:
-(void) getImageForPostURL: (NSString *)postURL
{
NSString *baseURL = #"http://api.instagram.com/oembed?url=";
NSString *directLinkRequestURL = [NSString stringWithFormat:#"%#%#",baseURL,postURL];
//Request Direct URL to file from your post url
[self getDirectURLToLink:directLinkRequestURL completionBlock:^(BOOL succeeded, NSString *imgDirectURL) {
if (succeeded) {
//Direct link retrieved
//Get image
[self downloadImageWithURL:imgDirectURL completionBlock:^(BOOL succeeded, UIImage *image) {
if (succeeded) {
// change the image where you want, it has been downloaded
_imgView.image = image;
}
}];
}
else
{
//Error
//Link could not be retrieved
}
}];
}
All this work is not for vain. Now, You are all set to go. All you need is a URL to instagram post and you will be able to download your image just by calling this one line:
[self getImageForPostURL:#"https://www.instagram.com/p/9W-K0wtq3v/"]; //Give your post url as parameter here
I think: it will have two ways to achieve your goal
*First: parse link web Instagram. If you view source your link give: you will find direct link to image:
https://igcdn-photos-b-a.akamaihd.net/hphotos-ak-xfp1/t51.2885-15/e35/10729433_781480525295113_239273684_n.jpg
So you can parse web and find:
<meta property="og:image" content="
for direct link.
Second: You can reference here:
https://instagram.com/developer/endpoints/media/
You enroll developer instagram and learn how to use Instagram API end points.

Using blocks to download image, freezing UI

In my app I am downloading image using blocks but it is freezing my UI. I have one network class which contains method to download image,
-(void)downloadImageWithCompletionHandler:^(NSData *aData, NSError *error)aBlock;
I am calling above method in my view controller to download image. So once the image is downloaded I am using NSData to show in image view. The network class method uses NSURLConnection methods to download the image.
[[NSURLConnection alloc] initWithRequest:theURLRequest delegate:self];
Once the data download is complete I am calling completion handler block of the view controller.
But I am not sure why my UI is freezing? Can anyone help me find where I am doing wrong?
Thanks in advance!
- (void) setThumbnailUrlString:(NSString *)urlString
{
NSString *url= [NSString stringWithFormat:#"%#",urlString];
//Set up Request:
NSMutableURLRequest *request = [[NSMutableURLRequest alloc]init];
[request setURL:[NSURL URLWithString:url]];
NSOperationQueue *queue=[[NSOperationQueue alloc] init];
if ( queue == nil ){
queue = [[NSOperationQueue alloc] init];
}
[NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse * resp, NSData *data, NSError *error)
{
dispatch_async(dispatch_get_main_queue(),^
{
if ( error == nil && data )
{
UIImage *urlImage = [[UIImage alloc] initWithData:data];
_headImageView.image=urlImage;
_backgroundImageView.image=urlImage;
}
});
}];
}
You need to download the image in background thread to avoid freezing the UI thread.There is a simple demo to achieve this.
- (void)downloadImageWithCompletionHandler:(void(^)(NSData *aData, NSError *error))aBlock {
NSURLRequest *theURLRequest = nil; // assign your request here.
NSOperationQueue *mainQueue = [NSOperationQueue mainQueue];
[NSURLConnection sendAsynchronousRequest:theURLRequest queue:mainQueue completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
// UIThread.
aBlock(data,connectionError);
}];
}
how to call this method.
[self downloadImageWithCompletionHandler:^(NSData *aData, NSError *error) {
// get UIImage.
UIImage *image = [UIImage imageWithData:aData];
}];
I figured out the problem. Problem was not in the block or using NSUrlConnection method, it is working properly. Problem was, I was saving data in file once I download it. This operation was happening on main thread which was blocking the UI.

How know my UIImage is loaded on IOS ?

this is my code to load my images.
NSString *urltest = test[#"images"][#"items"][i][#"url"];
url = [NSURL URLWithString:urltest];
data = [NSData dataWithContentsOfURL:url];
img = [[UIImage alloc] initWithData:data];
[self.imgView setImage:img];
I would like to know when my is loaded. How can i do that?
In XCode Debugger section (located at the bottom left of the XCode), you can check image object value by inserting breakpoint there. You can also preview its value by clicking on preview button (human eye look like button).
You can achive it by,
First write this code
[self performSelectorOnMainThread:#selector(LoadImage:) withObject:#"MY URL STRING" waitUntilDone:NO];
And then
-(void)LoadImage:(NSString *) urlString
{
/// do something when image is loading
NSURL *imgURL=[NSURL URLWithString:urlString];
NSData *imgData=[NSData dataWithContentsOfURL:imgURL];
[self performSelectorInBackground:#selector(setImage:) withObject:imgData];
}
-(void)setImage:(NSData *) imgData;
{
/// do something when image loading is over
myImageView.image=[UIImage imageWithData:imgData];
}
And if you want to know your image is successfully downloaded or not then use following code
[NSURLConnection sendAsynchronousRequest:[NSURLRequest requestWithURL:[NSURL URLWithString::#"MY URL STRING"]] queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse* response, NSData* data, NSError* error){
if(error)
{
// Error Downloading image data
}
else
{
[myImageView setImage:[UIImage imageWithData:data]];
}
}];

NSData loading UIImage

How to tell if the NSData returns nil if theres no internet connection or if the image is no longer available ??
this is the code:
NSString *str = #"http://p.twimg.com/A76-I-PCYAA75YH.jpg";//URL is broken
NSData *imgData = [NSData dataWithContentsOfURL:[NSURL URLWithString:url]];
image = [UIImage imageWithData:imgData];
The nsdata is nil in two cases:
If thers no internet connection.
Or if the image in the url is no longer available.
Try this code.
NSURL* url = [NSURL URLWithString:#"http://imageAddress.com"];
NSURLRequest* request = [NSURLRequest requestWithURL:url];
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse * response,
NSData * data,
NSError * error) {
if (!error){
NSImage* image = [[NSImage alloc] initWithData:data];
// do whatever you want with image
}
}];
You should first test for an available network data connection separately, see Apple's Reachability sample code.
Then, if you have a network connection, you can go ahead and try and load the file. If it then fails, you know it's not because there was no network data connection.
Before downloading check for internet connection and then download. You can check availaibility bu putting condition of
if(imgdata == nil)
// image is not available in server
else
// convert data into image and use
image = [UIImage imageWithData:imgData];

Display UIAlertView if my JSON does not load?

Here is my question. How do I display an error if my app is unable to load my remote JSON file? I turned my wifi off on my computer and ran the app in the Simulator. It NSLogs the message that should be displayed if there is connection. How can I fix this? Thanks.
Here is my code:
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *jsonStr = #"http://xxx.com/server.php?json=1";
NSURL *jsonURL = [NSURL URLWithString:jsonStr];
// NSData *jsonData = [NSData dataWithContentsOfURL:jsonURL];
// NSError *jsonError = nil;
NSURLRequest *jsonLoaded = [NSURLRequest requestWithURL:jsonURL];
if(!jsonLoaded) {
UIAlertView *alertView = [[UIAlertView alloc] init];
alertView.title = #"Error!";
alertView.message = #"A server with the specified hostname could not be found.\n\nPlease check your internet connection.";
[alertView addButtonWithTitle:#"Ok"];
[alertView show];
[alertView release];
NSLog(#"No connection, JSON not loaded...");
}
else {
NSLog(#"JSON loaded and ready to process...");
}
}
Your code just creates the request. It doesn't actually fetch the data. You need to use NSURLConnection to fetch the data.
There are multiple ways to fetch the data. This example is for iOS 5.0 or higher:
NSOperationQueue *q = [[[NSOperationQueue alloc] init] autorelease];
NSURLRequest *jsonRequest = [NSURLRequest requestWithURL:jsonURL];
[NSURLConnection sendAsynchronousRequest:jsonRequest
queue:q
completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
// data was received
if (data)
{
NSLog(#"JSON loaded and ready to process...");
// ... process the data
}
// No data received
else
{
NSLog(#"No connection, JSON not loaded...");
// ... display your alert view
}
}];
You have not actually requested anything yet. Read here on how to make requests.
Basically, what you want to do is to implement NSURLConnectionDelegate protocol and override connection:didFailWithError: function to listen for failure event.

Resources