NSURL سحب قيمة واحدة لمفتاح في سلسلة المعلمة

StackOverflow https://stackoverflow.com/questions/2225814

  •  19-09-2019
  •  | 
  •  

سؤال

لدي NSURL:

ServerCall؟ x = a & y = b & z = c

ما هي الطريقة الأسرع والأكثر فعالية للحصول على قيمة Y؟

شكرا

هل كانت مفيدة؟

المحلول

تحديث:

منذ عام 2010 عندما كتب هذا، يبدو أن Apple أصدرت مجموعة من الأدوات لهذا الغرض. يرجى الاطلاع على الإجابات أدناه لأولئك.

حل المدرسة القديمة:

حسنا، أنا أعلم أنك قلت "أسرع طريقة"ولكن بعد أن بدأت إجراء اختبار مع NSScanner أنا فقط لم أستطع التوقف. وبينما لم يكن الأمر أقصر طريقة، فمن المؤكد أنه من الأفضل أن تخطط لاستخدام هذه الميزة كثيرا. لقد أنشأت أ URLParser فئة تحصل على هذه الفاوات باستخدام NSScanner. وبعد الاستخدام بسيط مثل:

URLParser *parser = [[[URLParser alloc] initWithURLString:@"http://blahblahblah.com/serverCall?x=a&y=b&z=c&flash=yes"] autorelease];
NSString *y = [parser valueForVariable:@"y"];
NSLog(@"%@", y); //b
NSString *a = [parser valueForVariable:@"a"];
NSLog(@"%@", a); //(null)
NSString *flash = [parser valueForVariable:@"flash"];
NSLog(@"%@", flash); //yes

والصف الذي يفعله هذا هو ما يلي (* الملفات المصدر في الجزء السفلي من المنشور):

urlparser.h.

@interface URLParser : NSObject {
    NSArray *variables;
}

@property (nonatomic, retain) NSArray *variables;

- (id)initWithURLString:(NSString *)url;
- (NSString *)valueForVariable:(NSString *)varName;

@end

urlparser.m.

@implementation URLParser
@synthesize variables;

- (id) initWithURLString:(NSString *)url{
    self = [super init];
    if (self != nil) {
        NSString *string = url;
        NSScanner *scanner = [NSScanner scannerWithString:string];
        [scanner setCharactersToBeSkipped:[NSCharacterSet characterSetWithCharactersInString:@"&?"]];
        NSString *tempString;
        NSMutableArray *vars = [NSMutableArray new];
        [scanner scanUpToString:@"?" intoString:nil];       //ignore the beginning of the string and skip to the vars
        while ([scanner scanUpToString:@"&" intoString:&tempString]) {
            [vars addObject:[tempString copy]];
        }
        self.variables = vars;
        [vars release];
    }
    return self;
}

- (NSString *)valueForVariable:(NSString *)varName {
    for (NSString *var in self.variables) {
        if ([var length] > [varName length]+1 && [[var substringWithRange:NSMakeRange(0, [varName length]+1)] isEqualToString:[varName stringByAppendingString:@"="]]) {
            NSString *varValue = [var substringFromIndex:[varName length]+1];
            return varValue;
        }
    }
    return nil;
}

- (void) dealloc{
    self.variables = nil;
    [super dealloc];
}

@end

* إذا كنت لا تحب النسخ واللصق، يمكنك فقط تنزيل الملفات المصدر - قمت بإجراء منشور سريع بلوق حول هذا الموضوع هنا.

نصائح أخرى

الكثير من محلل URL المخصص هنا، تذكر nsurlcomponents. هو صديقك!

فيما يلي مثال حيث أسحب معلمة مشفرة عناوين URL ل "الصفحة"

سويفت

let myURL = "www.something.com?page=2"

var pageNumber : Int?
if let queryItems = NSURLComponents(string: myURL)?.queryItems {
    for item in queryItems {
        if item.name == "page" {
           if let itemValue = item.value {
               pageNumber = Int(itemValue)
           }
        }
    }
}
print("Found page number: \(pageNumber)")

