编写一个 iOS 应用程序,我需要给用户一个选项来阻止这个应用程序的网络访问。有可能在代码中做到这一点吗?
这意味着每次调用,由代码的任何部分(包括静态库)进行,都应该在那个特定时刻被阻止。
编写一个 iOS 应用程序,我需要给用户一个选项来阻止这个应用程序的网络访问。有可能在代码中做到这一点吗?
这意味着每次调用,由代码的任何部分(包括静态库)进行,都应该在那个特定时刻被阻止。
您可以使用自定义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];
}];
我正在使用一个 crittercism 库,它对应用程序中的每个网络调用进行网络分析,无论它是您自己的代码还是第三方库。
它是封闭源代码,但从我偶尔看到的堆栈跟踪来看,它们是 CFNetwork 类上的方法调配方法。这些是相当低级的网络类,将被更高级别的 api 使用,例如 NSURLConnection(这只是我的假设)。
所以我会先看看那里。
我认为您不能以编程方式阻止网络连接
解决问题
为阻塞网络保留一个布尔变量。检查每个网络调用变量上的值。如果块设置为是,不要调用任何网络服务。