Programing

Objective-C : NSURL에 쿼리 매개 변수를 추가하는 방법은 무엇입니까?

lottogame 2020. 12. 27. 10:18
반응형

Objective-C : NSURL에 쿼리 매개 변수를 추가하는 방법은 무엇입니까?


내가 NSURL있는가? 이 있는지 여부 이미 빈 쿼리 문자열, 내가 어떻게 하나 개 이상의 매개 변수를 추가하려면이 query의를 NSURL? 즉,이 기능의 구현을 아는 사람이 있습니까?

- (NSURL *)URLByAppendingQueryString:(NSString *)queryString

따라서 다음 NSURL+AdditionsSpec.h파일을 충족 합니다.

#import "NSURL+Additions.h"
#import "Kiwi.h"

SPEC_BEGIN(NSURL_AdditionsSpec)

describe(@"NSURL+Additions", ^{
    __block NSURL *aURL;

    beforeEach(^{
        aURL = [[NSURL alloc] initWithString:@"http://www.example.com"];
        aURLWithQuery = [[NSURL alloc] initWithString:@"http://www.example.com?key=value"];
    });

    afterEach(^{
        [aURL release];
        [aURLWithQuery release];
    });

    describe(@"-URLByAppendingQueryString:", ^{
        it(@"adds to plain URL", ^{
            [[[[aURL URLByAppendingQueryString:@"key=value&key2=value2"] query] should]
             equal:@"key=value&key2=value2"];
        });

        it(@"appends to the existing query sting", ^{
            [[[[aURLWithQuery URLByAppendingQueryString:@"key2=value2&key3=value3"] query] should]
             equal:@"key=value&key2=value2&key3=value3"];
        });
    });
});

SPEC_END

iOS 7 부터는 사용하기 매우 간단한 NSURLComponents 를 사용할 수 있습니다. 다음 예를 살펴보십시오.

예 1

NSString *urlString = @"https://mail.google.com/mail/u/0/?shva=1#inbox";
NSURLComponents *components = [[NSURLComponents alloc] initWithString:urlString];

NSLog(@"%@ - %@ - %@ - %@", components.scheme, components.host, components.query, components.fragment);

예 2

NSString *urlString = @"https://mail.google.com/mail/u/0/?shva=1#inbox";
NSURLComponents *components = [[NSURLComponents alloc] initWithString:urlString];

if (components) {
    //good URL
} else {
    //bad URL
}

예제 3

NSURLComponents *components = [NSURLComponents new];
[components setScheme:@"https"];
[components setHost:@"mail.google.com"];
[components setQuery:@"shva=1"];
[components setFragment:@"inbox"];
[components setPath:@"/mail/u/0/"];

[self.webview loadRequest:[[NSURLRequest alloc] initWithURL:[components URL]]];

그러나 NSURLComponents를 사용하여 다른 많은 작업을 수행 할 수 있습니다. Apple 문서 또는 다음 링크에서 NSURLComponents 클래스 참조를 살펴보십시오. http://nshipster.com/nsurl/


사양을 통과하는 구현은 다음과 같습니다.

@implementation NSURL (Additions)

- (NSURL *)URLByAppendingQueryString:(NSString *)queryString {
    if (![queryString length]) {
        return self;
    }

    NSString *URLString = [[NSString alloc] initWithFormat:@"%@%@%@", [self absoluteString],
                           [self query] ? @"&" : @"?", queryString];
    NSURL *theURL = [NSURL URLWithString:URLString];
    [URLString release];
    return theURL;
}

@end

그리고 여기에 대한 구현이 있습니다 NSString.

@implementation NSString (Additions)

- (NSURL *)URLByAppendingQueryString:(NSString *)queryString {
    if (![queryString length]) {
        return [NSURL URLWithString:self];
    }

    NSString *URLString = [[NSString alloc] initWithFormat:@"%@%@%@", self,
                           [self rangeOfString:@"?"].length > 0 ? @"&" : @"?", queryString];
    NSURL *theURL = [NSURL URLWithString:URLString];
    [URLString release];
    return theURL;
}

// Or:

