AFNetworking 检查可用性

Posted

技术标签:

【中文标题】AFNetworking 检查可用性【英文标题】:AFNetworking checking Availability 【发布时间】:2013-02-23 14:33:29 【问题描述】:

我已经实现了AFNetworking 没有子类化AFHTTPClient,部分使用了我的DownloadQueueManager 中的以下代码:

-(void)downloadPodcastAt:(NSString *)url toPath:(NSString *)path

    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]
                                             cachePolicy:NSURLRequestReturnCacheDataElseLoad
                                         timeoutInterval:60.0];
    AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];

    operation.outputStream = [NSOutputStream outputStreamToFileAtPath:path append:NO];

    [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject)
    
        [self saveQueuedItemInformation];
     failure:^(AFHTTPRequestOperation *operation, NSError *error)
    
        // Other stuff
    ];

    [operation start];

我的问题是多方面的。我用谷歌搜索直到我的手指麻木了,但还没有找到一个像样的代码示例,可以使用AFNetworking 简单轻松地检查可达性状态。 (奇怪的是,有很多关于导入 SystemConfiguration.framework 的讨论,这似乎很容易)。所以如果我的用户想尽量减少他们的数据使用,并且只使用 wifi 下载,我如何检查 wifi,并且只有在 wifi 可用时才下载?

其次,AFNetworking 似乎想成为一个用户友好的前端。但我实际上可以在这个前端使用一个前端,因为那里有很多东西必须经过筛选才能获得需要的东西。我只需要访问一个 url,下载一个 xml 文件(基于可达性),然后用它做一些事情。我是否遗漏了一些使这成为一项简单任务的东西?

当我理解这一点时,我完全是在构建一个或五个前端来简化实现(假设我不只是一个白痴)。提前感谢您的任何回复。

【问题讨论】:

Reachability 不是 AFNetworking 的一部分,您必须依赖它的通知或进行状态检查 manually。这是有道理的,因为您可能希望在用户甚至能够尝试加载某些内容之前检查连接性,并且网络操作可能会使用缓存或返回错误。 但是 AFNetworking 使用了可用性,并且实现了与 Reachability 实现的非常相似的东西,以检查连接状态。我的问题主要是如何最有效地访问这些枚举变量。 【参考方案1】:

实际上与 A-Live said 可达性是 AFNetworking 的一部分相反。它在AFHTTPClient.hhere 中实现。您需要在 .pch 文件中正确导入 here 才能使用它。

要使用它,您可能希望拥有AFHTTPClient 的子类,这样您就可以使用setReachabilityStatusChangeBlock 定义的here。这是一个不使用子类的简单示例。

AFHTTPClient *client = [AFHTTPClient clientWithBaseURL:[NSURL URLWithString:@"http://google.com"]];
[client setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) 
    if (status == AFNetworkReachabilityStatusNotReachable) 
        // Not reachable
     else 
        // Reachable
    

    if (status == AFNetworkReachabilityStatusReachableViaWiFi) 
        // On wifi
    
];

如果您不喜欢这种可达性设置的工作方式,那么我会推荐 Apple 的可达性的 Tony Million's fork。简单例子:

Reachability *reach = [Reachability reachabilityWithHostname:@"google.com"];
if ([reach isReachable]) 
    // Reachable
    if ([reach isReachableViaWiFi]) 
        // On WiFi
    
 else 
    // Isn't reachable

    [reach setReachableBlock:^(Reachability *reachblock)
    
        // Now reachable
    ];

    [reach setUnreachableBlock:^(Reachability*reach)
    
        // Now unreachable
    ];

【讨论】:

这会继续监控可达性状态,还是一次性的? 块继续监控。如果您想阻止它们,可以将块设置为 nil(或等效项) 我使用 afnetworking 可达性块,但它从不触发并且 [httpClient networkReachabilityStatus] 总是返回 -1,有什么建议如何让它工作吗? @Pion 假设您没有关于缺少框架 (fix here) 的编译器警告,那么我的第一个猜测是,如果您在 ios 上使用它,它可能无法在模拟器中运行,您可能有在实际设备上。 @KeithSmiley 检查我的代码和信息。包括框架,xcode 中没有警告。使用 iPhone 4、iOS 6.1。 ***.com/questions/15452885/…【参考方案2】:

使用AFNetworking 2.0 及更高版本,可以像这样检查可用性,

    [[AFNetworkReachabilityManager sharedManager] setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) 
    switch (status) 
        case AFNetworkReachabilityStatusUnknown:
        case AFNetworkReachabilityStatusReachableViaWWAN:
        case AFNetworkReachabilityStatusReachableViaWiFi:
            //available
            break;
        case AFNetworkReachabilityStatusNotReachable:
            //not available
            break;
        default:
            break;
    

    NSLog(@"Reachability: %@", AFStringFromNetworkReachabilityStatus(status));

];

//start monitoring
[[AFNetworkReachabilityManager sharedManager] startMonitoring];

获取当前状态

[AFNetworkReachabilityManager sharedManager].reachable

【讨论】:

这是 AFNetworking 2.0 的正确答案,尽管我发现该块未被可靠调用【参考方案3】:

只是一个更新,较新版本的 AFNetworking 已弃用 AFHTTPClient。

您可以改用 AFHTTPRequestOperationManager.h

取自 github 页面本身的一些小东西:

AFHTTPRequestOperationManager *manager = [[AFHTTPRequestOperationManager alloc] initWithBaseURL:url]; //url can be google.com or something you want to reach

NSOperationQueue *operationQueue = manager.operationQueue;
[manager.reachabilityManager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status)


    switch (status)
    
        case AFNetworkReachabilityStatusReachableViaWWAN:
        case AFNetworkReachabilityStatusReachableViaWiFi:
        
            NSLog(@"SO REACHABLE");
            [operationQueue setSuspended:NO]; // or do whatever you want
            break;
        

        case AFNetworkReachabilityStatusNotReachable:
        default:
        
            NSLog(@"SO UNREACHABLE");
            [operationQueue setSuspended:YES]; 
            //not reachable,inform user perhaps
            break;
        
    
];
[manager.reachabilityManager startMonitoring];

【讨论】:

但是,如果可达性不会改变,这不会给出当前状态。要检查当前状态,[AFNetworkReachabilityManager sharedManager].reachable 应该这样做。 使用[manager.reachabilityManager isReachable] 检查当前状态对我有用。

以上是关于AFNetworking 检查可用性的主要内容,如果未能解决你的问题,请参考以下文章

使用 SDWebImage 而不是 AFNetworking 进行图像加载有很大的优势吗?

AFNetworking 检查进度

使用 AFNetworking 检查 Internet 连接状态

AFNetworking - 检查域的可达性

AFNetworking 2.0。如何检查套接字的可达性状态(managerForAddress :)?

AFNetworking - 在恢复下载文件之前检查下载的字节?