编码NSDictionary以通过AFNetworking发送

时间:2015-09-25 19:10:22

标签: ios objective-c afnetworking

我如何 URLEncode 一个NSDictionary,以便我可以通过AFNetworking发送。

代码如下:

NSMutableDictionary *rus = [[NSMutableDictionary alloc] init];
[rus setValue:@"1211" forKey:@"id"];
[rus setValue:@"33" forKey:@"man"];

如何对此NSDictionary进行编码,以便我可以通过AFNetworking发送它?

2 个答案:

答案 0 :(得分:0)

取决于您希望如何发送数据:

1)@" application / json" 在这种情况下你会使用[NSJSONSerialization dataWithJSONObject:参数选项:self.writingOptions错误:错误]

2)@" application / x-www-form-urlencoded" 在这种情况下你基本上想要创建字符串:?id = 1211& man = 33 from your your字典rus。

这里有一些代码,你可能不是最有效率的想法:

 NSString *temp;
    int i=0;

    for(NSString *key in options.params.allKeys)
    {
        NSString *value = [options.params objectForKey:key];
        [parameters setObject:value forKey:key];

        if(i==0)
        {
            temp = [NSString stringWithFormat:@"?%@=%@", key,value];
        }
        else
        {
            temp = [NSString stringWithFormat:@"%@&%@=%@", temp, key, value];
        }
    }

注意:可能与您有关,也可能与您无关,但我的两分钱:

我使用AFHTTPSessionManager来处理包括url编码在内的所有细节,所以我只传入所需的字典:

    NSMutableDictionary *rus = [[NSMutableDictionary alloc] init];
    [rus setValue:@"1211" forKey:@"id"];
    [rus setValue:@"33" forKey:@"man"];

    [self POST:@"/api/place/nearbysearch" parameters:rus success:^(NSURLSessionDataTask *task, id responseObject) {
            NSLog(@"nearbyPlaces: success");
            [self fetchedPlacesData:responseObject block:block];
            if(task != nil && task.originalRequest != nil)
            {
                NSString *url = [task.originalRequest.URL absoluteString];
                [self saveNearbySearchEvent:url params:params];
            }
        } failure:^(NSURLSessionDataTask *task, NSError *error) {
            NSLog(@"nearbyPlaces: error: %@", error);
            block(self, nil, error);
        }];

AFHTTPSessionManager封装了许多功能,包括序列化数据:AFURLRequestSerialization作为JSON或HTTP请求。如果您对AFHTTPSessionManager在这里实际做了什么感兴趣,请参阅以下内容:

A)HTTP请求 这是来自AFURLRequestSerialization.m的代码:

- (NSURLRequest *)requestBySerializingRequest:(NSURLRequest *)request
                               withParameters:(id)parameters
                                        error:(NSError *__autoreleasing *)error
{
    NSParameterAssert(request);

    NSMutableURLRequest *mutableRequest = [request mutableCopy];

    [self.HTTPRequestHeaders enumerateKeysAndObjectsUsingBlock:^(id field, id value, BOOL * __unused stop) {
        if (![request valueForHTTPHeaderField:field]) {
            [mutableRequest setValue:value forHTTPHeaderField:field];
        }
    }];

    if (parameters) {
        NSString *query = nil;
        if (self.queryStringSerialization) {
            NSError *serializationError;
            query = self.queryStringSerialization(request, parameters, &serializationError);

            if (serializationError) {
                if (error) {
                    *error = serializationError;
                }

                return nil;
            }
        } else {
            switch (self.queryStringSerializationStyle) {
                case AFHTTPRequestQueryStringDefaultStyle:
                    query = AFQueryStringFromParametersWithEncoding(parameters, self.stringEncoding);
                    break;
            }
        }

        if ([self.HTTPMethodsEncodingParametersInURI containsObject:[[request HTTPMethod] uppercaseString]]) {
            mutableRequest.URL = [NSURL URLWithString:[[mutableRequest.URL absoluteString] stringByAppendingFormat:mutableRequest.URL.query ? @"&%@" : @"?%@", query]];
        } else {
            if (![mutableRequest valueForHTTPHeaderField:@"Content-Type"]) {
                [mutableRequest setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
            }
            [mutableRequest setHTTPBody:[query dataUsingEncoding:self.stringEncoding]];
        }
    }

    return mutableRequest;
}

B)JSON

