iPhone - асинхронная загрузка NSURLConnection с использованием URL-адресов в NSArray

Я видел почти все сообщения о NSURL на этом сайте, и я все еще застрял. Я использую Xcode 4.5.

Я пытаюсь загрузить изображения и отобразить их в UIScrollView.

Я хочу загружать изображения с асинхронной загрузкой, используя URL-адреса, которые сохраняются в массиве, заполненном с помощью JSON. Я получаю URL-адреса из базы данных в формате JSON. Это работает довольно хорошо, и я вижу, что URL-адрес помещается в urlArray, но создание URLConnection для получения изображения, похоже, не работает.

Я не могу загрузить изображения или, по крайней мере, они не отображаются в моем imageArray.

Вот мой код и спасибо за любую помощь !! Дайте мне знать, что еще нужно

- (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;
}

person Siriss    schedule 18.12.2012    source источник
comment
что будет theJsonData после завершения соединения?   -  person Gabriele Petronella    schedule 18.12.2012
comment
theJsonData имеет необработанный JSON из соединения. Они анализируются и помещаются в jsonArray. Я знаю, что имена моих переменных нуждаются в доработке.   -  person Siriss    schedule 18.12.2012
comment
я имел в виду, каково его фактическое значение, вы пытались его зарегистрировать?   -  person Gabriele Petronella    schedule 18.12.2012
comment
Я сделал это, когда работал над синтаксическим анализом JSON, и я вижу правильные строки, когда проверяю NSLOG после синтаксического анализа.   -  person Siriss    schedule 18.12.2012


Ответы (1)


вы никогда не загружаете imageData. вы назначаете ему объект запроса. вот почему вы тоже получаете предупреждение. объект NSURLConnection не является объектом NSData: NSData *imgData = [[NSURLConnection alloc] initWithRequest:imageRequest delegate:self]; //"Incompatible pointer types initializing ..." warning here

Сегодня я бы переписал его, используя метод startAsyncConnection. сек

- вот и все, непроверенные и написанные в текстовом редакторе, но это должно помочь вам начать (я повторно использовал большую часть вашего кода, но также сильно сократил его)

#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
person Daij-Djan    schedule 18.12.2012
comment
Вау, спасибо за такой отличный ответ. Итак, я лучше понимаю это, что мне делать с connectionDidFinishLoading и другими частями NSURLConnection? Спасибо еще раз! - person Siriss; 19.12.2012
comment
удалите их. новые удобные методы, основанные на блоках, в этом не нуждаются. ТОЛЬКО ЕСЛИ вам понадобится обрабатывать аутентификацию позже, вам понадобится больше кода - person Daij-Djan; 19.12.2012
comment
Daij-Djan, можете ли вы отредактировать скобку, я получаю сообщение об ошибке в блоке loadImageArray. - person Hardik Patel; 09.05.2013
comment
Я забыл свой обычный отказ от ответственности: я написал это встроенным образом, и он не тестировался и даже не компилировался! - плохо смотрю на это - person Daij-Djan; 10.05.2013