I have seen almost all the posts about NSURL on this site, and I am still stuck. I am using Xcode 4.5.
I am trying to download images and display them in a UIScrollView.
I want to download asynchronously download images using URLs, that get stored in an array populated using JSON. I get the URLs from a JSON grab off of my database. That works quite well and I can see the URL's being placed into the urlArray, but making the URLConnection to get the image, seems to fail.
I can't get any of the images to download, or at least they don't show up in my imageArray.
Here is my code and thank you for any help!! Let me know what else is needed
- (void)viewDidLoad
{
[super viewDidLoad];
//show network activity to user.... very useful
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
//call getJSON. getJSON does not parse, but it connects and gets the data.
[self getJSON];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)getJSON
{
NSURL *url = [NSURL URLWithString:@"http://"My server goes here/json.php"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
//just initialize the connection, do not
[[NSURLConnection alloc] initWithRequest:request delegate:self]; //"Ecression result unused" warning here
}
- (void)getNextImage
{
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
for (int y = 0; y < urlArray.count; y++)
{
NSString *urlString = [urlArray objectAtIndex:y];
NSLog(@"Array String is: %@ ", urlString);
NSURL *arrayURL = [NSURL URLWithString:urlString];
NSURLRequest *imageRequest = [NSURLRequest requestWithURL:arrayURL];
NSData *imgData = [[NSURLConnection alloc] initWithRequest:imageRequest delegate:self]; //"Incompatible pointer types initializing ..." warning here
imageData = [UIImage imageWithData:imgData];
[imageArray addObject:imageData];
}
NSLog(@"LEAVING getNextImage");
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
theJsonData = [[NSMutableData alloc] init];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[theJsonData appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
urlArray = [[NSMutableArray alloc] init];
//This is where all the JSON Parsing is being done.
//Turn off the data indicator, because the download is complete.
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
jsonArray = [NSJSONSerialization JSONObjectWithData:theJsonData options:nil error:nil]; //"Incompatible pointer types initializing ..." warning here
//get the URL strings out of the jsonArray
for (int x = 0; x < jsonArray.count; x++)
{
NSString *urlString = [[jsonArray objectAtIndex:x] objectForKey:@"image_URL"];
NSLog(@"String is %@ ", urlString);
[urlArray addObject:urlString];
}
[self getNextImage];
//display the images..... Not sure why this is in connectionDidFinishLoading.
for (int x = 0; x < imageArray.count; x++)
{
CGRect frame;
frame.origin.x = self.mainScroll.frame.size.width * x;
frame.origin.y = 0;
frame.size = self.mainScroll.frame.size;
UIImageView *nextIV = [[UIImageView alloc] initWithFrame:frame];
[nextIV setImage:imageData];
[self.mainScroll addSubview:nextIV];
//NSLog(@"Pass %d", x);
}
self.mainScroll.contentSize = CGSizeMake(self.mainScroll.frame.size.width * imageArray.count,1.0);
NSLog(@"!!!!!!leaving connection did finnish loading!!!!!");
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
//show error message to user if there is a connection error.
UIAlertView *errorView = [[UIAlertView alloc] initWithTitle:@"Error" message:@"The Download could not complete - please make sure you're connected to the internet." delegate:nil cancelButtonTitle:@"Dismiss" otherButtonTitles:nil];
[errorView show];
//turn off the network activity indicatior
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}
you never download imageData. you assign it the request object . thats why you get the warning too. a NSURLConnection object is not a NSData object: NSData *imgData = [[NSURLConnection alloc] initWithRequest:imageRequest delegate:self]; //"Incompatible pointer types initializing ..." warning here
I would today rewrite it using the startAsyncConnection method. sec
-- there you go, untested and written in text edit but it should get you started (I reused most of your code but cut it down a lot too)
#import "RootViewController.h"
@interface RootViewController ()
@property(assign) IBOutlet UIScrollView *mainScroll;
@end
@implementation RootViewController
- (void)viewDidLoad
{
[super viewDidLoad];
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
[self getJSONAndImageData];
}
- (void)getJSONAndImageData
{
NSURL *url = [NSURL URLWithString:@"http://My server goes here/json.php"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse*r, NSData*d, NSError*e) {
[self parseJSONAndGetImages:d];
}];
}
- (void)parseJSONAndGetImages:(NSData*)data
{
NSMutableArray *urlArray = [[NSMutableArray alloc] init];
//This is where all the JSON Parsing is being done.
//Turn off the data indicator, because the download is complete.
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
NSArray *jsonArray = (NSArray*)[NSJSONSerialization JSONObjectWithData:data options:nil error:nil]; //"Incompatible pointer types initializing ..." warning here => likely not an array then
assert([jsonArray isKindOfClass:[NSArray class]]);
//could be made in one liner with KVC
//get the URL strings out of the jsonArray
for (int x = 0; x < jsonArray.count; x++)
{
NSString *urlString = [[jsonArray objectAtIndex:x] objectForKey:@"image_URL"];
NSLog(@"String is %@ ", urlString);
[urlArray addObject:urlString];
}
[self loadImageArray:urlArray handler:^(NSArray* imageArray) {
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
for (int x = 0; x < imageArray.count; x++)
{
CGRect frame;
frame.origin.x = self.mainScroll.frame.size.width * x;
frame.origin.y = 0;
frame.size = self.mainScroll.frame.size;
UIImageView *nextIV = [[UIImageView alloc] initWithFrame:frame];
[nextIV setImage:imageArray[x]];
[self.mainScroll addSubview:nextIV];
//NSLog(@"Pass %d", x);
}
self.mainScroll.contentSize = CGSizeMake(self.mainScroll.frame.size.width * imageArray.count,1.0);
}];
}
//for SIMPLICITY I do synchronous networking here!
- (void)loadImageArray:(NSArray *)urlArray handler:(void(^)())handler {
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSMutableArray *imageArray = [NSMutableArray array];
for (int y = 0; y < urlArray.count; y++)
{
NSString *urlString = [urlArray objectAtIndex:y];
NSLog(@"Array String is: %@ ", urlString);
NSURL *arrayURL = [NSURL URLWithString:urlString];
NSURLRequest *imageRequest = [NSURLRequest requestWithURL:arrayURL];
NSData *imgData = [NSURLConnection sendSynchronousRequest:imageRequest returningResponse:nil error:nil];
UIImage *image = [UIImage imageWithData:imgData];
[imageArray addObject:image];
}
dispatch_async(dispatch_get_main_queue(),^ {
handler(imageArray);
});
});
}
@end
来源:https://stackoverflow.com/questions/13938354/iphone-nsurlconnection-asynchronous-download-using-urls-in-nsarray