目前我正在使用 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:
控制台输出:
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
控制台输出续:
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:
控制台输出:
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
控制台输出续:
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 中,请求导致失败 block ,因为没有访问权限。但是当设备上线时,请求不再执行。我在这里缺少什么吗?我必须在操作队列或失败 block 中配置一些东西吗?
引用:AFNetworking 2.0 queue request when device is offline with setReachabilityStatusChangeBlock does nothing , IOS - best way to queue requests to be sent when connection is reestablished
Best Answer-推荐答案 strong>
一些观察:
在模式 1 中,由于可达性状态 block 是异步运行的,因此存在一些竞争条件,因此如果启动可达性并立即添加操作,则状态可能尚未被识别为离线,因此队列可能尚未暂停,因此操作可能会立即开始(并且由于您处于离线状态而失败)。
如果在开始可达性之前和开始任何操作之前挂起队列,问题就解决了。如果您实际上处于脱机状态,则队列将保持脱机状态,并且添加的任何操作也将暂停。但是如果你真的在线,可达性 block 将被相当快地调用,并且队列将被立即解除暂停。它消除了这种竞争条件。
队列的suspended 状态不会影响已经开始的操作。仅影响那些尚未开始的操作。因此,如果在网络操作正在进行时连接脱机,则没有内置机制可以暂停操作直到连接恢复,也没有在状态更改时重新启动操作。如果您需要该功能,则必须自己实现。
更多观察:
值得注意的是,仅仅因为可达性表明连接可用,它并不能保证请求会成功。您仍然需要优雅地处理失败的请求。
对于前面一点,如果您想要更可靠的“我可以连接到特定服务器”,您可以考虑使用 managerForDomain 而不是 sharedManager 。只需确保对生成的 AFNetworkReachabilityManager 保持强引用,因为与单例不同,它不会对自身保持强引用。
AFHTTPRequestOperationManager 来自 2.x 版,您可以考虑升级到最新版本(以便您使用 AFHTTPSessionManager ,一个 NSURLSession 基于实现)。 2.x 中使用的 NSURLConnection 已被弃用。
不幸的是,AFHTTPSessionManager 不是基于 NSOperation 的。但是,如果您想享受“仅在建立连接时发送请求”功能,您可以自己将它们包装在异步 NSOperation 子类中(参见 AFNetworking 3.0 AFHTTPSessionManager using NSOperation),您可以使用后台 session (请参阅 AFNetworking 2.0 and background transfers ,虽然是为 AFNetworking 2.x 编写的,但概述了使用 AFHTTPSessionManager 和后台 session 的基本要素,这仍然主要适用于版本 3)。
关于ios - AFNetworking 离线队列,我们在Stack Overflow上找到一个类似的问题:
https://stackoverflow.com/questions/29187488/
|