3

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];

しかし、それは非常に面倒なことのように思えます。特に、リクエストで多くの値を送信する必要がある場所に到達した場合はなおさらです。アップルが同様に役立つ方法を提供してくれることを願っ[request addBodyField:@"fileName":fileName]ていますが、ドキュメントで見つけることができませんでした。足りないものはありますか、それとも文字列の追加に固執する必要がありますか?

4

5 に答える 5

5

問題は、そのstringByAppendingString場で文字列を変更せず、結果を含む新しい文字列を返すことです。ただし、の結果をstringByAppendingString変数に割り当てることはなく、bodyContents変更されません。

これを解決するには、次のいずれかを使用できますstringWithFormat

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

stringWithFormatまたは、可変文字列として宣言し、次のメソッドを使用しappendStringます。

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

または、すべての呼び出しでの結果をstringWithFormatに割り当てます。bodyContents

NSString *bodyContents = @"fileName=";
bodyContents = [bodyContents stringByAppendingString:fileName];
bodyContents = [bodyContents stringByAppendingString:@"&"];
// ...
于 2012-03-22T21:57:16.007 に答える
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対応):

@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リクエストをサブクラス化し、可変のパラメーター配列を指定すると、開始する前に次のようになります。

// 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"];
    }
}
于 2012-03-22T23:27:38.003 に答える
3

+stringWithFormatをお勧めします。

編集:そのように:

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)または句読点が必要な場合は、必要に応じて各%@の間に配置してください。

于 2012-03-22T21:52:43.733 に答える
1

一言で言えば。文字列を作成します。

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

NSDataへのフォーマット:

NSData *body = [bodyString dataUsingEncoding:NSUTF8StringEncoding];

リクエストに本文を追加します。

[request setHTTPBody:body];

注:の形式bodyStringは、リクエストのPOST形式によって異なります:application/x-www-form-urlencodedまたはmultipart/form-data。使用する場合multipart/form-data-この形式はサーバーで受け入れられない可能性があります。

于 2012-03-22T22:25:15.687 に答える
0

文字列を使用する必要があると確信しています。

ちなみに、あなたの文字列はNSMutableStringではないので、これらのstringByAppendingString:メソッドは、あなたが持っていない限り、実際には何もしません。bodyContents = [bodyContents string...

stringWithFormat最良の方法です:

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

または、キーのNSArrayと、そのキーに基づくNSDictionary(値を保持するため)を使用することもできます。次に、NSArrayをループして、文字列を作成します。

于 2012-03-22T21:56:45.850 に答える