- (NSURLRequest *)requestBySerializingRequest:(NSURLRequest *)request
                               withParameters:(id)parameters
                                        error:(NSError *__autoreleasing *)error
{
    NSParameterAssert(request);

    if ([self.HTTPMethodsEncodingParametersInURI containsObject:[[request HTTPMethod] uppercaseString]]) {
        return [super requestBySerializingRequest:request withParameters:parameters error:error];
    }

    NSMutableURLRequest *mutableRequest = [request mutableCopy];

    [self.HTTPRequestHeaders enumerateKeysAndObjectsUsingBlock:^(id field, id value, BOOL * __unused stop) {
        if (![request valueForHTTPHeaderField:field]) {
            [mutableRequest setValue:value forHTTPHeaderField:field];
        }
    }];

    if (parameters) {
        if (![mutableRequest valueForHTTPHeaderField:@"Content-Type"]) {
            [mutableRequest setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
        }

        [mutableRequest setHTTPBody:[NSJSONSerialization dataWithJSONObject:parameters options:self.writingOptions error:error]];
    }

    return mutableRequest;
}

答案 1 :(得分:0)

NSMutableDictionary *rus = [[NSMutableDictionary alloc] init];
[rus setValue:@"1211" forKey:@"id"];
[rus setValue:@"33" forKey:@"man"];

如果您正在与服务器交换JSON数据:

NSError *error = nil;
NSData *aRequestData = [NSJSONSerialization dataWithJSONObject:rus options:NSJSONWritingPrettyPrinted error:&error];

if (!error) {
     [urlRequest setHTTPBody:aRequestData];
}

如果您正在与服务器交换PLIST数据:

[self stringByAppendingQueryParameters:rus appendQuestionMark:NO];

- (NSString *)stringByAppendingQueryParameters:(NSDictionary *)iParameters appendQuestionMark:(BOOL)iAppendQuestionMark {
    BOOL aAppendAmpersand = YES;
    NSMutableString *aWorking = [NSMutableString stringWithString:self];

    if (iAppendQuestionMark) {
        NSRange aQueryBeginning = [self rangeOfString:@"?"];
        if (aQueryBeginning.location == NSNotFound) {
            [aWorking appendString:@"?"];
            aAppendAmpersand = NO;
        }
    } else {
        aAppendAmpersand = NO;  
    }

    for (id aKey in iParameters) {
        id aValue = [iParameters valueForKey:aKey];
        NSString *aKeyStr = [self convertObjectToURLEncodedValue:aKey];

    if (aAppendAmpersand) {
        [aWorking appendString:@"&"];
    } else {
        aAppendAmpersand = YES;
    }

    if ([aValue isKindOfClass:[NSArray class]]) {
        NSArray *aSubParamaters = (NSArray *)aValue;
        BOOL aFirstTime = YES;
        for (id aSubValue in aSubParamaters) {
            NSString *aValueString = [self convertObjectToURLEncodedValue:aSubValue];

            if (!aFirstTime) {
                [aWorking appendString:@"&"];                   
            }
            [aWorking appendString:aKeyStr];
            [aWorking appendString:@"="];
            [aWorking appendString:aValueString];

            aFirstTime = NO;
        }

    } else {
        NSString *aValueString = [self convertObjectToURLEncodedValue:aValue];
        [aWorking appendString:aKeyStr];
        [aWorking appendString:@"="];
        [aWorking appendString:aValueString];           
    }

}

return [NSString stringWithString:aWorking];        
}


- (NSString *)convertObjectToURLEncodedValue:(id)iObject {
    NSString *anIntermediate = nil;

    if ([iObject isKindOfClass:[NSString class]]) {
        anIntermediate = iObject;
    } else if ([iObject respondsToSelector:@selector(stringValue)]) {
        anIntermediate = [iObject stringValue];
    } else {
        anIntermediate = [iObject description];
    }

    NSString *anEncodingString = (__bridge_transfer NSString *)(CFURLCreateStringByAddingPercentEscapes(
                                                                                     NULL,
                                                                                     (__bridge CFStringRef)anIntermediate,
                                                                                     NULL,
                                                                                     (CFStringRef)@"!*'();:@&=+$,/?%#[]",
                                                                                     kCFStringEncodingUTF8 ));
    return anEncodingString;
}