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]
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.
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]];
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?.
In my iOS app I need to load an image from web, but this image is on a server in which it's necessary to give username and password. I tried to use this code:
- (void) loadImageFromWeb:(NSString *)urlImg {
NSURL* url = [NSURL URLWithString:urlImg];
NSURLRequest* request = [NSURLRequest requestWithURL:url];
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse * response,
NSData * data,
NSError * error) {
if (!error){
UIImage* image = [[UIImage alloc] initWithData:data];
[self.imageObjectScanned setImage:image];
} else {
NSLog(#"ERRORE: %#", error);
}
}];
}
But it return an error and says that:
Error Domain=NSURLErrorDomain Code=-1012 "The operation couldn’t be completed. (NSURLErrorDomain error -1012.)" UserInfo=0x14e6b420 {NSErrorFailingURLKey=http://54.204.6.246/magento8/media/catalog/product/cache/0/image/9df78eab33525d08d6e5fb8d27136e95/s/c/scheda_non_shop.jpg, NSErrorFailingURLStringKey=http://54.204.6.246/magento8/media/catalog/product/cache/0/image/9df78eab33525d08d6e5fb8d27136e95/s/c/scheda_non_shop.jpg, NSUnderlyingError=0x14e695c0 "The operation couldn’t be completed. (kCFErrorDomainCFNetwork error -1012.)"}
I guess this error it's because I'm not sending the username and the password. How I can send username and password to load this image?
Try adding the basic authentication in header of your request object.
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
NSString *authCredentials = [NSString stringWithFormat:#"%#:%#", userName, password];
NSString *authValue = [NSString stringWithFormat:#"Basic %#",[authCredentials base64EncodedStringWithWrapWidth:0]];
[urlRequest setValue:authValue forHTTPHeaderField:#"Authorization"];
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse * response,
NSData * data,
NSError * error) {
if (!error){
UIImage* image = [[UIImage alloc] initWithData:data];
[self.imageObjectScanned setImage:image];
} else {
NSLog(#"ERRORE: %#", error);
}
}];
Download the Base64.h/.m files from here and import it into your project.
Add header #import "Base64.h" in your implementation file.
This GitHub-issue suggests that your server is using an incorrect SSL certificate:
https://github.com/RestKit/RestKit/issues/1511
But if it is a credentials-issue, I suggest looking at NSURLCredential
https://developer.apple.com/library/mac/documentation/cocoa/reference/foundation/Classes/NSURLCredential_Class/Reference/Reference.html
You can present the credentials in a delegate method to NSURLConnection, or store them once and let them be used for all requests.
Alternatively, you could take a look into using RestKit.
You may try to pass the credentials within the URL as a query component, as described in the official documentation:
If authentication is required in order to download the request, the required credentials must be specified as part of the URL. If authentication fails, or credentials are missing, the connection will attempt to continue without credentials.
The parameters which comprises the query component need to be properly encoded. You may use this method to encode the parameters for a URL shown in this answer.
For example:
NSDictionary* parameters = #{#"login": name, #"password": password};
NSData* queryComponent = [parameters dataFormURLEncoded];
NSString* queryComponentString = [NSString alloc] initWithData:queryComponent
encoding:NSUTF8StringEncoding];
NSString* urlString = [NSString stringWithFormat:#"%#?%#",
urlImg, queryComponentString];
NSURL* url = [NSURL URLWithString: urlString];
A small caveat:
The described method which encodes the parameter included in the query component for a URL follows strictly the suggested algorithm specified by w3c: The application/x-www-form-urlencoded encoding algorithm which should be applied for URLs.
This encoding algorithm will escape a tilde character ~ when it occurs in either the name or value string. However, according the more general rules to compose a URL (see RFC 3986), the tilde character should not be escaped. I don't think this will ever be a problem, though.
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];