connectionDidFinishLoading 在图像下载之前调用?

connectionDidFinishLoading calls before image has downloaded?

我正在尝试检索 Facebook 个人资料图片,但无法检查图片何时下载?

首先我创建了一个变量。

@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 不会 return 为空,它实际上 return 是照片。那么为什么 connectionDidFinishedLoading 在图片从 Facebook 下载之前调用呢?

所以我不确定为什么在您设置连接后立即调用 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
        });

    });
}

告诉我进展如何

问题几乎可以肯定既不是 NSURLConnection 也不是 Facebook API,而是你如何称呼它。但是,您的问题没有包含足够的信息供我们诊断。

因此,首先,扩展您的方法以包含更多诊断信息,例如:

// 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. 查看响应 headers 并确保它们正常,而不是报告一些非 200 状态代码; 2.实现将报告网络错误的委托;和 3. 如果图像转换失败,那么您显然没有收到图像,因此请停下来弄清楚您实际收到的是什么。 (通常如果服务器无法满足您的请求,响应实际上是 HTML 或类似的东西告诉您 为什么 它有问题。如果您不看它, 你瞎了。)

其次,您可以使用 Charles(或类似的东西)查看网络连接。 运行 模拟器上的应用程序,然后在应用程序运行时观察网络连接。

第三,如果您仍有问题,请创建 MCVE。也就是说,我们不想看到您的所有代码,但您应该创建尽可能简单的示例来说明您描述的问题。不要要求我们倾注大量代码,而是尽可能做到绝对bare-bones。