6

私はしばらくの間 RestKit 0.10.0 を使用してきましたが、この時点までは、シリアル化されたオブジェクトのみをサーバーに投稿しました。

[[RKObjectManager sharedManager] postObject:serializedObject
                                 usingBlock:^(RKObjectLoader *loader) {
                                     loader.delegate = self;
                                     loader.objectMapping = responseMapping;
                                     loader.serializationMIMEType = RKMIMETypeFormURLEncoded;
                                     loader.targetObject = nil;
                                 }];

ここまでは順調ですね。しかし、いくつかのクエリ パラメータを使用してサーバーに GET リクエストを送信する必要があります。最初に頭に浮かんだ自然なことは、私がオブジェクトを投稿したときと同じことをすることでした:

  • クエリ パラメータをカプセル化するオブジェクトのシリアル化マッピングを作成する
  • サーバーから受信するオブジェクトの応答マッピングを作成する
  • (RKRequestMethodPOST の代わりに) RKRequestMethodGET 用のルーターを定義して使用する
  • (postObject:usingBlock の代わりに) getObject:usingBlock を使用してリクエストを行います。

私はすぐにこれがそれを行う方法ではないことがわかったので、利用可能なリソース ( RestKit WikiRestKit Google グループ) を検索した後、有効と見なされる 2 つの解決策を知っています。

  • クエリ パラメーターをリソース パスに追加します。

これは完全に機能します。

NSDictionary *queryParams = [NSDictionary dictionaryWithObjectsAndKeys:
                                          token, @"accessToken",
                                          [NSNumber numberWithInt:level], @"level",
                                          [NSNumber numberWithInt:count], @"count",
                                          nil];

NSString* resourcePath = [PEER_SUGGESTIONS_CONTROLLER_PATH stringByAppendingQueryParameters:queryParams];

[[RKObjectManager sharedManager] loadObjectsAtResourcePath:resourcePath
                                                usingBlock:^(RKObjectLoader *loader) {
                                                    loader.delegate = self;
                                                    loader.objectMapping = responseMapping;
                                                }];
  • ローダー ブロックでクエリ パラメータを設定します。

これはクエリ パラメータを送信しません。

RKParams *params = [RKParams params];
[params setValue:token forParam:@"accessToken"];
[params setValue:[NSNumber numberWithInt:level] forParam:@"level"];
[params setValue:[NSNumber numberWithInt:count] forParam:@"count"];

[[RKObjectManager sharedManager] loadObjectsAtResourcePath:PEER_SUGGESTIONS_CONTROLLER_PATH
                                                usingBlock:^(RKObjectLoader *loader) {
                                                    loader.delegate = self;
                                                    loader.objectMapping = responseMapping;
                                                    loader.params = params;
                                                }];

私の質問は次のとおりです。

  1. 2 番目のソリューションが機能しないのはなぜですか?
  2. JSON 応答にルート キー パスがないにもかかわらず、最初のソリューションが loader.targetObject を nil に設定しなくても機能するのはなぜですか?
  3. getObject:usingBlock メソッドを使用する必要があるのはどのような場合ですか? その意図された目的は何ですか?
  4. loader.params は何に使用すればよいですか? ウィキのオブジェクト マッピング チュートリアルでは、このプロパティを使用して POST パラメーターをカプセル化できると述べていますが、メソッド postObject:usingBlock で送信されるシリアル化されたオブジェクトにパラメーターをラップできるため、ポイントがわかりません。

ありがとう。

[後で編集]

2 番目の質問への回答について: POST リクエストを作成するときに、ローダー ブロックで targetObject を nil に設定しています。そうしないと、RestKit が応答に send オブジェクト マッピングを使用しようとするためです (関連する議論については、このリンクを確認してください)。しかし、loadObjectsAtResourcePath:usingBlock: を使用しているため、送信されるオブジェクトがないため、targetObject を nil に設定しなくても、応答は応答マッピングに自然にマッピングされます。

4

2 に答える 2

4
  1. 2 番目のソリューションが機能しないのはなぜですか?

params は、GET/HEAD リクエストでは使用されない HTTP 本文を作成するために使用されます。

  1. JSON 応答にルート キー パスがないにもかかわらず、最初のソリューションが loader.targetObject を nil に設定しなくても機能するのはなぜですか?

