【问题标题】:AFNetworking checking AvailabilityAFNetworking 检查可用性
【发布时间】: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 实现的非常相似的东西,以检查连接状态。我的问题主要是如何最有效地访问这些枚举变量。

标签: ios ios6 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。 stackoverflow.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] 检查当前状态对我有用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多