AFNetworking离线队列

时间:2015-03-21 20:09:07

标签: ios httprequest afnetworking

目前,我正在使用AFHTTPRequestOperationManager排队一个简单的离线请求,但它似乎无法以所需的方式运行:

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

@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
  • 无线激活

控制台输出contd。:

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已激活

控制台输出contd。:

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中,请求导致失败块,因为没有访问权限。但是当设备联机时,请求不会再次执行。这里有什么我想念的吗?我是否必须在操作队列或故障块中配置某些内容?

参考:AFNetworking 2.0 queue request when device is offline with setReachabilityStatusChangeBlock does nothingIOS - best way to queue requests to be sent when connection is reestablished

1 个答案:

答案 0 :(得分:4)

一些观察结果:

  1. 在模式1中,您有一些竞争条件,因为可达性状态块是异步运行的,因此如果您启动可达性并立即添加操作,则状态可能尚未被识别为脱机,因此队列可能没有被挂起,因此操作可能会立即开始(并因为您处于脱机状态而失败)。

    如果在启动可达性之前和开始任何操作之前挂起队列,问题就解决了。如果您实际处于脱机状态,则队列将保持脱机状态,并且所有已添加的操作也将暂停。但是如果你真的在线,可以快速调用可达性块,并且队列将立即被取消暂停。它消除了这种竞争条件。

  2. 队列的suspended状态不会影响已经启动的操作。仅影响那些尚未开始的操作。因此,如果在网络操作正在进行时连接脱机,则在恢复连接之前没有内置机制暂停操作,也不会在状态更改时重新启动操作。如果您需要该功能,则必须自己实现。


  3. 还有一些观察结果:

    1. 值得注意的是,仅仅因为可达性表明连接可用,它并不能保证请求会成功。您仍然需要优雅地处理失败的请求。

    2. 对于前一点,如果您想要更可靠的“我可以连接到特定服务器”,您可以考虑使用managerForDomain而不是sharedManager。只要确保对结果AFNetworkReachabilityManager保持强烈的引用,因为与单身人士不同,它不会对自己有强烈的引用。

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

      遗憾的是,AFHTTPSessionManager不是基于NSOperation的。但是,如果您想享受“仅在建立连接时发送请求”功能,您可以自己将它们包装在异步NSOperation子类中(请参阅AFNetworking 3.0 AFHTTPSessionManager using NSOperation),您可以使用后台会话(请参阅AFNetworking 2.0 and background transfers,虽然是为AFNetworking 2.x编写的,但概述了使用AFHTTPSessionManager和后台会话的基本要素,这些内容仍主要适用于版本3)。