sos の 作業メモ

プログラミングや英会話学習、マイルや旅行、日常生活など。最近はWebFormなASP.NETのお守りがお仕事です。

日々の生活にhappyをプラスする|ハピタス Gポイント

HTTPでPOST その1 Request組み立て

HTTPでPOSTするにはNSURLConnectionを使うのだけれど、実際にはNSURLRequestを組み立てる必要があります。

URL Encoding

URLパラメータはURL EncodingしてUSASCIIだけにしないといけないんだけど、NSStringのurlEncodingは仕様上の欠陥があるので代替メソッドを用意。(ここではUTF-8決めうちで実装してます)

+ (NSString*)urlEncodingByUTF8:(NSString*)text
{
    CFStringRef escaped =
        CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
                                            (__bridge CFStringRef)text,
                                            (__bridge CFStringRef)@" ",
                                            (__bridge CFStringRef)@"!*'();:@&=+$,/?%#[]",
                                            kCFStringEncodingUTF8);
    NSMutableString* ret = [NSMutableString stringWithString:(__bridge NSString*)escaped];
    [ret replaceOccurrencesOfString:@" " withString:@"+" options:0 range:NSMakeRange(0, [ret length])];
    CFRelease(escaped);
    return ret;
}

最初のCFURLCreateString〜で、@" "を変換しないようにしているのは、後で'+'に変換するためです。

NSURLRequest

リクエストの本体

HTTPMethodと、Content-Type: application/application/x-www-form-urlencoded,と Bodyの設定が必要。

// POSTのHTTP Requestを作成する
+ (NSURLRequest*)createHttpPostRequest:(NSURL*)url withParams:(NSDictionary*)params timeoutInterval:(NSTimeInterval)timeout
{
    NSMutableString* bodytext = [NSMutableString string];
    for(NSString* key in params){
        NSString* rawValue = [params objectForKey:key];
        if(rawValue){
            NSString* encodedValue = [NetTool urlEncodingByUTF8:rawValue];
            [bodytext appendFormat:@"%@=%@&",key,encodedValue];
        }
    }
    if([bodytext length] > 0){
        [bodytext deleteCharactersInRange:NSMakeRange([bodytext length] - 1,1)];    //  末尾の&を削除
    }
    NSData* body = [bodytext dataUsingEncoding:NSUTF8StringEncoding];   // Body文字列からDataを生成

    // Requestを組み立てる
    NSMutableURLRequest* req = [[NSMutableURLRequest alloc] initWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:timeout];

    [req setHTTPMethod:@"POST"];

    // setValue:forHTTPHeaderField:で任意のヘッダを追加できる
    [req setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
    [req setValue:[NSString stringWithFormat:@"%d", [body length]] forHTTPHeaderField:@"Content-Length"];
    [req setHTTPBody:body];
    [req setHTTPShouldHandleCookies:YES];

    return req;
}

その2へ続く