Instagram photo to UIImageView - ios

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.

Related

Objective-C: Get Image from JSON

I am trying to learn web service on iOS.
I'm starting of from getting an image from a JSON api link.
I've used the code below but the image is not displaying and I'm getting warning that says
Incompatible pointer types assigning to 'UIImage * _Nullable' from 'NSSting * _Nullable'
My code
NSURL *urlAdPop = [NSURL URLWithString:#"JSON LINK HERE"];
NSURLRequest *request = [NSURLRequest requestWithURL:urlAdPop];
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response,
NSData *data, NSError *connectionError)
{
if (data.length > 0 && connectionError == nil)
{
NSDictionary *AdPopUp = [NSJSONSerialization JSONObjectWithData:data
options:0
error:NULL];
popUpBanner.image = [[AdPopUp objectForKey:#"ad_image"] stringValue];
popUpAdURL = [AdPopUp objectForKey:#"ad_link"];
}
}];
popUpBanner.image = [UIImage imageWithData:[NSData dataWithContentsOfURL:popUpAdURL]];
popUpBanner.hidden = NO;
popUpBanner.layer.cornerRadius = 9;
popUpBanner.clipsToBounds = YES;
popUpBanner.userInteractionEnabled = YES;
[self.view addSubview:popUpBanner];
You need to write your code inside block after you get response from webservice.
NSURL *urlAdPop = [NSURL URLWithString:#"JSON LINK HERE"];
NSURLRequest *request = [NSURLRequest requestWithURL:urlAdPop];
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response,
NSData *data, NSError *connectionError)
{
if (data.length > 0 && connectionError == nil)
{
NSDictionary *AdPopUp = [NSJSONSerialization JSONObjectWithData:data
options:0
error:NULL];
popUpBanner.image = [[AdPopUp objectForKey:#"ad_image"] stringValue];
popUpAdURL = [AdPopUp objectForKey:#"ad_link"];
UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:popUpAdURL]];
dispatch_async(dispatch_get_main_queue(), ^{ // get main thread to update image
popUpBanner.image= image
popUpBanner.hidden = NO;
popUpBanner.layer.cornerRadius = 9;
popUpBanner.clipsToBounds = YES;
popUpBanner.userInteractionEnabled = YES;
[self.view addSubview:popUpBanner];
});
}
}];
popUpBanner.layer.cornerRadius = 9;
popUpBanner.clipsToBounds = YES;
popUpBanner.userInteractionEnabled = YES;
popUpBanner.hidden = YES;
[self.view addSubview:popUpBanner];
NSString* strURL=#"JSON LINK HERE";
NSString* webStringURL = [strURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *urlAdPop = [NSURL URLWithString:webStringURL];
NSURLRequest *request = [NSURLRequest requestWithURL:urlAdPop];
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response,
NSData *data, NSError *connectionError)
{
if (data.length > 0 && connectionError == nil)
{
NSDictionary *AdPopUp = [NSJSONSerialization JSONObjectWithData:data
options:0
error:NULL];
popUpAdURL = [AdPopUp objectForKey:#"ad_link"];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSData *imgData = [NSData dataWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:#"%#",[AdPopUp objectForKey:#"ad_image"]]]];
if (imgData)
{
UIImage *image = [UIImage imageWithData:imgData];
if (image)
{
dispatch_async(dispatch_get_main_queue(), ^{
popUpBanner.image = image;
popUpBanner.hidden = NO;
});
}
else
{
dispatch_async(dispatch_get_main_queue(), ^{
});
}
}
else
{
dispatch_async(dispatch_get_main_queue(), ^{
});
}
});
}
}];
Perfect way to display image!
Hope It will help you :)
If you need to deal with images comes from web response then you can use SDWebImage library from GitHub.
In its read me page they have also provided the way how you can achieve it.
#import <SDWebImage/UIImageView+WebCache.h>
[self.YourImageView sd_setImageWithURL:[NSURL URLWithString:#"http://yourimagePath/.../"]
placeholderImage:[UIImage imageNamed:#"placeholder.png"]];
Thats it !
Firstly,check if that url available in browser. If yes,check if your app accept HTTP(not HTTPS). You can set app accept like this:
You are adding popUpBanner in view after getting image from server. so you have to initialize it before in viewdidload and need to set it's frame.
Then set image to popUpBanner from completion handler of web service on main thread. And make sure that you have to set image not image name string!
Below line is wrong, it is trying to set string to imageview which is not possible.
popUpBanner.image = [[AdPopUp objectForKey:#"ad_image"] stringValue];
get image from image url provided by service side and use image name that you get in response.
And make sure that you are getting image object using breakpoint.
Hope this will help :)
###require suppurate api to load image.
want to attach the link and image name together as to reach. thus two strings are needed to store each the api and the image name.###
s=[[mutarray objectAtIndex:index]valueForKey:#"image"];
NSString *f=[NSString stringWithFormat:#"http://iroidtech.com/wecare/uploads/news_events/%#",s];
NSURL *g=[[NSURL alloc]initWithString:f];
data=[NSMutableData dataWithContentsOfURL:g];
self.imgvw.image=[UIImage imageWithData:data];
_descrilbl.text=[[mutarray objectAtIndex:index]valueForKey:#"image"];

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.

iOS : How to upload an image from a URL to Parse?

I'm able to upload an image (in form of PFFile) on parse with their methods available.
NSData *data = ... ;
PFFile *file = [PFFile fileWithData:data];
[file saveInBackground];
Is there a better way to directly upload an image from a url to parse?
Update: The bad way I found is,
To get an image from NSURL to NSData - don't know about the proper way, but this is working. Something like this,
PFFile *file = [PFFile fileWithData:[NSData dataWithContentsOfURL:urlObj]];
[file saveInBackground];
I think the question is how best to get the data to pass to parse. You're right that dataWithContentsOfUrl is a bad way because it blocks the main thread during the fetch.
Here's a block-based approach to get the data asynchronously:
NSURL *url = [NSURL URLWithString:#"http:// ..."];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
if (!error) {
PFFile *file = [PFFile fileWithData:data];
[file saveInBackground];
}
}];

UIKeyboardTaskQueue threading issue

I'm fairly new to iOS development and I've been stuck on this bug for a while. I'm making a simple app the uses a web service. Right now I currently have two view controllers. A login view controller (with its NIB file) and a main view controller (with its NIB file). When I created the app I chose an empty application so I don't have a storyboard. Instead I'm using UINavigationController. When I run my code I get the following error after entering my username and password and pressing submit in the login view:
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[UIKeyboardTaskQueue waitUntilAllTasksAreFinished] may only be called from the main thread.'
This is the code I have for my submit button:
-(IBAction)logIn:(id)sender{
UIApplication *application = [UIApplication sharedApplication];
application.networkActivityIndicatorVisible = YES;
[_loginNetworkingContorller checkCredentialsWithUsername:self.username.text withPassword:self.password.text completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if(!error){
NSHTTPURLResponse *httpResp = (NSHTTPURLResponse*) response;
if (httpResp.statusCode == 200) {
NSLog(#"SUCESS");
NSDictionary *credentials = #{self.username.text: self.password.text};
[KeychainUserPass save:#"MY APP" data:credentials];
UIViewController *mainView = [[RDMainViewController alloc] initWithNibName:#"RDMainViewController" bundle:nil];
[self.navigationController pushViewController:mainView animated:YES];
}
else{
NSLog(#"ERROR");
}
}
else{
NSLog(#"ERROR");
}
}];
}
And here is the code for the following function
[_loginNetworkingContorller checkCredentialsWithUsername:self.username.text withPassword:self.password.text completionHandler:^(NSData *data, NSURLResponse *response, NSError *error)
-(void)checkCredentialsWithUsername:(NSString *)username withPassword:(NSString *)password completionHandler:(void (^)(NSData *data,NSURLResponse *response, NSError *error))myCompletion
{
NSString *requestString = #"SOME WEBSITE";
NSURL *url = [NSURL URLWithString:requestString];
NSURLRequest *req = [NSURLRequest requestWithURL:url];
NSData *userPasswordData = [[NSString stringWithFormat:#"%#:%#", username, password] dataUsingEncoding:NSUTF8StringEncoding];
NSString *base64EncodedCredential = [userPasswordData base64EncodedStringWithOptions:0];
NSString *authString = [NSString stringWithFormat:#"Basic %#", base64EncodedCredential];
NSURLSessionConfiguration *sessionConfig=[NSURLSessionConfiguration defaultSessionConfiguration];
sessionConfig.HTTPAdditionalHeaders=#{#"Authorization":authString};
self.session=[NSURLSession sessionWithConfiguration:sessionConfig];
NSURLSessionDataTask *dataTask = [self.session dataTaskWithRequest:req completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
myCompletion(data, response, error);
}];
[dataTask resume];
}
I'm a stuck right now and am not really sure what the issue is especially since I don't do anything with the keyboard. I have a feeling there is an issue with my blocks but I'm not exactly sure what the issue is. Any help would be greatly appreciated.
Hey I had this same issue after I received my response from my web call. I was able to solve it be doing the following:
//do something with response
dispatch_async(dispatch_get_main_queue()) { () -> Void in
// continue with program by calling next step on main thread
}
I think if you push to the next view controller iOS attempts to do it on not the main thread, causing the error, but I'm not 100% is that is accurate

Asynchronous image download succeeded but image does not appear

I am writing an app that displays images from url in a view. The idea is that when the view appears, image is dowloaded and it actualizes a UIImamgeView in the view.
I am using a Asyncrounse method in this way:
-(void)downloadASyncro:(NSString*)urlLink{
NSURL * imageURL = [NSURL URLWithString:urlLink];
[self downloadImageWithURL:imageURL completionBlock:^(BOOL succeeded, UIImage *image) {
if (succeeded) {
NSLog(#"scaricaImmagineASyncro Succeded= %#",image);
picView.image = image;
}
else {
//default image
picView.image = [UIImage imageNamed:#"icon_old.jpg"];
}
}];
}
the downloadImageWithURL method is:
- (void)downloadImageWithURL:(NSURL *)url completionBlock:(void (^)(BOOL succeeded, UIImage *image))completionBlock
{
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
if ( !error )
{
UIImage *image = [[UIImage alloc] initWithData:data];
completionBlock(YES,image);
} else{
completionBlock(NO,nil);
}
}];
}
When I call the method:
[self downloadASyncro:link];
and the operation sees end with success (NSLOG), picView.image = image; should actualize the view showing the image downloaded , should not it? But immage does not appear...
Any idea? Thanks in advance.

Resources