13

私はRestKitをテストしており、異なるBaseUrlにアクセスする必要があり、時には異なる場所から同じbaseUrlを持つWebサービスに「一度に」アクセスする必要があります。最後に、同じコントローラー内の異なるressourcePathを持つ同じbaseUrlにもアクセスする必要があります。

私のアプリ デリゲートでは、このように RKObjectManager シングルトンをセットアップしました。

RKObjectManager *objectManager = [RKObjectManager objectManagerWithBaseURL:kBaseUrl];
[objectManager registerClass:[EntityClass1 class] forElementNamed:@"element1"];
[objectManager registerClass:[EntityClass2 class] forElementNamed:@"element2"];
.
.
.
etc.

シングルトン アプローチは非常に簡単に操作できますが、さまざまな Web サービス呼び出しを分離する方法がわかりません。

RKObjectLoaderDelegate を実装する MyViewController には、次の 2 つのメソッドがあります。

- (void)objectLoader:(RKObjectLoader *)objectLoader didLoadObjects:(NSArray *)objects         {
    //stuff with result
}

- (void)objectLoader:(RKObjectLoader *)objectLoader didFailWithError:(NSError *)error {
    //stuff with error    
}

MyViewController が 1 つの RKObjectManager シングルトンを使用して 1 つの baseUrl を持つ 1 つの ressourcePath にアクセスする場合、これは問題を引き起こしません。

この方法で別のリクエストを開始した場合:

[[RKObjectManager sharedManager] loadObjectsAtResourcePath:FLICKRPath delegate:self]
[[RKObjectManager sharedManager] loadObjectsAtResourcePath:FOURSQUAREPath delegate:self]

など、同じ MyController 内で、FLICKRPath と FOURSQUAREPath にはもちろん異なる baseUrl がありますが、RKObjectManager には 1 つしかないという問題がありますか?

これが機能し、異なる RKObjectManagers を持つことができる場合、別の問題が発生します。デリゲート メソッドの didLoadObjects と didFailWithError は両方の RKObjectManagers から結果を受け取りますが、baseUrls 以外にそれらを区別する方法はありません。デリゲート メソッドで各戻り値を baseUrl と比較する可能性があり、さらに悪いことに ressourcePath と比較することは、私にはまったく魅力的ではありません。

異なる RKObjectManagers がある場合、それらに異なるデリゲートを渡し、異なる baseUrls と ressourcePaths からの戻り値を処理する専用のクラスを構築できると思います。これは、MyController と RestKit の上にさらに別の抽象化を構築する必要があったことを意味しますが、これも面倒です。

私はこれを間違った方法で行っていると強く感じています.RestKitソースは非常に印象的で、私がフレームワークと戦っていることを示しています. この件に関するベストプラクティスの洞察をいただければ幸いです。見つけたすべてのリソースと例を確認しましたが、上記の使用例は見たことがありません。常に 1 つの RKObjectManager、1 つの baseUrl、および 1 つの ressourcePath です。

前もって感謝します。

4

5 に答える 5

10

受け入れられた答えがまだないため、複数のオブジェクト マネージャーを使用することは、 を使用して非常に簡単RestKitです。

Wikiから( Using Multiple Base URLs (and Multiple Object Managers ):

最初に作成するオブジェクト マネージャは、デフォルトで RestKit が使用する共有シングルトンになります。ただし、追加のオブジェクト マネージャーを作成することで、必要に応じて BaseURL からプルできます。ただし、これらの新しいマネージャーは必ず保持してください。

RKObjectManager *flickrManager = 
    [RKObjectManager objectManagerWithBaseURL:flickrBaseUrl]; // <-- shared singleton
RKObjectManager *foursquareManager = 
    [[RKObjectManager objectManagerWithBaseURL:foursquareBaseUrl] retain]; // <-- you must retain every other instance.

アプリケーションによっては、必要に応じて簡単にプルできるように、この 2 番目のオブジェクト マネージャーをよりアクセスしやすい場所 (AppDelegate の保持プロパティなど) に配置することをお勧めします。2 つ (またはそれ以上) のオブジェクト マネージャーからの結果を区別する必要がある場合は、クエリの userData に識別子を設定するだけです。

- (void)someAction(id)sender {
        // .......
        RKObjectLoader* loader = [[RKObjectManager sharedManager] loadObjectsAtResourcePath:@"/whatever" delegate:self];
        loader.userData = @"foursquare";
        // or do this, if you need a number instead of a string
        loader.userData = [NSNumber numberWithInt:1234];
        // .......
    }

//Then when the delegate comes back you can cast it into a string or number as appropriate:
- (void)objectLoader:(RKObjectLoader*)objectLoader didLoadObjects:(NSArray*)objects {
    // .......
    NSString* source = (NSString*) objectLoader.userData;
    // or, if you did the NSNumber instead:
    NSNumber* source = (NSNumber*) objectLoader.userData;
    // .......
}
于 2011-11-07T08:39:06.780 に答える
3

APIの変更:

RKObjectLoader* loader = [[RKObjectManager sharedManager] loadObjectsAtResourcePath:@"/whatever" delegate:self];

RestKit v.0.10.3ではコンパイルされません(loadObjectsAtResourcePath:delegate:voidを返します)。ただし、このメソッドは数行のコードをラップするだけなので、ローダーにアクセスして、次のようにuserDataを追加できます。

RKObjectLoader *loader = [[RKObjectManager sharedManager] loaderWithResourcePath:resourcePath];
loader.userData = @"SOMEDATA";
loader.delegate = self;
loader.method = RKRequestMethodGET;
[loader send];

(他の新しいユーザーが私と同じ問題に遭遇した場合に備えてメモを追加します)。

于 2012-10-23T14:20:10.017 に答える
0

objectLoader を使用するのはどうですか。マップされたオブジェクト タイプ/クラスを見つけてobjectLoader.objectMapping.objectClass、URL の代わりにそれに基づいて条件を追加します。

-(void)objectLoader:(RKObjectLoader *)objectLoader didLoadObjects:(NSArray *)objects {
    // your condition based on -> objectLoader.objectMapping.objectClass   
}

それが役立つことを願っています

于 2012-12-17T12:58:51.473 に答える
0

ちなみに、userData プロパティは RKRequest でも利用できるため、同じアプローチを使用してリクエストの読み込み/識別を行うことができます。

たとえば、いくつかの投稿リクエスト:

RKClient * client = [RKClient sharedClient];
[client post:@"/your-api-path" usingBlock:^(RKRequest *request) {
    request.userData = @"<some-object-you-can-check-in-delegate-callback>";
    request.params = someParamsForRequest;
    request.delegate = <delegate you want to call when request is finished>;
}];
于 2012-08-31T07:31:13.903 に答える