AFNetworking检查可用性

19

我已经实现了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 的一部分,您必须依赖它的通知或手动进行状态检查。这是有道理的,因为您可能希望在用户尝试加载某些内容之前检查其连接性,并且网络操作可以使用缓存或返回错误。 - A-Live
但是AFNetworking使用了Availability,并且实现了与Reachability类似的功能来检查连接状态。我的问题主要是如何最有效地访问这些枚举变量。 - AMayes
3个回答

45
实际上,与A-Live所说相反,可达性是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
    }
}];

如果您不喜欢这种可达性设置的工作方式,我建议使用Tony Million's fork Apple的Reachability。一个简单的例子:
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
    }];
}

这会继续监测可达状态吗,还是只有一次? - AMayes
这些块将继续监视。如果您想要停止它们,可以将这些块设置为 nil(或等效项)。 - Keith Smiley
我使用AFNetworking的可达性块,但它从未触发,而[httpClient networkReachabilityStatus]始终返回-1,有什么建议如何使其工作? - Pion
@Pion 假设您没有编译器警告缺少框架(在此处修复),那么我的第一个猜测是,如果您在iOS上使用它,则可能无法在模拟器中工作,您可能必须在实际设备上使用。 - Keith Smiley
1
@KeithSmiley请查看我的代码和信息。框架已包含,Xcode中没有警告。使用iPhone 4,iOS 6.1。http://stackoverflow.com/questions/15452885/afnetworking-reachablity-returning-always-1 - Pion
显示剩余4条评论

20

使用 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的正确答案,尽管我发现该块不可靠地被调用。 - Fraser

8

更新一下,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];

1
然而,如果可达性不会改变,这将无法提供当前状态。要检查当前状态,应该像这样执行[AFNetworkReachabilityManager sharedManager].reachable - Hemang
使用 [manager.reachabilityManager isReachable] 来检查当前状态对我很有效。 - ᴳᴿᴵᴹᴹ

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接