AFNetworking离线队列 [英] AFNetworking Offline Queue

查看:114
本文介绍了AFNetworking离线队列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当前,我正在使用 AFHTTPRequestOperationManager 排队一个简单的脱机请求,并且它似乎无法以所需的方式工作:

Currently I am queueing a simple offline request using AFHTTPRequestOperationManager and it doesn't seem to work in the desired manner:

这是负责的代码,下面是不同的执行模式:

Here is the responsible code and below are different execution patterns:

@interface ViewController ()
{
    AFHTTPRequestOperationManager *manager;
}

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    manager = [AFHTTPRequestOperationManager manager];
    NSOperationQueue *operationQueue = manager.operationQueue;

    [[AFNetworkReachabilityManager sharedManager] startMonitoring];
    [[AFNetworkReachabilityManager sharedManager] setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status){
        NSLog(@"Reachability: %@", AFStringFromNetworkReachabilityStatus(status));
        switch (status) {
            case AFNetworkReachabilityStatusReachableViaWWAN:
            case AFNetworkReachabilityStatusReachableViaWiFi:
                NSLog(@"Operation: %@", operationQueue.operations);
                [operationQueue setSuspended:NO];
                NSLog(@"ONLINE");
                break;
            case AFNetworkReachabilityStatusNotReachable:
            default:
                NSLog(@"Operation: %@", operationQueue.operations);
                [operationQueue setSuspended:YES];
                NSLog(@"OFFLINE");
                break;
        }
    }];

    manager.responseSerializer = [AFHTTPResponseSerializer serializer];
    [manager GET:@"http://www.google.com"
      parameters:nil
         success:^(AFHTTPRequestOperation *operation, id response){
             NSLog(@"success");
         }
         failure:^(AFHTTPRequestOperation *operation, NSError *failure){
             NSLog(@"failure");
         }];
}

模式1:


  • 处于AirPlane模式的设备

  • 运行

控制台输出:

