在ObjC中设计基于块的API时,哪种方法更好,一个或两个完成块,一个是成功还是失败?
假设我们有一个方法以异步方式检索某个块,其中一个完成块将是:
- (void) retrieveSomethingCompletion:(void (^)(id retrievedObject, NSError *error))completionBlock;
Run Code Online (Sandbox Code Playgroud)
并且有成功/失败块(AFNetworking样式):
- (void) retrieveSomethingSuccess:(void(^)(id retrievedObject))successBlock failure:(void(^)(NSError *error))failureBlock;
Run Code Online (Sandbox Code Playgroud)
我总是使用第二种方法,但每种方案的优缺点是什么?你通常使用什么,为什么?
我正在GET请求检索JSON数据,AFNetworking如下面的代码:
NSURL *url = [NSURL URLWithString:K_THINKERBELL_SERVER_URL];
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:url];
Account *ac = [[Account alloc]init];
NSMutableURLRequest *request = [httpClient requestWithMethod:@"GET" path:[NSString stringWithFormat:@"/user/%@/event/%@",ac.uid,eventID] parameters:nil];
AFHTTPRequestOperation *operation = [httpClient HTTPRequestOperationWithRequest:request
success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSError *error = nil;
NSDictionary *JSON = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingAllowFragments error:&error];
if (error) {
}
[self.delegate NextMeetingFound:[[Meeting alloc]init] meetingData:JSON];
}
failure:^(AFHTTPRequestOperation *operation, NSError *error){
}];
[httpClient enqueueHTTPRequestOperation:operation];
Run Code Online (Sandbox Code Playgroud)
问题是我想基于这些数据创建单元测试,但我不希望测试实际上会发出请求.我希望预定义的结构将作为响应返回.我是一个新的单元测试,并戳了一点,OCMock但无法弄清楚如何管理这个.
我正在使用XCTestExpectation测试异步调用.
在给定的1秒超时之前执行completionHandler时,以下代码有效(测试成功).
func test__async_call() {
// prepare
let sut = ClassToTest()
let expectation: XCTestExpectation = self.expectationWithDescription(nil)
// test
sut.methodToTestWithCompletionHandler() { () -> () in
expectation.fulfill()
}
// verify
self.waitForExpectationsWithTimeout(1, handler: nil)
}
Run Code Online (Sandbox Code Playgroud)
但是,如果没有调用completionHandler,因此没有满足期望,而是在调用waitForExpectationsWithTimeout时没有得到测试失败,我得到一个EXC_BAD_ACCESS,这不是很方便,因为这使得无法看到整个测试套件的结果.
如何避免这种情况并获得正常的测试失败?
当我想在一个方法中验证模拟对象是否按特定顺序接收某些消息时,我会执行以下操作:
// sut is an instance of the class I am testing and myMock is a mock object injected in sut.
// I want to test that myMock sends messageA and then messageB, in that particular order.
[[[myMock expect] andDo:^(NSInvocation *invocation)
{
[[myMock expect] messageB];
}]
messageA];
[sut methodToTest];
[myMock verify];
Run Code Online (Sandbox Code Playgroud)
有没有更干净/更好的方法呢?提前致谢.
给出以下JSON:
{
"someKey":"someValue",
"otherKey":"otherValue",
"features":[
"feature1",
"feature2",
"feature3"
]
}
Run Code Online (Sandbox Code Playgroud)
我将这个JSON映射到NSManagedObject带有RKMapperOperation和的s RKEntityMapping(在这个例子中我将有2个实体映射:一个用于顶级对象,另一个用于我的Feature类).
顶级对象映射是微不足道的:两个属性映射加上与Feature关系的一个(特征)关系.
我的问题是,如何将功能JSON数组映射到Feature对象数组?Feature类只有一个属性name where I want to store "feature1", "feature2", etc plus a reference to the parent object (the top level one). Something like this:
@interface Feature : NSManagedObject
//In the implementation file both properties are declared with @dynamic.
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) MyTopLevelObject *myTopLevelObject;
@end
Run Code Online (Sandbox Code Playgroud)
任何的想法?
我想通过指定范围来查询sqllite表.所以这就像给我所有id列在3000到3010之间的记录.
我尝试了Apple推荐的产品,但它没有用.这是我尝试过但失败了.
NSPredicate *betweenPredicate =
[NSPredicate predicateWithFormat: @"attributeName BETWEEN %@", @[@1, @10]];
Run Code Online (Sandbox Code Playgroud)
我有两个名为start和end的字符串.我更新了Apple的示例如下.
NSPredicate *betweenPredicate =
[NSPredicate predicateWithFormat: @"%@ BETWEEN %@", columnName, @[start,end]];
Run Code Online (Sandbox Code Playgroud)
当我使用上面的谓词执行executeRequest时,我得到0条记录,即使该表具有与谓词匹配的记录.有人能说出错的地方吗?
ios ×5
objective-c ×2
ocmock ×2
unit-testing ×2
afnetworking ×1
api ×1
core-data ×1
nspredicate ×1
restkit ×1
restkit-0.20 ×1
sqlite ×1
swift ×1
xcode ×1
xctest ×1