【问题标题】:AFNetworking and Reachability: Why request fail after resume?AFNetworking 和可达性:为什么请求在恢复后失败?
【发布时间】:2014-08-05 22:15:02
【问题描述】:

我使用AFHTTPSessionManager 向服务器发送请求,并使用可达性逻辑检查是否存在连接。

请求的代码很简单:

   [manager POST:urlString parameters:parameters  success:^(NSURLSessionDataTask *task, id responseObject) {
       //Parse data...
   } failure:^(NSURLSessionDataTask *task, NSError *error) {
        NSLog(@"Error: %@", error);
   }];

此外,还有一些代码可以检查可用性,例如 GitHub 中的示例:

NSOperationQueue *operationQueue = manager.operationQueue;
[manager.reachabilityManager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
    switch (status) {
        case AFNetworkReachabilityStatusReachableViaWWAN:
        case AFNetworkReachabilityStatusReachableViaWiFi:
            [operationQueue setSuspended:NO];
            break;
        case AFNetworkReachabilityStatusNotReachable:
        default:
            [operationQueue setSuspended:YES];
            break;
    }
}];

当状态改变时(例如AFNetworkReachabilityStatusNotReachableAFNetworkReachabilityStatusReachableViaWiFi),请求被恢复,为什么会执行失败块?这是什么原因?我是不是做错了什么?

【问题讨论】:

  • AppDelagate中是否开启了AFNetworkReachabilityManager监控?
  • 否。它是在初始化管理器时启动的。有区别吗,可达性管理器在哪里启动?
  • 评论setReachabilityStatusChangeBlock会发生什么?
  • 请求执行,但由于队列未挂起而失败并出现NSURLErrorCannotConnectToHost 代码。
  • 如果您使用的 baseUrl 不同于初始化 AFHTTPSessionManager 的默认值,那么当您将其更改为类似“google.com”时会发生什么?

标签: ios objective-c afnetworking


【解决方案1】:

AFURLSessionManager 中的operationQueue 仅用于委托回调(请参阅标题中的文档)。

我怀疑请求是在离线时执行的,但回调被暂停并仅在operationQueue 恢复时触发。

但是我还没有找到在线后恢复请求的方法。

【讨论】:

  • 哦,我忘记了这个问题:) 我找到了一个解决方案,但它可能只对我有用。它的工作原理如下:如果请求因 Internet 连接而失败,我将其添加到他的特定属性(如类型、参数等)到我的核心数据模型。当网络再次可访问时,使用“AFNetworkingReachabilityDidChangeNotification”请求使用此参数重新执行。 HTH
【解决方案2】:

我认为这可能是网络错误。

事实上:AFNetworking 不会为您检查 Internet,因此如果它返回失败,则说明存在连接错误或其他逻辑错误(我想这不是第二种情况)。

首先:你的可达性经理做什么测试?尝试访问的 IP 地址或域是什么? 因为如果您的可达性状态返回一个 wifi 连接,它不会告诉您您的 Web 服务响应您。

如果您在遇到 AFNetworking 故障块时测试您的 Internet 连接,那么测试相关 Web 服务器的特定地址非常重要。 您还可以在 Internet 连接更改后立即进行多次尝试,因为您可以拥有 wifi 网络但还不能访问 Internet(例如,在分配动态 IP 地址时)。

【讨论】:

  • 首先,感谢您的回答。我有一个类似这样的 baseURL 属性:NSURL *rootURL = [NSURL URLWithString:@"http://example.com/"];,并且AFHTTPSessionManager 使用此根 URL 进行初始化。根据文档 AFNetworking 可达性管理器观察此主机中的更改。所以如果状态改变(主机激活或WIFI开启),操作队列必须恢复,请求必须再次执行。
【解决方案3】:

这种情况会发生在设备上还是仅在模拟器上?因为我在 Xcode 5 模拟器上遇到了可达性问题,但它在设备上运行良好(我的问题是当它必须从离线模式更改为在线模式时,它说它仍然处于离线状态并引发一些错误)

【讨论】:

  • 在设备上。我根本没有尝试过模拟器。
【解决方案4】:

当使用AFNetworkReachabilityManager 时,我通常在AppDelegate.m 中启动它。我实际上不记得它是否必须从那里开始,但我认为应该。如果您没有在其中启动它,请尝试一下,如下所示:

- (void)applicationDidBecomeActive:(UIApplication *)application {

   [[AFNetworkReachabilityManager sharedManager] startMonitoring];

   // Rest of your code here
}

编辑:

也试试:

NSOperationQueue * operationQueue = [[NSOperationQueue alloc] init];
[operationQueue addOperation:manager.operationQueue];
[manager.operationQueue release]; // as i have read you must do this release, but not sure
// rest of your code here

您可能已经看过这篇文章,但如果没有,也许它会有所帮助:http://www.raywenderlich.com/19788/how-to-use-nsoperations-and-nsoperationqueues

编辑 2:

假设您试图模拟从入队开始就没有互联网连接的情况,可能您的问题类似于AFNetworking 2.0 Reachability

从这个意义上说,您可能应该在入队操作之前设置可达性检查,如下所示:

if ([AFNetworkReachabilityManager sharedManager].reachable) {
   NSOperationQueue *operationQueue = manager.operationQueue;
}

让我知道它是否有效。

【讨论】:

  • 感谢您的建议。我试过这个。队列暂停,但是当每次执行失败块时恢复它([operationQueue setSuspended:NO];)。这意味着由于某种原因主机仍然无法访问。我可能遗漏了一些东西,但是什么?
  • Xcode5中不能使用release,但是尝试了其他操作队列的方法,不行。
  • 是的,通常你在使用 ARC 时不会使用 release。但是在我通过链接的这篇文章中,它指出除了使用 ARC 之外,您还应该使用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-02
  • 1970-01-01
  • 2014-11-23
  • 1970-01-01
相关资源
最近更新 更多