0

iOS プロジェクト用に AFNetworking を使用して REST API レイヤーを作成しています。これまでに書いたことについていくつか質問があるので、ガイダンス/回答を得るためにスタックオーバーフローに目を向けています。

私が達成しようとしていることのガイドラインは次のとおりです。

  • AFHTTPClient の cocoadoc が推奨するように、シングルトン クライアントを初期化する基本クラス (DRAPI : AFHTTPClient)。
  • DRAPI の「ベース」デリゲート: DAPIDelegate。統一された形式でエラーを表示するためのメソッドを保持します。
  • REST API の特定のルートを処理する DRAPI のサブクラス。たとえば、ユーザーに対する CRUD 操作は、DRAPI の子クラスである DRUserAPI の責任です。
  • DRAPI の各サブクラスには、独自のデリゲートがあります。DRUserAPI には、DRAPIDelegate を拡張する DRUserAPIDelegate があります。

これまでの記述方法の簡単な例を次に示します。

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 サブクラス内で呼び出しているメソッドにデリゲートのシングルトン インスタンスを渡すことだと考えています。

これは良い考えですか?

ありがとう!

4

2 に答える 2

0

完璧ではありませんが、機能します。なぜこれほど多くの代議員が?シングルトンの無限ループに移行しているようです。やめた方がいいと思います...

于 2013-09-12T22:06:05.917 に答える