ج موضوعية

NSString *myURL = @"www.something.com?page=2";
NSURLComponents *components = [NSURLComponents componentsWithString:myURL];
NSNumber *page = nil;
for(NSURLQueryItem *item in components.queryItems)
{
    if([item.name isEqualToString:@"page"])
        page = [NSNumber numberWithInteger:item.value.integerValue];
}

"لماذا إعادة اختراع العجلة!" - شخص ذكي

أنا متأكد من أن عليك تحليلها بنفسك. ومع ذلك، فهذا ليس سيئا للغاية:

NSString * q = [myURL query];
NSArray * pairs = [q componentsSeparatedByString:@"&"];
NSMutableDictionary * kvPairs = [NSMutableDictionary dictionary];
for (NSString * pair in pairs) {
  NSArray * bits = [pair componentsSeparatedByString:@"="];
  NSString * key = [[bits objectAtIndex:0] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
  NSString * value = [[bits objectAtIndex:1] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
  [kvPairs setObject:value forKey:key];
}

NSLog(@"y = %@", [kvPairs objectForKey:@"y"]);

في SWIFT يمكنك استخدام NSurLComponents لتحليل سلسلة الاستعلام من NSURL في [anyobject].

يمكنك بعد ذلك إنشاء قاموس من ذلك (أو الوصول إلى العناصر مباشرة) للحصول على أزواج المفتاح / القيمة. كمثال، هذا هو ما أستخدمه لتحليل عنوان URL متغير NSURL:

let urlComponents = NSURLComponents(URL: url, resolvingAgainstBaseURL: false)
let items = urlComponents?.queryItems as [NSURLQueryItem]
var dict = NSMutableDictionary()
for item in items{
    dict.setValue(item.value, forKey: item.name)
}
println(dict["x"])

لقد كنت أستخدم هذه الفئة: https://github.com/carlj/nsurl-parameters..

انها صغيرة وسهلة الاستخدام:

#import "NSURL+Parameters.h"
...
NSURL *url = [NSURL URLWithString:@"http://foo.bar.com?paramA=valueA&paramB=valueB"];
NSString *paramA = url[@"paramA"];
NSString *paramB = url[@"paramB"];

يمكنك استخدام مربع أدوات Google لنظام التشغيل Mac. يضيف وظيفة إلى nsstring لتحويل سلسلة الاستعلام إلى القاموس.

http://code.google.com/p/google-toolbox-for-mac/

أنه يعمل مثل السحر

        NSDictionary * d = [NSDictionary gtm_dictionaryWithHttpArgumentsString:[[request URL] query]];

إليك ملحق SWIFT 2.0 يوفر وصول بسيط إلى المعلمات:

extension NSURL {
    var params: [String: String] {
        get {
            let urlComponents = NSURLComponents(URL: self, resolvingAgainstBaseURL: false)
            var items = [String: String]()
            for item in urlComponents?.queryItems ?? [] {
                items[item.name] = item.value ?? ""
            }
            return items
        }
    }
} 

استخدام عينة:

let url = NSURL(string: "http://google.com?test=dolphins")
if let testParam = url.params["test"] {
    print("testParam: \(testParam)")
}

كتبت فئة بسيطة لتوسيع NSSTRING / NSURL التي تتيح لك استخراج معلمات استعلام URL بشكل فردي أو كقوس القاموس في أزواج المفتاح / القيمة:

https://github.com/nicklockwood/requestutils.

هل قمت باستخدام طريقة فئة تعتمد على محلول DIMITRIS

#import "NSURL+DictionaryValue.h"

@implementation NSURL (DictionaryValue)
-(NSDictionary *)dictionaryValue
{
NSString *string =  [[self.absoluteString stringByReplacingOccurrencesOfString:@"+" withString:@" "]
                     stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSScanner *scanner = [NSScanner scannerWithString:string];
[scanner setCharactersToBeSkipped:[NSCharacterSet characterSetWithCharactersInString:@"&?"]];

NSString *temp;
NSMutableDictionary *dict = [[[NSMutableDictionary alloc] init] autorelease];
[scanner scanUpToString:@"?" intoString:nil];       //ignore the beginning of the string and skip to the vars
while ([scanner scanUpToString:@"&" intoString:&temp]) 
{
    NSArray *parts = [temp componentsSeparatedByString:@"="];
    if([parts count] == 2)
    {
        [dict setObject:[parts objectAtIndex:1] forKey:[parts objectAtIndex:0]];
    }
}

return dict;
}
@end

يمكنك القيام بذلك بسهولة:

- (NSMutableDictionary *) getUrlParameters:(NSURL *) url
{
    NSMutableDictionary *params = [[NSMutableDictionary alloc] init];
    NSString *tmpKey = [url query];
    for (NSString *param in [[url query] componentsSeparatedByString:@"="])
    {
        if ([tmpKey rangeOfString:param].location == NSNotFound)
        {
            [params setValue:param forKey:tmpKey];
            tmpKey = nil;
        }
        tmpKey = param;
    }
    [tmpKey release];

    return params;
}

IT RETION قاموس مثل ذلك: Key = القيمة

لقد قمت بتحرير رمز Dimitris قليلا لإدارة الذاكرة بشكل أفضل وكفاءة. أيضا، يعمل في قوس.

urlparser.h.

@interface URLParser : NSObject

- (void)setURLString:(NSString *)url;
- (NSString *)valueForVariable:(NSString *)varName;

@end

urlparser.m.

#import "URLParser.h"

@implementation URLParser {
    NSMutableDictionary *_variablesDict;
}

- (void)setURLString:(NSString *)url {
    [_variablesDict removeAllObjects];

    NSString *string = url;
    NSScanner *scanner = [NSScanner scannerWithString:string];
    [scanner setCharactersToBeSkipped:[NSCharacterSet characterSetWithCharactersInString:@"&?"]];
    NSString *tempString;

    [scanner scanUpToString:@"?" intoString:nil];       //ignore the beginning of the string and skip to the vars
    while ([scanner scanUpToString:@"&" intoString:&tempString]) {
        NSString *dataString = [tempString copy];
        NSArray *sepStrings = [dataString componentsSeparatedByString:@"="];
        if ([sepStrings count] == 2) {
            [_variablesDict setValue:sepStrings[1] forKeyPath:sepStrings[0]];
        }
    }
}

- (id)init
{
    self = [super init];
    if (self) {
        _variablesDict = [[NSMutableDictionary alloc] init];
    }
    return self;
}

- (NSString *)valueForVariable:(NSString *)varName {
    NSString *val = [_variablesDict valueForKeyPath:varName];
    return val;
    return nil;
}

-(NSString *)description {
    return [NSString stringWithFormat:@"Current Variables: %@", _variablesDict];
}

@end

جميع الإجابات الحالية هي الإصدار المحدد أو مهدر بلا داع. لماذا إنشاء قاموس إذا كنت تريد فقط قيمة واحدة؟

هنا بسيط الإجابة التي تدعم جميع إصدارات iOS:

- (NSString *)getQueryParam:(NSString *)name  fromURL:(NSURL *)url
{
    if (url)
    {
        NSArray *urlComponents = [url.query componentsSeparatedByString:@"&"];
        for (NSString *keyValuePair in urlComponents)
        {
            NSArray *pairComponents = [keyValuePair componentsSeparatedByString:@"="];
            NSString *key = [[pairComponents firstObject] stringByRemovingPercentEncoding];

            if ([key isEqualToString:name])
            {
                return [[pairComponents lastObject] stringByRemovingPercentEncoding];
            }
        }
    }
    return nil;
}

أسرع:

NSString* x = [url valueForQueryParameterKey:@"x"];
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top