2012-03-22 1 views
3

NSMutableURLRequestのボディにキー値のペアを追加するにはどうすればよいですか?私はこのようなものを使用することができます知っている:NSMutableURLRequestにフィールドを追加する

NSURL *url = [[NSURL alloc] initWithString:@"http://localhost:8080/upload/"]; 
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url]; 
[request setHTTPMethod:@"POST"]; 
NSString *bodyContents = @"fileName="; 
[bodyContents stringByAppendingString:fileName]; 
[bodyContents stringByAppendingString:@"&"]; 
[bodyContents stringByAppendingString:@"deviceName="]; 
[bodyContents stringByAppendingString:deviceName]; 
[bodyContents stringByAppendingString:@"fileContents="]; 
[bodyContents stringByAppendingString:fileContents]; 

しかし、それは私がリクエスト内の値の多くを提出する必要がどこに行く場合は特に、手間の多くのように思えます。私はappleが[request addBodyField:@"fileName":fileName]のようなメソッドを提供するか、それと同等の機能を提供することを願っていますが、ドキュメントで見つけられませんでした。私が行方不明になっている人がいますか?

答えて

5

たくさんの良い回答があります。ここで私がしていることは次のとおりです。ペアリング構文とURLエンコーディングを処理するパラメータクラスを作成しました。

#import "NSString+URLEncoding.h" 

@interface UrlParameter() 

@property (strong, nonatomic) NSString *pair; 
@property (strong, nonatomic) NSString *encodedPair; 

@end 

@implementation UrlParameter 

@synthesize pair = _pair; 
@synthesize encodedPair = _encodedPair; 


+ (UrlParameter *)withName:(NSString *)name value:(NSString *)value { 

    UrlParameter *answer = [[UrlParameter alloc] init]; 
    answer.pair = [NSString stringWithFormat:@"%@=%@", name, value]; 
    answer.encodedPair = [NSString stringWithFormat:@"%@=%@", [name urlEncode], [value urlEncode]]; 

    return answer; // autorelease if non-ARC 
} 

@end 

これは、このNSStringカテゴリメソッドに依存しています。 (また、ARC対応):

// in the interface 
@property (strong, nonatomic) NSMutableArray *parameters; 

- (void)prepareParameters { 

    NSMutableString *encodedParameterPairs = [NSMutableString stringWithCapacity:256]; 

    int position = 1; 
    for (UrlParameter *requestParameter in self.parameters) { 
     [encodedParameterPairs appendString:[requestParameter encodedPair]]; 
     if (position < [self.parameters count]) [encodedParameterPairs appendString:@"&"]; 
     position++; 
    } 

    if ([[self HTTPMethod] isEqualToString:@"GET"] || [[self HTTPMethod] isEqualToString:@"DELETE"]) { 

     NSString *urlString = [NSString stringWithFormat:@"%@?%@", [self URLString], encodedParameterPairs]; 
     [self setURL:[NSURL URLWithString:urlString]]; 

    } else { 

     // POST, PUT 
     NSData *postData = [encodedParameterPairs dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES]; 
     [self setHTTPBody:postData]; 
     [self setValue:[NSString stringWithFormat:@"%d", [postData length]] forHTTPHeaderField:@"Content-Length"]; 
     [self setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"]; 
    } 
} 
+0

本質的に私が何をしているか – nick

3

私は+ stringWithFormatをお勧めします。

EDIT:そうのように:

NSURL *url = [[NSURL alloc] initWithString:@"http://localhost:8080/upload/"]; 
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url]; 
[request setHTTPMethod:@"POST"]; 
NSString *bodyContents = [NSString stringWithFormat:@"fileName=%@%@%@%@%@%@",fileName, @"&",@"deviceName=",deviceName,@"fileContents=",fileContents]; 

私はどんなNSMutableRequestsを使用する必要がありましたが、あなたは(\ nは改行\]タブのためのtの場合)、または句読点文字列リテラルが必要な場合は、必要に応じて、ちょうどそれらを入れていません各%@の間。

+0

ので、すでにありません方法はありません。

@implementation NSString (URLEncoding) - (NSString *)urlEncodeUsingEncoding:(CFStringEncoding)encoding { return CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (__bridge CFStringRef)self, NULL, CFSTR("!*'();:@&=+$,/?%#[]"), encoding)); } - (NSString *)urlEncode { return [self urlEncodeUsingEncoding:kCFStringEncodingUTF8]; } @end 

私もそれが開始する前に、それはこの行い、その後、URLリクエストをサブクラス化し、それをパラメータの可変配列を与えます私のためにそれを追加するには? – nick

+0

私は '[setValue:@" string "forHTTPHeaderField:@" string "];'と言っていますが、これはあなたが達成しようとしているとは思われません.... – CodaFi

+0

@CodaFi - 実際には3つのパラメータしかないので、 'NSString * bodyContents = [NSString stringWithFormat ...'私の答えを見てください。 – sch

0

文字列を使用する必要があります。ところで

、あなたの文字列がNSMutableStringはないので、あなたもbodyContents = [bodyContents string...

stringWithFormatを持っていない限り、これらのstringByAppendingString:方法は、実際には何もしません最良の方法である:

また
NSString *bodyContents = [NSString stringWithFormat:@"fileName:%@&deviceName=%@&fileContents=%@", fileName, deviceName, fileContents"]; 

、そのキーに基づいているキーのNSArrayとNSDictionary(値を保持する)を持つことができます。 NSArrayをループして文字列を作成します。

5

問題は、stringByAppendingStringは文字列を変更しませんが、結果を含む新しい文字列を返します。ただし、stringByAppendingStringの結果を任意の変数に代入するのではなく、bodyContentsは変更されません。

NSString *bodyContents = [NSString stringWithFormat:@"fileName=%@&deviceName=%@fileContents=%@", fileName, deviceName, fileContents]; 

または変更可能な文字列としてstringWithFormatを宣言し、この方法appendString使用します:

それを解決するために、あなたはstringWithFormatを使用することができますいずれか

NSMutableString *bodyContents = @"fileName="; 
[bodyContents appendString:fileName]; 
[bodyContents appendString:@"&"]; 
// ... 

するか、でbodyContentsstringWithFormatの結果を割り当てます毎コール:

NSString *bodyContents = @"fileName="; 
bodyContents = [bodyContents stringByAppendingString:fileName]; 
bodyContents = [bodyContents stringByAppendingString:@"&"]; 
// ... 
1

一言で言えば、NSDataのに

NSString *bodyString = [NSString stringWithFormat:@"fileName=%@&deviceName=%@&[email protected]%", fileName, deviceName, fileContents]; 

フォーマット:文字列を作成します

NSData *body = [bodyString dataUsingEncoding:NSUTF8StringEncoding]; 

は、要求に身体を追加:

[request setHTTPBody:body]; 

注:bodyStringの形式はPOSTに依存しますあなたの要求の形式:application/x-www-form-urlencodedまたはmultipart/form-datamultipart/form-dataを使用する場合、この形式はサーバーによって受け入れられない可能性があります。

関連する問題