我正在为一个 iOS 项目编写一个带有 AFNetworking 的 REST API 层。我对到目前为止所写的内容有一些疑问,所以我转向 stackoverflow 寻求一些指导/答案。
以下是我想要实现的指导方针:
- 一个基类(DRAPI:AFHTTPClient),它将初始化一个单例客户端,就像 AFHTTPClient 的 cocoadocs 推荐的那样。
- DRAPI 的“基础”委托:DRAPIDelegate,它包含以统一格式显示错误的方法。
- 处理我的 REST API 的某些路由的 DRAPI 子类。例如,对用户的 CRUD 操作是 DRUserAPI 的责任,它是 DRAPI 的子类。
- DRAPI 的每个子类都有自己的委托。对于 DRUserAPI,有 DRUserAPIDelegate,它扩展了 DRAPIDelegate。
这是到目前为止如何编写的一个简单示例:
DRAPI.h
@interface DRAPI : AFHTTPClient
- (void) apiGetCallWithRoute:(NSString*)route
parameters:(NSDictionary*)parameters
onSuccess:(void(^)(id))successBlock
onError:(void(^)(NSArray* errors))errorBlock;
@end
@protocol DRAPIDelegate <NSObject>
-(void) DRAPIErrorFromServer:(NSArray*)errors;
@end
DRAPI.m
@implementation DRAPI
+(DRAPI*) sharedClient
{
static DRAPI *aSharedClient = nil;
static dispatch_once_t onceToken;
dispatch_once(&once_token, ^{
_sharedClient = [DRAPI alloc] initWithBaseURL:[NSURL URLWithString:@"http://127.0.0.1:3000/api"];
});
return aSharedClient;
}
-(id) initWithBaseURL:(NSURL *)url
{
self = [super initWithBaseURL:url];
if (self) {
// configuration goes here... skipping because it is not important.
}
return self;
}
#pragma mark - Helper methods for Server Calls
- (void) apiGetCallWithRoute:(NSString*)route
parameters:(NSDictionary*)parameters
onSuccess:(void(^)(id))successBlock
onError:(void(^)(NSArray* errors))errorBlock
{
[[DRAPI sharedClient] getPath:route
parameters:addAuthenticationParametersTo(parameters)
success:^(AFHTTPRequestOperation *operation, id responseObject) {
successBlock(responseObject);
}
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
errorBlock( processError() );
}];
}
@end
DRUserAPI.h
@interface DRUserAPI: DRAPI
@property (weak, nonatomic) id<DRUserAPIDelegate>delegate;
+(DRUserAPI*) APIWithDelegate:(id<DRUserAPIDelegate>)delegate;
-(void) createUser:(NSString*)username password:(NSString*)password;
// ... more methods would be declared here...
@end
@protocol DRUserAPIDelegate <NSObject, DRAPIDelegate>
-(void) DRUserAPIOnUserCreated:(MyUserModel*)newUser;
// more delegate methods would be here...
@end
DRUserAPI.m
@implementation DRUserAPI
@synthesize delegate;
+(DRUserAPI*) APIWithDelegate:(id<DRUserAPIDelegate>)delegate
{
DRUserAPI * client = [DRUserAPI new];
client.delegate = delegate;
return client;
}
-(void) createUser:(NSString*)username password:(NSString*)password
{
[self apiGetCallWithRoute:@"users/create"
parameters:@{@"username" : username, @"password": password}
onSuccess:^(id response) {
NSDictionary *parsedJSON = response;
[delegate DRUserAPIOnUserCreated:[MyUserModel newModelFromDictionary:parsedJSON];
}
onError:^(NSArray *errors) {
[delegate DRAPIErrorFromServer:errors];
}];
}
@end
一位同事引起我的注意,代表和单身人士不能混为一谈。不过,我仍然想管理代表。我认为好的解决方案是将委托的单例实例传递给我在 API 子类中调用的方法。
这是一个好主意吗?
谢谢!