targetObject はデフォルトでは nil だと思います。通常は設定しません。必要に応じてリクエストによって作成されます。私がそれを使用するのは、主キーまたはその他の奇妙な問題のないオブジェクトを要求するときだけです。

  1. getObject:usingBlock メソッドを使用する必要があるのはどのような場合ですか? その意図された目的は何ですか?

これは便利な方法なので、正しい構文をすべて覚える必要はありません。内部的には、GET を使用してオブジェクト ロード リクエストを送信するだけです。

編集:

更新したいオブジェクトがある場合に使用します。

  1. loader.params は何に使用すればよいですか? ウィキのオブジェクト マッピング チュートリアルでは、このプロパティを使用して POST パラメーターをカプセル化できると述べていますが、メソッド postObject:usingBlock で送信されるシリアル化されたオブジェクトにパラメーターをラップできるため、ポイントがわかりません。

params に入力したものはすべて、HTTP 本文 (または本文ストリーム) にシリアル化されます。繰り返しますが、postObject:usingBlock: は単なる便利なメソッドなので、すべてを覚える必要はありません。

RestKit はオープンソースです。それがどのように機能するかわからない場合は、内部でパラメーターを自由にフォローできます。アプリと Web サービスが適切に設計されている場合は、便利なメソッドを使用できるはずです。できない場合もありますが、以前のように未加工のフォームを使用できます。

編集: Q うーん、あなたの箇条書きを引用すると数字が台無しになります...

于 2012-06-27T20:16:22.760 に答える
3

カテゴリをRKObjectLoaderに追加することを解決しました。つまり、次のとおりです。

メソッド用

-(void)getObject:(id<NSObject>)object usingBlock:(RKObjectLoaderBlock)block;

変更されたメソッドをカテゴリに追加しました。

-(void)getObject:(id<NSObject>)object queryParameters:(NSDictionary*)queryParameters usingBlock:(void(^)(RKObjectLoader *))block;

これは、リストされた fpr ファイル「RKObjectManager+QueryParameters」です。

//
//  RKObjectManager+QueryParameters.h
//  AlphaClient
//
//  Created by Antonio Rossi on 14/07/12.
//

#import <RestKit/RestKit.h>

@interface RKObjectManager (QueryParameters)

- (void)getObject:(id<NSObject>)object queryParameters:(NSDictionary*)queryParameters usingBlock:(void(^)(RKObjectLoader *))block;
- (void)sendObject:(id<NSObject>)object queryParameters:(NSDictionary*)queryParameters method:(RKRequestMethod)method usingBlock:(void(^)(RKObjectLoader *))block;

@end

ファイル「RKObjectManager+QueryParameters.m」のリストは次のとおりです。

//
//  RKObjectManager+QueryParameters.m
//  AlphaClient
//
//  Created by Antonio Rossi on 14/07/12.
//

#import "RKObjectManager+QueryParameters.h"

@implementation RKObjectManager (QueryParameters)

- (void)getObject:(id<NSObject>)object queryParameters:(NSDictionary*)queryParameters usingBlock:(void(^)(RKObjectLoader *loader))block {
    [self sendObject:object queryParameters:queryParameters method:RKRequestMethodGET usingBlock:block];
}

- (void)sendObject:(id<NSObject>)object queryParameters:(NSDictionary*)queryParameters method:(RKRequestMethod)method usingBlock:(void(^)(RKObjectLoader *))block {
    NSString *resourcePath = [self.router resourcePathForObject:object method:method];
    [self sendObject:object toResourcePath:resourcePath usingBlock:^(RKObjectLoader *loader) {
        loader.method = method;

        // need to transform the original URL because when method is GET the additional paramentes don't get added
        RKURL *originalBaseURL = [RKURL URLWithBaseURL:[loader.URL baseURL]];
        NSString *resourcePath = [self.router resourcePathForObject:object method:RKRequestMethodGET];
        RKURL *authTokenURL = [originalBaseURL URLByAppendingResourcePath:resourcePath queryParameters:queryParameters];
        [loader setURL:authTokenURL];

        block(loader);
    }];
}

@end

#import "RKObjectManager+QueryParameters.h"もう 1 つのステップは、実装ファイルを追加することです。この新しいメソッドではrouter、呼び出しを行う前に RKObjectManager のプロパティが定義されていると想定されています。

于 2012-07-14T13:31:50.310 に答える