[英]How to correctly provide networking feedback to the user? [closed]
我的应用程序使用后台GCD队列中的同步NSURLConnection从Web服务检索货币兑换率,如下所示:
// This method is called in background queue
- (NSData*)fetchDataWithURLStr:(NSString*)urlStr {
NSData *jsonData = nil;
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
NSURL *url = [NSURL URLWithString:urlStr];
NSURLResponse *response = nil;
NSError *error = nil;
NSURLRequest *request = [NSURLRequest requestWithURL:url];
jsonData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
if (error != nil) {
NSString *errorMsg = nil;
NSInteger ec = [error code];
if (ec == NSURLErrorTimedOut || ec == NSURLErrorCannotConnectToHost) {
errorMsg = @"Data temporarily not available.";
}
// Call on main thread
dispatch_async(dispatch_get_main_queue(), ^{
// Present the error
[self showErrorWithCode:ec title:@"ERROR" message:errorMsg];
});
jsonData = nil;
}
return jsonData;
}
但问题往往是应用程序试图获取数据,下载似乎永远在运行,没有任何反应。 没有任何状态更新。 通常我的WiFi只是停滞不前,我必须去设置,禁用并重新启用它。 或者我家里的WiFi路由器的互联网连接已关闭,但设备已连接到WiFi。
我真正想做的是提供有关网络目前究竟发生了什么的准确反馈。 例如
“试图联系服务器......”“等等......还在尝试......”“你的互联网似乎已经破了......”“再试一次......”“收到回复......”“已下载20%”“已下载40%“”完了!“
关于正在发生的事情的确切反馈。
有人推荐MKNetworkKit,但它只是觉得死了,没有任何反馈。
这个问题的解决方案适用于iOS吗?
编辑:我有可达性,但它没有给我这种我想在网络中显示的反馈。 此外,Reachability并没有告诉我当有WiFi连接但互联网停滞时发生了什么。
这里的根本问题是,根据您的应用程序可用的信息,不可能(是不可能的 )对网络问题进行可靠的诊断。 可能的原因太多,如果不了解实际网络和/或访问其他诊断信息源,其中一些原因根本无法区分。
你可以使用Reachability类。
下面是一个使用此可访问性类的示例代码,并通知我们正在使用哪种类型的连接。 示例代码来自apple。
以同样的方式看看和实现。
为了向用户显示进度,我建议从其委托方法使用NSURLConnection
,您可以轻松获取连接/请求的状态。
在其中一个委托中,它给出了错误描述。
您应该使用异步 API。 在单独的工作线程/队列中使用同步API通常不是正确的方法(参见有关这些主题的WWDC'12视频)
更好的解决方案是使用较新的NSURLConnection
API和+sendAsynchronousRequest:queue:completionHandler:
方法,而不是使用sendSynchronousRequest: returningResponse: error:
. 通过这种方式,您可以避免阻止API并在请求失败时被通知(无论是启动失败还是因为网络中断而运行失败等)。
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse*, NSData*, NSError*) {
// Code that will be executed asynchronously
// when the response to the request has been received
}];
// After the call to this method above, the code will continue executing
// WITHOUT WAITING for the network request to have its response.
这样您的UI就不会“冻结”,其余代码将继续运行,因此您可以在视图中显示一些进度指示器,例如,依此类推。 只有在响应到达completionHandler
才会异步调用completionHandler
块中的代码(独立于其余代码)。
此外,为了在网络本身无法访问(下降等)时获得通知,请使用可达性[编辑]您似乎已经按照您在问题的编辑中添加的那样执行此操作,因此您应该已经了解了这一点,能够在这种情况下通知用户)
提示:您也可以使用一些第三方框架,例如优秀的[ AFNetworking
(https://github.com/AFNetworking/AFNetworking),它允许您在发送网络请求时执行更多操作,例如具有Objective-C块在网络请求正在进行时调用的代码,使您可以轻松了解下载的进度。
将AFNetworking
项目集成到工作区后,您就可以执行以下操作:
AFHTTPRequestOperation* reqOp = [[[AFHTTPRequestOperation alloc] initWithRequest:request] autorelease];
[reqOp setCompletionBlockWithSuccess: ^(AFHTTPRequestOperation *operation, id responseObject)
{
// Code to execute asynchronously when you successfully received the whole page/file requested
// The received data is accessible in the responseObject variable.
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
// Code to execute asynchronously when you request failed, for example if you have a network error, or received some 404 error code, etc.
progressLabel.text = [NSString stringWithFormat:@"Download error: %@", error];
}];
[reqOp setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead)
{
// Code to execute periodically each time a partial chunk of data is received
// So that you can update your progression. For example:
progressLabel.text = [NSString stringWithFormat:@"Downloading %.1f%%", (float)totalBytesRead*100.f/totalBytesExpectedToRead];
}];
[reqOp start]; // start the request
// The rest of the code will continue to execute, and the blocks mentioned above will be called asynchronously when necessary.
这是我检查互联网连接的方式。 您需要先添加Reachability。
+ (BOOL) checkNetworkStatus
{
Reachability *reachability = [Reachability reachabilityForInternetConnection];
NetworkStatus networkStatus = [reachability currentReachabilityStatus];
return !(networkStatus == NotReachable);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.