iOS——格式化简单的HTTP POST

本文介绍如何在Cocoa环境下实现一个用于POST请求的自定义请求类,包括设置URL、参数字典和HTTP头,以及如何通过扩展NSString类进行字符转义处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

为了实现POST请求,我们写一个NSMutableURLRequest的子类,XYFormEncodedPOSTRequest,他支持POST方式中用到的参数字典。

XYFormEncodedPOSTRequest.h:

#import <Foundation/Foundation.h>

@interface XYFormEncodedPOSTRequest : NSMutableURLRequest

+ (id)requestWithURL:(NSURL *)url formParameters:(NSDictionary *)params;
- (id)initWithURL:(NSURL *)url formParameters:(NSDictionary *)params;

- (void)setFormParameters:(NSDictionary *)params;

@end

XYFormEncodedPOSTRequest.m:

#import "XYFormEncodedPOSTRequest.h"
#import "NSString+XYURLAdditions.h"

@implementation XYFormEncodedPOSTRequest

+ (id)requestWithURL:(NSURL *)url formParameters:(NSDictionary *)params{
    return [[self alloc] initWithURL:url formParameters:params];
}

- (id)initWithURL:(NSURL *)url formParameters:(NSDictionary *)params{
    if (self = [super initWithURL:url]) {
        [self setHTTPMethod:@"POST"];
        [self setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
        [self setFormParameters:params];
    }
    return self;
}

- (void)setFormParameters:(NSDictionary *)params{
    NSStringEncoding enc = NSUTF8StringEncoding;
    NSMutableString *postBody = [NSMutableString string];
    for (NSString *paramKey in params) {
        if ([paramKey length] > 0) {
            NSString *value = [params objectForKey:paramKey];
            NSString *encodeValue = [value URLEncodedFormStringUsingEncoding:enc];
            NSUInteger length = [postBody length];
            NSString *paramFormat = (length == 0? @"%@=%@" : @"&%@=%@");
            [postBody appendFormat:paramFormat, paramKey,encodeValue];
        }
    }
    
    NSLog(@"postBody is now %@", postBody);
    [self setHTTPBody:[postBody dataUsingEncoding:enc]];
}

@end
表单参数看上去和URL查询字符串差不多,但是要把它们放到http正文中,而不是加到URL中,所以,假如提交包含名字和年龄的表单,编写好的正文字符长因该向下面这样:name-Lucas+Drance&age=1.5.
每个参数的名字与值之间用等号(=)连接,然后把这些参数用and(&)连接起来。

因此,若给定一组名称值对,我们的cocoa代码需要像先前说明的那样把它们连接在一块,这就是-setFormetters:所做的事情,他是用NSString的扩展来处理所有的字符转义。

标准的-[NSString stringByAddingPercentEscapesUsingEncoding:]方法可以把接受器转换成合法的URL字符串。但是如果用户输入中包含了保留字符(+,&,=),他会不做任何处理。我们需要自己转义。
NSString+XYURLAdditions.h:

#import <Foundation/Foundation.h>

@interface NSString (XYURLAdditions)

- (NSString *)URLEncodedFormStringUsingEncoding:(NSStringEncoding)enc;
- (NSString *)percentEscapedStringWithEncoding:(NSStringEncoding)enc additionalCharacters:(NSString *)add ignoredCharacters:(NSString *)ignore;
@end
如果先替换空白字符,那么转义处理将对所有加号做转义;我们只是想对用户输入做转义,所以在最后一步替换空白字符。
NSString+XYURLAdditions.m:
#import "NSString+XYURLAdditions.h"

@implementation NSString (XYURLAdditions)

- (NSString *)URLEncodedFormStringUsingEncoding:(NSStringEncoding)enc{
    NSString *escapedStringWithSpaces = [self percentEscapedStringWithEncoding:enc additionalCharacters:@"&=+" ignoredCharacters:nil];
    return escapedStringWithSpaces;
}

- (NSString *)percentEscapedStringWithEncoding:(NSStringEncoding)enc additionalCharacters:(NSString *)add ignoredCharacters:(NSString *)ignore{
    
    CFStringEncoding convertedEncoding = CFStringConvertNSStringEncodingToEncoding(enc);
    return (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)self, (CFStringRef)ignore, (CFStringRef)add, convertedEncoding));
}

@end
字符串转换由第二个方法完成,他有两组字符参数:一组是该被转义的(即保留字符),一组是不应该转义的。使用Core Fundation中CFURLCreateStringByAddingPercentEscpes的调用会执行所需的特殊替换。

源代码:连接地址

转载于:https://my.oschina.net/orangef/blog/135146

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值