有一个正在处理的应用程序,我经常会收到以下消息:
NSURLConnection error: Error Domain=NSURLErrorDomain Code=-1005
"The network connection was lost."
我的日志将记录此内容,然后我的应用程序将冻结。 我的希望是,我最好的选择是什么,只是发送互联网丢失的通知,请重试而不是关闭我的应用程序?
这是我正在做的事情:
用户登录 -> 主控制器加载并运行以下命令:
// EXECUTE SERVER CALL
-(void)makeRequests
{
/* GRAB USERNAME TO BE SENT OVER FOR POPULATING DATA */
NSArray *get = [[SSKeychain allAccounts] init];
NSString *username = [get[0] objectForKey:@"acct"];
NSDictionary *dictionary = @{@"function": @"populateHomePage", @"username" : username};
NSError *error = nil;
NSData *data = [NSJSONSerialization dataWithJSONObject:dictionary options:0 error:&error];
NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
if (error)
NSLog(@"%s: JSON encode error: %@", __FUNCTION__, error);
NSURL *url = [NSURL URLWithString:@"/IOS-Frame/grab-data.php"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:@"POST"];
NSString *params = [NSString stringWithFormat:@"json=%@",
[string stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
NSData *paramsData = [params dataUsingEncoding:NSUTF8StringEncoding];
[request addValue:@"8bit" forHTTPHeaderField:@"Content-Transfer-Encoding"];
[request addValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
[request addValue:[NSString stringWithFormat:@"%lu", (unsigned long)[paramsData length]] forHTTPHeaderField:@"Content-Length"];
[request setHTTPBody:paramsData];
// issue the request
NSURLResponse *response = nil;
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
if (error)
NSLog(@"%s: NSURLConnection error: %@", __FUNCTION__, error);
NSString *responseString = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];
NSLog(@"responseString: %@",responseString);
// GRAB STATUS OBJECT
NSDictionary* json = [NSJSONSerialization
JSONObjectWithData:returnData //1
options:kNilOptions
error:&error];
self.dataGrabed_dictionary = [json objectForKey:@"retrieved_data"];
}
按照此答案进行互联网连接测试,只需在队列中订购方法。
- (void)testInternetConnection
{
internetReachableFoo = [Reachability reachabilityWithHostname:@"www.google.com"];
// Internet is reachable
internetReachableFoo.reachableBlock = ^(Reachability*reach)
{
// Update the UI on the main thread
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"Yayyy, we have the interwebs!");
//show activity indicator........block ui until data loads.
//queue methods
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// Save in the background
[self makerequests];
dispatch_async(dispatch_get_main_queue(), ^{
// Perform UI functions on the main thread!
//dismiss activity indicator
});
});
});
};
// Internet is not reachable
internetReachableFoo.unreachableBlock = ^(Reachability*reach)
{
// Update the UI on the main thread
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"Someone broke the internet :(");
//show some alert....
});
};
[internetReachableFoo startNotifier];
}
附言这是提示,而不是确切的答案。
if(error)
条件之后的所有内容包装在 else
语句中(如果服务失败,设置响应/json 没有意义)。这将确保您不会尝试使用可能导致问题的nil
数据创建对象。在捕获错误的 if
语句中,还可以借此机会让调用方法知道服务失败。
调用方法可能正在等待数据从此服务返回。如果失败,数据将永远不会出现。
目前尚不清楚这是否在主线程上被调用,因为没有显示调用方法。话虽如此,您确实希望确保从后台线程命中 Web 服务,以防止您的 UI 在运行时冻结。我个人更喜欢dispatch_async
但您可以查看将任务发送到后台线程的不同方法。