MMBarricade是一个用于在iOS应用中设置运行时可配置的本地服务器的框架。它通过创建一个名为 "barricade" 的 NSURLProtocol 来拦截 outgoing network traffic 并将其重定向到一个自定义的本地响应,而无需对现有的网络代码进行任何更改。
NSURLSession
, NSURLConnection
, AFNetworking
和所有使用 Foundation 的 URL 加载系统 的网络都是支持的。
大多数其他的本地服务器实现只支持每个请求一个响应,但是Barricade支持每个请求多个响应。这使得我们能够在运行时提供一个接口,以便修改对请求返回哪个响应。
在 开发过程 中,Barricade 非常有用,可以在构建特性的同时轻松测试其所有边缘情况,而无需频繁调整实时服务器状态。
对于 单元测试和集成测试,Barricade 允许您轻松切换到每个请求的预定义响应,以便测试可以彻底覆盖边缘情况。
同样,对于 UI测试,如KIF,也可以编程更新所选响应,这使得测试套件可以覆盖失败案例以及“快乐路径”。
请参考DevelopmentApp/Barricade.xcworkspace
中MMBarricadeTests.m
中的单元测试,以了解如何使用Barricade实现单元测试的几个示例。
安装MMBarricade最简单的方法是使用CocoaPods
pod 'MMBarricade', '~> 1.0.0'
Barricade的功能基于四个主要类:MMBarricade
,MMBarricadeResponse
,MMBarricadeResponseSet
和 <MMBarricadeResponseStore>
。
MMBarricade
MMBarricade
是NSURLProtocol的一个子类,是和Barricade交互的主要类。
MMBarricadeResponse
MMBarricadeResponse
的实例定义了对HTTP请求的单个响应。例如,响应可能包括一个HTTP状态码200,内容类型 "application/json",以及响应数据的一个JSON对象。
MMBarricadeResponseSet
MMBarricadeResponseSet
的实例表示单个请求可能的一组响应。例如,对于 /login
API 端点的响应集可能是一组三个响应,表示成功、无效凭据和服务器错误。
MMBarricadeResponseStore
响应库符合 <MMBarricadeResponseStore>
规范,并负责从可能响应集中选择应该返回的响应。此选择可以通过程序修改或通过 Tweaks UI(如上 gif 所示)进行修改。
首先,导入库头文件。如果使用 Tweaks 管理用户选择,请导入 Tweaks 类别以获取便利初始化器访问权限。
#import "MMBarricade.h"
然后,给拦路墩分配一个响应存储并启用它。启用后,拦路墩将开始响应对网络请求。
// Setup the barricade. This only needs to be done once.
[MMBarricade setupWithInMemoryResponseStore];
[MMBarricade enable];
在这个例子中,我们将设置拦路墩能够响应该 /login
API 端点的一个可能响应。响应集和每个单个响应的 "name" 参数是面向用户的字符串,用于标识开发人员对请求和响应对。它们在 Tweaks UI 中显示,并且可以用于程序更新所选响应。
在这个例子中,响应文件是存储在磁盘上名为 "LocalServer" 的应用包子目录中 JSON 格式的文本文件。没有必须遵循的文件命名约定。
// Create a response set for each API call that should be barricaded.
MMBarricadeResponseSet *responseSet = [MMBarricadeResponseSet responseSetForRequestName:@"Login" respondsToRequest:^BOOL(NSURLRequest *request, NSURLComponents *components) {
return [components.path hasSuffix:@"/login"];
}];
// Add Successful response
[responseSet addResponseWithName:@"Success"
file:MMPathForFileInMainBundleDirectory(@"login.success.json", @"LocalServer")
statusCode:200
contentType:@"application/json"];
// Add Invalid Credentials response
[responseSet addResponseWithName:@"Invalid Credentials"
file:MMPathForFileInMainBundleDirectory(@"login.invalid.json", @"LocalServer")
statusCode:401
contentType:@"application/json"];
// Add No Network Connection response
[responseSet addResponseWithName:@"Offline"
error:[NSError errorWithDomain:NSURLErrorDomain
code:NSURLErrorNotConnectedToInternet
userInfo:nil]];
// Register the response set
[MMBarricade registerResponseSet:responseSet];
默认情况下,响应集中添加的第一个响应将用于响应对。但是,所选响应可以通过 Tweaks 接口或程序修改。在两种情况下,创建上述响应时指定的 "name" 参数用于标识所需响应。
[MMBarricade selectResponseForRequest:@"Login" withName:@"Offline"];
Barricade 提供一个内建界面,在其运行时允许选择网络响应。
呈现选择 UI 有两种方法
UIWindow
替换为 MMBarricadeShakeWindow
的一个实例。如果你使用场景图,请覆盖应用代理中的 - window
- (UIWindow *)window {
if (!_window) {
_window = [[MMBarricadeShakeWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
}
return _window;
}
注意:默认情况下,震动窗口仅在调试构建中呈现。您可以覆盖 MMBARRICADE_SHAKE_ENABLED
宏以调整此行为。
MMBarricadeViewController
,只需确保将其限制为调试构建,如果您不希望将其发布到应用商店。如果你在教育 Facebook Tweaks 中的应用,你可以使用 Barricade 的 Tweaks subspec 将内建选择界面集成到 Tweaks 中。
pod 'MMBarricade/Tweaks', '~> 1.0.0'
您需要做出的唯一其他更改是使用 tweaks 响应库而不是内存中的响应库来设置拦路墩
#import "MMBarricade+Tweaks.h"
...
[MMBarricade setupWithTweaksResponseStore];
[MMBarricade enable];
MMBarricade 可以安全地包含在应用商店构建中(可能用于支持您应用的演示模式),但大多数时候你可能希望确保拦路墩在应用商店构建中被禁用。这里有一些方法
条件启用
在你的应用中,你可以用宏包装创建拦路墩的操作,以限制代码执行到特定的构建配置。例如
#if DEBUG
[MMBarricade enable];
#endif
通过 CocoaPods 禁用
当通过 CocoaPods 安装时,您可以指定特定的构建配置来限制库的安装。例如:
pod 'MMBarricade', '~> 1.0.0', :configurations => ['Debug']
或者,如果您只是将库用于单元测试,可能希望只将库与您的测试目标链接。
target 'Tests', :exclusive => true do
pod 'MMBarricade', '~> 1.0.0'
end
配置由两个步骤组成
在可以使用之前,必须配置一个 <MMBarricadeResponseStore>
的实例。要使用所包含的响应存储之一,您可以
[MMBarricade setupWithTweaksResponseStore];
-or-
[MMBarricade setupWithInMemoryResponseStore];
一旦为障碍设置好备用存储,它就应该启用。因为障碍作为 NSURLProtocol 子类工作,所以启用它的方法取决于您在应用程序中将如何进行网络请求。
NSURLConnection
对于基于较旧的 NSURLConnection 风格的网络请求,只需调用 [MMBarricade enable]
即可为您注册 NSURLProtocol。
NSURLSession
对于基于较新的 NSURLSession API 的网络请求,您有两个选项
如果您使用 [NSURLSession sharedSession]
,则可以使用 [MMBarricade enable]
启用。
如果您正在创建一个自定义会话,例如使用 [NSURLSession sessionWithConfiguration:configuration]
,那么您应该在创建会话之前,使用您的自定义会话配置启用障碍。
NSURLSessionConfiguration *configuration = [self myCustomSessionConfiguration];
[MMBarricade enableForSessionConfiguration:configuration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration];
...
障碍在请求时返回的响应是指定在请求的 MMBarricadeResponseSet
中的“当前响应”。除了通过调整 UI 更新当前响应外,响应也可以通过编程方式更新。
[MMBarricade selectResponseForRequest:@"login" withName:@"offline"];
MMBarricade 需要 iOS 7.0 或更高版本。
MMBarricade 由 John McIntosh 在 Mutual Mobile 创建。
还要感谢 Justin Kolb 创造了运行时可调的网络响应概念,以及 Conrad Stoll 的反馈。
MMBarricade 在 MIT 许可证下提供。有关更多信息,请参阅 LICENSE 文件。