2

编写一个 iOS 应用程序,我需要给用户一个选项来阻止这个应用程序的网络访问。有可能在代码中做到这一点吗?

这意味着每次调用,由代码的任何部分(包括静态库)进行,都应该在那个特定时刻被阻止。

4

3 回答 3

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];
}];
于 2013-06-15T11:06:57.963 回答
0

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

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

所以我会先看看那里。

于 2013-06-15T10:42:32.653 回答
0

我认为您不能以编程方式阻止网络连接

解决问题

为阻塞网络保留一个布尔变量。检查每个网络调用变量上的值。如果块设置为是,不要调用任何网络服务。

于 2013-06-15T10:02:24.947 回答