我可以阻止特定时刻的网络访问吗?

时间:2013-06-15 09:57:07

标签: iphone ios objective-c networking

编写iOS应用程序,我会向用户提供阻止此应用程序的网络访问权限的选项。 是否可以在代码中执行此操作?

意味着每个调用都是由代码的任何部分(以及包括静态库)构成的,应该在特定时刻被阻止。

3 个答案:

答案 0 :(得分:7)

您可以使用拦截所有网络电话的自定义NSURLProtocol

这正是我在OHHTTPStubs库中对存根网络请求所做的事情(我的库使用私有API来模拟网络响应,但在你的情况下,如果你不需要伪造响应,你可以避免这些调用私有API并在生产代码中使用此技术)

  

[编辑] 由于此回答,OHHTTPStubs已更新,不再使用任何私有API,因此您甚至可以在生产代码中使用它。有关代码示例,请参阅本答案末尾的编辑。


@interface BlockAllRequestsProtocol : NSURLProtocol
@end

@implementation BlockAllRequestsProtocol
+ (BOOL)canInitWithRequest:(NSURLRequest *)request
{
    return YES; // Intercept all outgoing requests, whatever the URL scheme
    // (you can adapt this at your convenience of course if you need to block only specific requests)
}

+ (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request { return request; }
- (NSCachedURLResponse *)cachedResponse { return nil; }

- (void)startLoading
{
    // For every request, emit "didFailWithError:" with an NSError to reflect the network blocking state
    id<NSURLProtocolClient> client = [self client];
    NSError* error = [NSError errorWithDomain:NSURLErrorDomain
                                         code:kCFURLErrorNotConnectedToInternet // = -1009 = error code when network is down
                                     userInfo:@{ NSLocalizedDescriptionKey:@"All network requests are blocked by the application"}];
    [client URLProtocol:self didFailWithError:error];
}
- (void)stopLoading { }

@end

然后安装此协议并阻止所有网络请求:

[NSURLProtocol registerClass:[BlockAllRequestsProtocol class]];

稍后将其卸载并让您的网络请求进入现实世界:

[NSURLProtocol unregisterClass:[BlockAllRequestsProtocol class]];

[编辑]由于我的回答,我已经更新了我的库,它不再使用任何私有API。因此,任何人都可以直接使用OHHTTPStubs,即使是您需要的用法,例如:

[OHHTTPStubs stubRequestsPassingTest:^BOOL(NSURLRequest* request) {
    return YES; // In your case, you want to prevent ALL requests to hit the real world
} withStubResponse:^OHHTTPStubsResponse*(NSURLRequest* request) {
    NSError* noNetworkError = [NSError errorWithDomain:NSURLErrorDomain
                    code:kCFURLErrorNotConnectedToInternet userInfo:nil];
    return [OHHTTPStubsResponse responseWithError:noNetworkError];
}];

答案 1 :(得分:0)

我不认为你可以通过progamatically阻止网络连接

解决方法

保留bool变量以阻止网络。检查每个网络调用变量上的值。如果块设置为是,则不要调用任何Web服务。

答案 2 :(得分:0)

我正在使用一个关键应用程序库,它可以对应用程序中的每个网络调用进行网络分析,无论它是您自己的代码还是第三方库。

它是封闭源代码,但是从偶尔的堆栈跟踪中我看到的,它们是CFNetwork类上的方法调配方法。这些是相当低级别的网络类,将由更高级别的apis使用,例如NSURLConnection(这只是我的假设)。

所以我从那里开始。