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。
我正在尝试检索 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。