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]];
}
}];
Related
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"];
This is probably a simple fix, but I'm new to this.
NSString *barImageURLString = barDic[#"image_url"];
NSURL *barImageURL = [NSURL URLWithString:barImageURLString];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
NSData *imageData = [NSData dataWithContentsOfURL:barImageURL];
dispatch_async(dispatch_get_main_queue(), ^{
// Update the UI
cell.barImageView.image = [UIImage imageWithData:imageData];
});
});
NSString *ratingImageURLString = barDic[#"rating_img_url"];
NSURL *ratingImageURL = [NSURL URLWithString:ratingImageURLString];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
NSData *imageData = [NSData dataWithContentsOfURL:ratingImageURL];
dispatch_async(dispatch_get_main_queue(), ^{
// Update the UI
cell.ratingImage.image = [UIImage imageWithData:imageData];
});
});
Not sure how I would go about that with the dispatch_async in there.
Doing a POST not just a refactor of your code, which has the GET operation buried in dataWithContentsOfURL:. Here's more general POST code...
NSData *data = // init this to the data that you want to post
NSString *someURLString = #"http://www.myservice.com/mypost.php";
NSURL = *url = [NSURL URLWithString:someURLString];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = #"POST";
// depends on the data, but something like this to set a header...
[request setValue:#"application/xml; charset=utf-8" forHTTPHeaderField:#"Content-Type"];
request.HTTPBody = data;
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
if (!error) {
}
}];
This can be refactored into a GET by replacing the mutable url request with an immutable request and optionally adding query parameters to the url string.
Your code works under ideal conditions, but you want to do some error checking to prevent runtime exceptions.
NSString *barImageURLString = barDic[#"image_url"];
NSURL *barImageURL = [NSURL URLWithString:barImageURLString];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
NSData *imageData = [NSData dataWithContentsOfURL:barImageURL];
// check for valid data
if ( imageData ) {
// create the UIImage first and make sure it is a valid image
UIImage *image = [UIImage imageWithData:imageData];
if ( image ) {
dispatch_async(dispatch_get_main_queue(), ^{
// It is possible that your tableview cell is no longer on screen, check
YourTableViewCell *cellBeingUpdated = (id)[tableView cellForRowAtIndexPath:indexPath];
if ( cellBeingUpdated ) {
// Update the UI
cellBeingUpdated.barImageView.image = image;
}
});
}
}
});
Same applies to your other image. You want to have some sort of default image in case this fails. What I do is have a default image that I assign to the tableview cell before making the image request. This prevents blank imageviews while waiting for the actual image loading.
Since the logic of fetching the image and doing something with it is mostly the same, and you don't want to repeat the code everytime a new kind of image needs to be loaded, you can create a function or method to do the repetitive work. The input to the function will be a URL to an image, and the output will be the image itself. Since the actual fetch will be asynchronous, the function can take in as input a block of code with instructions on what to do once the image is available. The block can also be notified of failures if the image could not be fetched for some reason.
- (void)fetchImageFromURL:(NSURL *)imageURL completionHandler:(void(^)(UIImage *image, NSError *error))completionHandler {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
NSError *error = ...; // do error handling if image load fails
dispatch_async(dispatch_get_main_queue(), completionHandler(imageData, error);
});
}
This can be invoked as:
NSString *barImageURL = [NSURL URLWithString:barDic[#"image_url"]];
[self fetchImageFromURL:barImageURL completionHandler:^(UIImage *image, NSError *error) {
if (error != nil) {
// handle error
}
else {
cell.barImageView.image = image;
}
}];
Although it only seems to be cutting down a few lines of repetitive code, this design allows your code to be more flexible and scalable. This hides the implementation detail of how the image is actually fetched. Maybe you want to replace it with an asynchronous NSURLConnection, or with NSURLSession. This design allows for that kind of modifications without impacting the API. Error handling can be kept in a single place. Network requests can fail for a variety of reasons with the topmost reason being bad or no connectivity. You can add retry logic for such failures within the -fetchImageFromURL: method again without impacting the method API and callers. Maybe there is some caching you've built so there's no need to go out to the network at all. Again, this design would allow for such a growth.
In the most general terms, you want to separate the "what" from the "how". The what here is the image that some part of your code needs but it shouldn't concern itself with how that image is retrieved.
I have some code that gets an image from a web page and displays it in an ImageView. But the image loads very slowly for some reason I don't really understand! Through my logging I can see that all the data for the image (base64 string) arrives pretty instantly, yet it takes about 12 - 15 seconds for the image to appear in the ImageView.
I find this very strange because I used an NSStream to get the data for the image in a different method and the image loaded as soon as all the data arrived. But with this URLSession method its taking longer for the image to load. This doesn't really make sense! This method shouldn't affect how the ImageView loads that data.
Has anybody any ideas why this might be happening?
heres the code:
- (void)postMethod:(NSDictionary *)numDict
{
NSURL *url = [NSURL URLWithString:#"http://theWebAddress.com/aPage.php"]; // add url to page
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:config];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
request.HTTPMethod = #"POST";
NSError *error = nil;
NSData *data = [NSJSONSerialization dataWithJSONObject:numDict options:kNilOptions error:&error];
NSLog(#"%#", numDict);
if (!error)
{
NSURLSessionUploadTask *uploadTask = [session uploadTaskWithRequest:request fromData:data completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSDictionary *diction = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
for (id key in diction)
{
if ([key isEqualToString:#"text"])
{
NSLog(#"data is text");
self.messageLabel.text = diction[#"text"];
break;
}
else if ([key isEqualToString:#"image"])
{
NSLog(#"data is an image");
// gets the base64 string pretty instantly but takes 12 - 15 seconds to pop up in the imageView
NSData *ImgData = [[NSData alloc] init];
ImgData = [[NSData alloc] initWithBase64EncodedString:diction[#"image"] options:1];
self.ImageView.image = [UIImage imageWithData:ImgData];
break;
}
}
}];
[uploadTask resume];
}
}
many thanks!
Your completion handler might be operating on a background thread. UI updates should always work on the main thread. Put a break point at
self.ImageView.image = [UIImage imageWithData:ImgData];
and see if it is on the main thread. If not, dispatch it to the main thread before you set the ImageView.image:
dispatch_async(dispatch_get_main_queue(), ^{
self.ImageView.image = [UIImage imageWithData:ImgData];
});
You can try to use SDWebImage https://github.com/rs/SDWebImage and all you need is to set the image in imageView like this:
[cell.imageView setImageWithURL:[NSURL URLWithString:#"http://www.domain.com/path/to/image.jpg"]
placeholderImage:[UIImage imageNamed:#"placeholder.png"]];
You are firstly downloading image and then showing image.You can download image by using lazy loading.
For this you can use EgoImageView not uiimageview.
self.ImageView.imageURL=[NSURL URLWithString:
here self.ImageView is of egoimageview type.
you can get this class from github.
https://github.com/enormego/EGOImageLoading
I am using DBChooser in my application to import images from dropbox, I am getting image url like & to dasplay the image in UIImageView i have following code
UIImageView *imageView=[[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)];
imageView.image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:#"https://www.dropbox.com/s/7qey2let40eb9je/PRELIMINARY_FORM_2.jpg"]]];
[self.view addSubview:imageView];
but the image is not showing in application. please help me how to display the dropbox image in UIImageView, is it issue of https OR what .
See this reference: https://cantonbecker.com/etcetera/2014/how-to-directly-link-or-embed-dropbox-images/
Short answer: append raw=1 as querystring value to your image url
Let's try:
+ (void) downloadImage : (NSURL*) url withCallBack:(DownloadCallbackBlock)callback
{
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[NSURLConnection sendAsynchronousRequest:urlRequest queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
{
NSHTTPURLResponse *httpresponse = (NSHTTPURLResponse *)response;
if (httpresponse.statusCode == 200)
{
callback(error,data);
}
else
{
//error
}
}];
}
And I use it:
[DownloadManager downloadImage:url withCallBack:^(NSError *error, NSData *data){
if (data)
{
UIImage *image = [[UIImage alloc]initWithData:data];
[_arrImages addObject:image];
dispatch_async(dispatch_get_main_queue(), ^{
[self processAddImage];
});
}
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];