2015-06-16 9 views
1

Я пытаюсь получить изображение профиля Facebook, однако у меня возникли проблемы с возможностью проверить, когда изображение было загружено?connectionDidFinishLoading звонки перед загрузкой изображения?

Сначала я создаю переменную.

@property (strong, nonatomic) NSMutableData *imageData; 

Чем я запустил соединение.

-(void)getUserPicture { 

//Grab user profile picture 
imageData = [[NSMutableData alloc] init]; // the image will be loaded in here 
NSString *urlString = [NSString stringWithFormat:@"http://graph.facebook.com/%@/picture?type=large", userId]; 
NSMutableURLRequest *urlRequest = 
[NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlString]]; 

NSURLConnection *urlConnection = [[NSURLConnection alloc] initWithRequest:urlRequest 
                   delegate:self]; 
    if (!urlConnection) NSLog(@"Failed to download picture"); 


} 

После того, что я пытаюсь проверить, когда это будет сделано, так что я могу загрузить файл на моем внутреннем интерфейсе, однако моя проблема connectionDidFinishLoading вызывает почти мгновенно, пока изображение не скачал.

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { 
    imageData = [NSMutableData data]; 
} 

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { 
    [imageData appendData:data]; 
} 

- (void)connectionDidFinishLoading:(NSURLConnection *)connection { 

    userPicture = [UIImage imageWithData:imageData]; 

     NSLog(@"%@",userPicture); //this returns null :(

    } 

Странная вещь, если я называю этот метод дважды, NSLog не возвращает нуль, он фактически возвращает фотографию. Итак, почему connectionDidFinishedLoading звонок перед загрузкой изображения с Facebook?

+0

поместите свой 'userPicture = [UIImage imageWithData: imageData];' в ваши didReceiveData. –

+0

@SASmith Нет, это очень плохая идея. Если изображение мало, вы, скорее всего, не получили все данные в этот момент. – Rob

+0

@Rob, я не уверен, звонит ли он, прежде чем он скачал все, что я знаю, это мой NSLOG возвращает null, при первом вызове метода, чем если бы я вспомнил метод загрузки изображения? – Josh

ответ

0

Проблема почти наверняка ни NSURLConnection, ни API Facebook, но скорее, как вы это называете. Но ваш вопрос не содержит достаточно информации для нас, чтобы диагностировать его.

Итак, во-первых, расширить свои методы, чтобы включить больше диагностической информации, например:

// check the response header when we receive the response 

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { 
    imageData = [NSMutableData data]; 

    // if `statusCode` is not 200, show us what it was ... 

    if ([response isKindOfClass:[NSHTTPURLResponse class]]) { 
     int statusCode = [(NSHTTPURLResponse *)response statusCode]; 
     if (statusCode != 200) { 
      NSLog(@"Status code was %ld, but should be 200.", (long)statusCode); 
      NSLog(@"response = %@", response); 
     } 
    } 
} 

// make sure to detect and report any errors 

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { 
    NSLog(@"didFailWithError: %@", error); 
} 

// when you're done, if we fail to create `UIImage`, then it obviously 
// wasn't an image, so let's see what it was. 

- (void)connectionDidFinishLoading:(NSURLConnection *)connection { 
    userPicture = [UIImage imageWithData:imageData]; 

    // if not an image, then ... 

    if (!userPicture) { 
     NSString *responseString = [[NSString alloc] initWithData:imageData encoding:NSUTF8StringEncoding]; 
     if (responseString) { 
      // if it was a string, show it to us ... 

      NSLog(@"did not receive image: responseString = %@", responseString); 
     } else { 
      // if neither a string nor image data, then what was it ... 

      NSLog(@"did not receive image: imageData = %@", imageData); 
     } 
    } 

    // By the way, I'd expect to see you do something here to update the UI with the image; 
    // all of these delegate methods were called asynchronously, so you have 
    // to do something here that triggers the update of the UI, e.g. 
    // 
    // self.imageView.image = userPicture 
} 

Кстати, я напечатал выше без использования проверки синтаксиса Xcode и тому подобное, так что не удивляйтесь, если там есть некоторые ошибки. Но не беспокойтесь о фактическом коде и сосредоточьтесь на трех диагностических столпах, которые иллюстрируют: 1. Посмотрите на заголовки ответов и убедитесь, что они в порядке, а не сообщают о некотором статусе статуса не-200; 2. Внедрить делегат, который будет сообщать о сетевых ошибках; и 3. Если преобразование изображения не удалось, значит, вы, очевидно, не получили изображение, поэтому остановитесь и выясните, что вы действительно получили. (Часто, если серверу не удалось выполнить ваш запрос, ответ на самом деле является HTML или что-то вроде того, что сообщает вам , почему у у него были проблемы. Если вы не смотрите на него, вы летете вслепую.)

Во-вторых, вы можете посмотреть сетевое соединение, используя Charles (или что-то в этом роде). Запустите приложение на симуляторе, а затем просмотрите сетевое соединение по мере запуска приложения.

В-третьих, если у вас все еще есть проблемы, создайте MCVE. А именно, мы не хотим видеть весь ваш код, но вместо этого вы должны создать простейший возможный пример, который проявляет проблему, которую вы описываете. Не просите нас пролить тонны кода, а скорее сделайте это как абсолютно голые кости, насколько это возможно.

0

Так что я не уверен, почему connectionDidFinishLoading вызывается мгновенно после того, как вы установили соединение, но я могу помочь вам решить эту проблему.

Попробуйте это:

-(UIImage *) getImageFromURL:(NSString *)fileURL { 

    UIImage * result; 

    NSData * data = [NSData dataWithContentsOfURL:[NSURL URLWithString:fileURL]]; 
    result = [UIImage imageWithData:data]; 

    return result; 
} 

Где fileURL является строка с URL.

Если вы хотите, чтобы выполнить действие после отправки запроса попробовать вместо этого:

-(UIImage *) getImageFromURL:(NSString *)fileURL { 

    UIImage * result; 

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ 

     NSData * data = [NSData dataWithContentsOfURL:[NSURL URLWithString:fileURL]]; 
     result = [UIImage imageWithData:data]; 

     return result; 

     dispatch_async(dispatch_get_main_queue(), ^{ 
      //code for operation after download 
     }); 

    }); 
} 

Позвольте мне знать, как она идет

+0

Нет, переход на синхронный, не отмененный 'dataWithContentsOfURL' не является улучшением. Если вы хотите предложить что-то более простое, возможно, 'sendAsynchronousRequest' или лучше, если iOS 7 и более поздние,' NSURLSession'. Но это не улучшение по сравнению с кодом OPs, IMHO. – Rob

Смежные вопросы