Issue with NSURLComponents when building a queryString

时间:2016-02-03 23:06:28

标签: ios

I get this error:

-[__NSCFNumber stringByAddingPercentEncodingWithAllowedCharacters:]: unrecognized selector sent to instance 0x7fab88c21750        

And I get it with this code:

+ (NSString *)queryStringFromDictionary:(NSDictionary *)queryDictionary
{
    NSURLComponents *components = [NSURLComponents componentsWithString:@""];
    NSMutableArray *urlQueryComponents = [NSMutableArray array];

    for (NSString *key in [queryDictionary allKeys])
    {
        NSString *value = queryDictionary[key];
        NSURLQueryItem *newQueryItem = [NSURLQueryItem queryItemWithName:key value:value];
        [urlQueryComponents addObject:newQueryItem];
    }

    components.queryItems = urlQueryComponents; // HERE I GET THE ERROR
    return [components query];
}

In the case where I got the error my queryDictionary looked like this:

{
    lat = "49.3437442";
    lng = "17.0571453";
    username = demo;
}

Another time when my queryDictionary looked like following, it worked fine!

{
    latlng = "49.343744,17.057145";
    sensor = true;
}

So I can't understand the issue or how I can fix it. Any ideas?

1 个答案:

答案 0 :(得分:3)

您传递的字典包含NSNumber作为键或值。 queryWithItem:value:期望key和value都是一个字符串。

选项1

解决这个问题的最简单方法是将所有键/值视为NSObjects,并使用stringWithFormat将它们转换为字符串。

取代:

NSURLQueryItem *newQueryItem = [NSURLQueryItem queryItemWithName:key value:value];

使用:

NSURLQueryItem *newQueryItem = [NSURLQueryItem queryItemWithName:[NSString stringWithFormat:@"%@", key] value:[NSString stringWithFormat:@"%@", value]];

选项2

如果你想坚持所有键都是字符串,我建议你使用泛型输入字典,如果找到非字符串键则推荐使用NSAssert(这样你就可以找到当前的错误)。

+ (NSString *)queryStringFromDictionary:(NSDictionary <NSString*, NSString*> *)queryDictionary {
    NSURLComponents *components = [NSURLComponents componentsWithString:@""];
    NSMutableArray *urlQueryComponents = [NSMutableArray array];

    for (NSString *key in [queryDictionary allKeys]) {
        NSString *value = queryDictionary[key];

        // confirm key/value are strings
        NSAssert([key isKindOfClass:[NSString class]], @"keys must be strings!");
        NSAssert([value isKindOfClass:[NSString class]], @"values must be strings!");

        NSURLQueryItem *newQueryItem = [NSURLQueryItem queryItemWithName:key value:value];
        [urlQueryComponents addObject:newQueryItem];
    }

    components.queryItems = urlQueryComponents;
    return [components query];
}