After login to the salesforce in my app I am making service call which returns the list of products with attributes like productName and product image url.
I am trying to download the image from product image url in this way
SFOAuthCredentials *credentials =[SFAccountManager sharedInstance].credentials;
NSString *urlString = [NSString stringWithFormat:#"%#?oauth_token=%#",imageUrl,credentials.accessToken];
NSURL *imgUrl = [[NSURL alloc] initWithString:[URLString stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]];
NSURLRequest *imgRequest=[[NSURLRequest alloc]initWithURL:imgUrl];
[NSURLConnection sendAsynchronousRequest:imgRequest queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
UIImage *image=[[UIImage alloc] initWithData:data];
NSLog(#"Image Object %#",image);
}];
I am getting the data object of size around 1820 bytes, but while converting NSData to UIImage by using UIImage classsMethod [UIImage iamgeWithData:data] or instance method [UIImage alloc] initWithData:data] I am getting null
Can anyone help me to fix this issue?.
Related
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.
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];
}
}];
I'm practicing how to parse XML data and store it into the sqlite. I have done parsing and storing successfully. But I have one problem with displaying image from an url. The URL is formed by combining two NSStrings. One for the fixed address(which I set value) and other based on the name of the photo(retrieved from Sqlite). I am able to create complete URL by retrieving name of photo from Sqlite. But strange thing happen when I use that URL to display image in UIImageView. It does not work. After some testing, I found out there is something wrong with the portion(photo name) I retrieved from Sqlite. If I combine the fixed address with literal name of the photo, it works. Can somebody explain why it happens like this. Thanks in advance.
NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"user.db"];
FMDatabase * database = [FMDatabase databaseWithPath:defaultDBPath];
[database open];
results=[database executeQuery:#"SELECT * FROM plant WHERE name=?",self.plantname];
while([results next]) {
name = [results stringForColumn:#"name"];
category = [results stringForColumn:#"category"];
instructions = [results stringForColumn:#"instructions"];
price = [results stringForColumn:#"price"];
photo=[results stringForColumn:#"photo"];
}
NSString * fixedURL = #"http://services.hanselandpetal.com/photos/";
NSString *url=[fixedURL stringByAppendingString:photo];
NSLog(url);
NSURL * imgURL = [NSURL URLWithString:url];
NSData * imageData = [NSData dataWithContentsOfURL:imgURL];
UIImage * image = [UIImage imageWithData:imageData];
self.plantImageView.image=image;
Edit
I've edited based on Rob answer. But there are still problems. I put log below. I've already tried to remove white spaces by using [photo stringByReplacingOccurrencesOfString:#" " withString:#""]. But it does not seem to affect.
2014-10-15 02:12:39.505 SqlitePractice[9256:286525] url string = 'http:/services.hanselandpetal.com/photos/mona_lavender.jpg'
2014-10-15 02:12:39.506 SqlitePractice[9256:286525] imgURL = (null)
2014-10-15 02:12:39.516 SqlitePractice[9256:286525] sendAsynchronousRequest failed: Error Domain=NSURLErrorDomain Code=-1002 "unsupported URL" UserInfo=0x7a78ba50 {NSUnderlyingError=0x7a66b5e0 "unsupported URL", NSLocalizedDescription=unsupported URL}
Edit 2
The URL seems to be problem after changing from stringByAppendingString to stringByAppendingPathComponent. But I found out that even without one slash after http: , it works if I change the photo value. And the image is displayed.
NSString * fixedURL = #"http://services.hanselandpetal.com/photos/";
photo=#"bougainvillea.jpg";
NSString *url=[fixedURL stringByAppendingPathComponent:photo];
NSLog(#"url string = '%#'", url);
NSURL * imgURL = [NSURL URLWithString:url];
NSLog(#"imgURL = %#", imgURL);
And the log is below,
2014-10-15 12:07:56.650 SqlitePractice[9690:308022] url string = 'http:/services.hanselandpetal.com/photos/bougainvillea.jpg'
2014-10-15 12:07:56.651 SqlitePractice[9690:308022] imgURL = http:/services.hanselandpetal.com/photos/bougainvillea.jpg
Edit 3
I have changed based on Rob's modified answer.
NSURL *fixedURL = [NSURL URLWithString:#"http://services.hanselandpetal.com/photos/"];
NSURL *url = [fixedURL URLByAppendingPathComponent:[photo stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
NSLog(#"image URL = '%#'", url);
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
if (error) {
NSLog(#"sendAsynchronousRequest failed: %#", error);
return;
}
UIImage *image = [UIImage imageWithData:data];
self.plantImageView.image=image;
}];
And here is the log message:
2014-10-15 13:40:38.977 SqlitePractice[10436:357359] image URL = 'http://services.hanselandpetal.com/photos/camellia.jpg%250A%2520%2520%2520%2520'
A couple of thoughts:
Unrelated to your problem at hand, instead of stringByAppendingString, it's generally better to use URLByAppendingPathComponent with a NSURL. It takes care of adding any necessary / characters for you. Not critical given your example, but it's more robust.
Also, if the string might have spaces or other characters not permitted in a URL, you might percent escape it, too.
Thus, you'd do something like:
NSURL *fixedURL = [NSURL URLWithString:#"http://services.hanselandpetal.com/photos/"];
NSURL *url = [fixedURL URLByAppendingPathComponent:[photo stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
You should NSLog the NSURL variable and make sure it's not nil (e.g. which could be caused if there were some spaces in the photo string, for example, unless you percent escape it).
In your revised question, in which you share the log, the original URL string (before the conversion to the NSURL) is being reported as:
http:/services.hanselandpetal.com/photos/mona_lavender.jpg
That should be:
http://services.hanselandpetal.com/photos/mona_lavender.jpg
If imgURL is not nil, but imageData is, you might want to retrieve the image data in a manner that retrieves the error. For example, you could:
NSError *error = nil;
NSData *imageData = [NSData dataWithContentsOfURL:imgURL options:0 error:&error];
if (!imageData) {
NSLog(#"dataWithContentsOfURL failed: %#", error);
}
Bottom line, go through this one line at a time and identify precisely where it is going wrong.
As an aside, you generally would want to avoid using dataWithContentsOfURL, but instead use an asynchronous method:
NSURL *fixedURL = [NSURL URLWithString:#"http://services.hanselandpetal.com/photos/"];
NSURL *url = [fixedURL URLByAppendingPathComponent:[photo stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
NRURLRequest *request = [NSURLRequest requestWithURL:imgURL];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
if (error) {
NSLog(#"sendAsynchronousRequest failed: %#", error);
return;
}
UIImage *image = [UIImage imageWithData:data];
self.plantImageView.image=image;
}];
I belive that UIIMAGEVIEW will not display Url as image path. I would sugest to try with UIWebView which would display web content (image or whole web page). This example is writen in objective-c.
self.myWebView = [[UIWebView alloc] initWithFrame:self.view.bounds];
self.myWebView.scalesPageToFit = YES ;
[self.view addSubview:self.myWebView];
NSURL *url = [NSURL URLWithString:#"http://services.hanselandpetal.com/photos/mona_lavender.jpg"];
NSURLRequest *request = [ NSURLRequest requestWithURL:url];
[self.myWebView loadRequest:request]
Hi in my application I have image which change every day as per the date now i want to give download option for the user like they have to download by clicking button and they can see in there device. I'm searching for long time to achieve this task but not able get the proper solution please tell me how to achieve this one.
My ImageView code.
- (void)viewDidLoad
{
[super viewDidLoad];
//this is url which gives the date has a echo
NSMutableURLRequest *request=[NSMutableURLRequest requestWithURL:[NSURL URLWithString:#"url"]];
[request setHTTPMethod:#"GET"];
[request setValue:#"application/json;charset=UTF-8" forHTTPHeaderField:#"content-type"];
NSError *err;
NSURLResponse *response;
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&err];
NSString *resSrt = [[NSString alloc]initWithData:responseData encoding:NSASCIIStringEncoding];
//This is for Response
// here I'm connecting the date to my url do display the image
NSString *imgstr=[NSString stringWithFormat:#"url",resSrt];
//assign your image view name
imageview.image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:#"%#",imgstr] ]]];
}
I have used the above to do display the image now to want to user download the image by clicking the download button to localstorage of the device please tell me how to achieve this.
Thanks.
First download the image synchronously and save it in documents folder, then show it over image view.
NSURL *url = [NSURL URLWithString: #"url"];
NSString *imagePath = [DOCUMENTS_PATH stringByAppendingPathComponent:#"some name"];
NSError *error = nil;
NSData *imageData = [NSData dataWithContentsOfURL:url options:NSDataReadingUncached error: &error];
if (!error) {
[imageData writeToFile:imagePath atomically:YES];
}
Then give this image to the image view
imageview.image = [UIImage imageWithContentsOfFile:[NSString stringWithFormat:#"%#/some name", DOCUMENTS_PATH]];
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];