处理NSURLConnection错误的最佳方法 - IPhone开发

时间:2015-01-13 18:40:37

标签: ios objective-c iphone

嘿,我有一个我正在处理的应用程序,经常会收到以下消息:

 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"];
}

2 个答案:

答案 0 :(得分:2)

按照internet connection test的这个答案,只需在队列中订购方法。

- (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];
}

P.S。这是暗示,而不是确切的答案。

答案 1 :(得分:1)

我会在if(error)语句中的else条件之后包装所有内容(如果服务失败,则无法设置响应/ json)。这样可以确保您不会尝试使用可能导致问题的nil数据创建对象。在捕获错误的if语句中,您也可以借此机会让调用方法知道服务失败。

调用方法可能正在等待数据从此服务返回。如果失败,数据将永远不会到来。

目前还不清楚是否在主线程上调用了这个,因为没有显示调用方法。话虽如此,您确实希望确保从后台线程中获取Web服务,以防止UI在运行时冻结。我个人更喜欢dispatch_async,但您可以查看将任务发送到后台线程的不同方法。