3

AFNetworking 2.0以前のバージョンをしばらく使用していた新しい API を使い始めたところです。ボグスタンダードをやろうとしていますhttp POST requestが、残念ながらうまくいきません。これは私の現在のコードです:

AFHTTPRequestOperationManager *operationManager = [AFHTTPRequestOperationManager manager];

NSDictionary *parameters = @{@"username" : self.usernameField.text,
                             @"password" : self.passwordField.text};

[operationManager POST:@"https:URL GOES HERE" parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
    NSLog(@"JSON: %@", [responseObject description]);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    NSLog(@"Error: %@", error);
}];

現在、これはJSONofを返し(NULL)、ステータス コードのようなものは返されません404(ちなみに、AFN 2.0 を使用している場合、ステータス コードはどのように取得しますか?)。ただし、私のためにテストするapikitchen.comHTTP Post requestのような Web アプリで情報を試すと、フィールドにユーザー名とパスワードを入力すると機能しparamます。本当に私の質問は、Web アプリと同じように行動parametersしないのはなぜですか? そして、より一般的には、なぜ私のために働いていないのですか?AFN 2.0 parameter propertyparameterspost request parametersAFN 2.0

前もって助けてくれてありがとう、
マイク

編集:提案された修正の実装に苦労しています。私の Post メソッドは次のようになりましたが、今のところ意味がありません。

AFHTTPRequestOperationManager *operationManager = [AFHTTPRequestOperationManager manager];
NSDictionary *parameters = @{@"username" : self.usernameField.text,
                             @"password" : self.passwordField.text};

operationManager.requestSerializer.queryStringSerializationWithBlock =
^NSString*(NSURLRequest *request,
           NSDictionary *parameters,
           NSError *__autoreleasing *error) {
    NSString* encodedParams = form_urlencode_HTTP5_Parameters(parameters);
    return encodedParams;
};

[operationManager POST:@"URL HERE" parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
    NSLog(@"JSON: %@", [responseObject description]);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    NSLog(@"Error: %@", error);
}];
4

2 に答える 2

2

現在、これは (NULL) の JSON を返し、404 などのステータス コードは返されません (ちなみに、AFN 2.0 を使用しているときにステータス コードを取得するにはどうすればよいでしょうか?)。

少なくともエラーが発生するはずです。失敗ハンドラは何を出力しますか?

本当に私の質問は、AFN 2.0 パラメーター プロパティのパラメーターが Web アプリのパラメーターと同じように機能しないのはなぜですか? より一般的には、ポスト リクエスト パラメータが AFN 2.0 で機能しないのはなぜですか?

AFN (バージョン 2.0.1) がパラメーターをエンコードする方法を調べたところ、これらが適切にエンコードされていないように見えます: The application/x-www-form-urlencoded encoding algorithm .

これが修正されるまで、次の回避策を試すことができます。次のアルゴリズムは、少なくとも私がテストした Mac OS X 10.8 では、HTTP 5 の w3c で提案されているようにパラメーターを厳密にエンコードします。

static NSString* form_urlencode_HTTP5_String(NSString* s) {
    CFStringRef charactersToLeaveUnescaped = CFSTR(" ");
    CFStringRef legalURLCharactersToBeEscaped = CFSTR("!$&'()+,/:;=?@~");

    NSString *result = CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(
                         kCFAllocatorDefault,
                         (__bridge CFStringRef)s,
                         charactersToLeaveUnescaped,
                         legalURLCharactersToBeEscaped,
                         kCFStringEncodingUTF8));
    return [result stringByReplacingOccurrencesOfString:@" " withString:@"+"];
}

(注: 上記のコードは、 function の実装の詳細に依存しますCFURLCreateStringByAddingPercentEscapes。提案されたアルゴリズムを依存関係なしで簡単に実装することは完全に可能です。これをお勧めします。それほど短くはなりません。)

static NSString* form_urlencode_HTTP5_Parameters(NSDictionary* parameters) 
{
    NSMutableString* result = [[NSMutableString alloc] init];
    BOOL isFirst = YES;
    for (NSString* name in parameters) {
        if (!isFirst) {
            [result appendString:@"&"];
        }
        isFirst = NO;
        assert([name isKindOfClass:[NSString class]]);
        NSString* value = parameters[name];
        assert([value isKindOfClass:[NSString class]]);

        NSString* encodedName = form_urlencode_HTTP5_String(name);
        NSString* encodedValue = form_urlencode_HTTP5_String(value);

        [result appendString:encodedName];
        [result appendString:@"="];
        [result appendString:encodedValue];
    }

    return [result copy];
}

次に、AFN を使用する場合、以下に示すようにシリアル化アルゴリズムをカスタマイズできます。

    AFHTTPRequestOperationManager *operationManager = [AFHTTPRequestOperationManager manager];

    operationManager.requestSerializer.queryStringSerializationWithBlock = 
       ^NSString*(NSURLRequest *request,
                  NSDictionary *parameters,
                  NSError *__autoreleasing *error) {
        NSString* encodedParams = form_urlencode_HTTP5_Parameters(parameters);
        return encodedParams;
    };
于 2013-10-15T14:33:43.667 に答える
0

/URLの後に入れます。私は何時間もそれを逃しました。

于 2014-01-23T13:12:42.033 に答える