- (NSString *)URLStringByAppendingQueryString:(NSString *)queryString {
    if (![queryString length]) {
        return self;
    }
    return [NSString stringWithFormat:@"%@%@%@", self,
            [self rangeOfString:@"?"].length > 0 ? @"&" : @"?", queryString];
}

@end

iOS8 + 최신 방식

adding (or replacing 'ref' value if exists) ref=impm to url which is on min60.com

if ([[url host] hasSuffix:@"min60.com"]) {

    NSURLComponents *components = [[NSURLComponents alloc] initWithURL:url resolvingAgainstBaseURL:NO];
    NSURLQueryItem * newQueryItem = [[NSURLQueryItem alloc] initWithName:@"ref" value:@"impm"];
    NSMutableArray * newQueryItems = [NSMutableArray arrayWithCapacity:[components.queryItems count] + 1];
    for (NSURLQueryItem * qi in components.queryItems) {
        if (![qi.name isEqual:newQueryItem.name]) {
            [newQueryItems addObject:qi];
        }
    }
    [newQueryItems addObject:newQueryItem];
    [components setQueryItems:newQueryItems];

    url = [components URL];
}

Just a friendly post for those who don't want to write boilerplate code while building NSURL with NSURLComponents.
Since iOS8 we have NSURLQueryItem that helps building URL request freaking fast.

I wrote a little handy category to ease the work, that you can grab here: URLQueryBuilder
Here is example of how easy it is to work with it:

NSString *baseURL = @"https://google.com/search";
NSDictionary *items = @{
    @"q"  : @"arsenkin.com",
    @"hl" : @"en_US",
    @"lr" : @"lang_en"
};

NSURL *URL = [NSURL ars_queryWithString:baseURL queryElements:items];  
// https://google.com/search?q=arsenkin.com&hl=en_US&lr=lang_en

If you're using RestKit it provides additions to NSString. One of which is:

- (NSString *)stringByAppendingQueryParameters:(NSDictionary *)queryParameters

So you could do:

NSDictionary *shopParams = [NSDictionary dictionaryWithKeysAndObjects:
                                @"limit",@"20", 
                                @"location",@"latitude,longitude",
                                nil];
NSString *pathWithQuery = [@"/api/v1/shops.json" stringByAppendingQueryParameters:shopParams]

I have an extension to NSURLComponents that add query item, in swift:

extension NSURLComponents {

    func appendQueryItem(name name: String, value: String) {
        var queryItems: [NSURLQueryItem] = self.queryItems ?? [NSURLQueryItem]()
        queryItems.append(NSURLQueryItem(name: name, value: value))
        self.queryItems = queryItems
    }

}

To use,

let components = NSURLComponents(string: urlString)!
components.appendQueryItem(name: "key", value: "value")

The answers above mentioned the NSURLComponents,it's a good class to handle URL.

My answer is as follows:

Create a category with NSURL,like NSURL+Additions.h. Then,add the following method and implement it.

- (NSURL *)URLByAppendingQueryParameters:(NSDictionary *)queryParameters
{
    if (queryParameters.count == 0) {
        return self;
    }

    NSArray *queryKeys = [queryParameters allKeys];
    NSURLComponents *components = [[NSURLComponents alloc] initWithURL:self resolvingAgainstBaseURL:NO];
    NSMutableArray * newQueryItems = [NSMutableArray arrayWithCapacity:1];

    for (NSURLQueryItem * item in components.queryItems) {
        if (![queryKeys containsObject:item.name]) {
            [newQueryItems addObject:item];
        }
    }

    for (NSString *key in queryKeys) {
        NSURLQueryItem * newQueryItem = [[NSURLQueryItem alloc] initWithName:key value:queryParameters[key]];
        [newQueryItems addObject:newQueryItem];
    }

    [components setQueryItems:newQueryItems];

    return [components URL];
}

NSURL is not mutable so you cannot implement this functionality directly based on NSURL. Instead you will have to obtain the string representation of the URL, append your parameters to that and then create a new NSURL.

This does not sound like a good solution. Unless there is a good reason, it is better to work with strings until the last moment and only create an NSURL when you have your fully formed request.

ReferenceURL : https://stackoverflow.com/questions/6309698/objective-c-how-to-add-query-parameter-to-nsurl

반응형