2015-03-21 16:03:54.486 OfflineSupport[928:227748] Reachability: Not Reachable
2015-03-21 16:03:54.494 OfflineSupport[928:227748] Operation: (
    "<AFHTTPRequestOperation: 0x1701d0c20, state: isExecuting, cancelled: NO request: <NSMutableURLRequest: 0x170014ab0> { URL: http://www.google.com }, response: (null)>"
)
2015-03-21 16:03:54.494 OfflineSupport[928:227748] OFFLINE
2015-03-21 16:03:54.544 OfflineSupport[928:227748] failure




  • 已激活Wifi

  • 控制台输出续:

    2015-03-21 16:04:05.594 OfflineSupport[928:227748] Reachability: Reachable via WiFi
    2015-03-21 16:04:05.595 OfflineSupport[928:227748] Operation: (
    )
    2015-03-21 16:04:05.595 OfflineSupport[928:227748] ONLINE
    






    模式2:


    • Wifi Active

    • 运行

    控制台输出:

    2015-03-21 16:05:43.818 OfflineSupport[934:228478] Reachability: Reachable via WiFi
    2015-03-21 16:05:43.826 OfflineSupport[934:228478] Operation: (
        "<AFHTTPRequestOperation: 0x1701dde20, state: isExecuting, cancelled: NO request: <NSMutableURLRequest: 0x17001ad10> { URL: http://www.google.com }, response: (null)>"
    )
    2015-03-21 16:05:43.826 OfflineSupport[934:228478] ONLINE
    2015-03-21 16:05:43.960 OfflineSupport[934:228478] success
    




    • 已激活AirPlane

    • 控制台输出续:

      2015-03-21 16:05:53.437 OfflineSupport[934:228478] Reachability: Not Reachable
      2015-03-21 16:05:53.438 OfflineSupport[934:228478] Operation: (
      )
      2015-03-21 16:05:53.438 OfflineSupport[934:228478] OFFLINE
      

      在模式1中,由于没有访问权限,该请求导致失败块。但是,当设备联机时,该请求将不会再次执行。在这里我缺少什么吗?在操作队列或故障块中配置某些内容?

      In pattern 1, the request results in the failure block as there is no access. But when the device comes online, the request is not executed again. Is there something I am missing here? Do I have to configure something on the operation queue or in the failure block?

      参考:使用setReachabilityStatusChangeBlock使设备脱机时的AFNetworking 2.0队列请求不执行任何操作 IOS-最好在重新建立连接时将要发送的请求排队的方法

      推荐答案

      一些观察结果:


      1. 在模式1中,您有一些竞态条件,因为可达性状态块异步运行,因此,如果您启动可达性并立即添加操作,则该状态可能尚未被标识为脱机,因此该队列可能尚未挂起,因此该操作可能立即开始(并且失败,因为重新离线)。

      1. In pattern 1, you have a bit of a race condition because the reachability status block runs asynchronously, so if you start reachability and immediately add operation, the status may not have been identified as being offline yet, and thus the queue may not have been suspended and thus the operation may start immediately (and fail because you're offline).

      如果您在开始可达性之前和开始任何操作之前暂停队列,则可以解决问题。如果您实际上处于离线状态,则队列将保持离线状态,并且所有已添加的操作也将被暂停。但是,如果您确实在线,则可及性块将被迅速调用,并且队列将立即被取消挂起。

      The problem is solved if you suspend the queue before starting reachability and before starting any operations. If you're actually offline, the queue will stay offline and any operations that were added will be suspended, too. But if you were really online, the reachability block will be called reasonably quickly and and the queue will be promptly be unsuspended. It eliminates this race condition.

      队列的已暂停状态不会影响已经进行的操作开始。仅影响尚未开始的那些操作。因此,如果在进行网络操作时连接脱机,则没有内置机制可以暂停操作,直到恢复连接,或者在状态更改时也不重新启动操作。如果要使用该功能,则必须自己实现。

      The suspended state of a queue does not affect operations that have already started. In only impacts those operations that have not yet started. So, if the connection goes offline while a network operation was in progress, there is no built in mechanism to pause the operation until the connection is restored, nor restart the operation when the status changes. If you want that functionality, you'd have to implement that yourself.






      还有一些观察结果:


      A few more observations:


      1. 不过,值得注意的是,由于可及性表明连接可用,不能保证请求成功。仍然需要妥善处理失败的请求。

      1. It's worth noting, though, that just because reachability says that connectivity is available, it doesn't guarantee that the request will succeed. You still need to gracefully handle failed requests.

      到之前的情况,如果您想要更可靠的我可以连接到特定服务器,您可能考虑使用 managerForDomain 而不是 sharedManager 。只需确保对生成的 AFNetworkReachabilityManager 保持强烈引用,因为与单例不同,它不会对其自身保持强烈引用。

      To the prior point, if you want a more reliable "can I connect to a particular server", you might consider using managerForDomain rather than sharedManager. Just make sure to keep a strong reference to the resulting AFNetworkReachabilityManager, because unlike the singleton, it won't keep a strong reference to itself.

      AFHTTPRequestOperationManager 来自2.x版,您可以考虑升级到最新版本(以便使用 AFHTTPSessionManager ,基于 NSURLSession 的实现)。在2.x中使用的 NSURLConnection 已被弃用。

      The AFHTTPRequestOperationManager is from version 2.x, and you might consider upgrading to the latest version (so that you use AFHTTPSessionManager, a NSURLSession based implementation). The NSURLConnection used in 2.x has been deprecated.

      AFHTTPSessionManager 不是基于 NSOperation 的。但是,如果您想享受仅在建立连接时发送请求功能,则可以自己将它们包装在异步 NSOperation 子类中(请参见使用NSOperation的AFNetworking 3.0 AFHTTPSessionManager ),您可以使用后台会话(请参见 AFNetworking 2.0和背景传输使用 AFHTTPSessionManager 和后台会话的要领,这在很大程度上仍适用于版本3)。

      The AFHTTPSessionManager is, unfortunately, not NSOperation-based. But if you want to enjoy the "send the requests only when the connection is established" functionality, you can either wrap them in asynchronous NSOperation subclass yourself (see AFNetworking 3.0 AFHTTPSessionManager using NSOperation) you can use a background session (see AFNetworking 2.0 and background transfers, while written for AFNetworking 2.x, outlines the essentials of using AFHTTPSessionManager and background session which still largely applies for version 3).

      这篇关于AFNetworking离线队列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