Objective-C中的Url减去查询字符串

Posted

技术标签:

【中文标题】Objective-C中的Url减去查询字符串【英文标题】:Url minus query string in Objective-C 【发布时间】:2011-05-15 09:19:39 【问题描述】:

在 Objective-C 中获取 url 减去其查询字符串的最佳方法是什么?一个例子:

输入:

http://www.example.com/folder/page.htm?param1=value1&param2=value2

输出:

http://www.example.com/folder/page.htm

是否有我缺少的 NSURL 方法来执行此操作?

【问题讨论】:

【参考方案1】:

我们应该尝试使用 NSURLComponents

  NSURL *url = @"http://example.com/test";
  NSURLComponents *comps = [[NSURLComponents alloc] initWithURL:url resolvingAgainstBaseURL:YES];
  NSString *cleanUrl = [NSString stringWithFormat:@"%@://%@",comps.scheme,comps.host];
  if(comps.path.length > 0)
     cleanUrl = [NSString stringWithFormat:@"%@/%@",cleanUrl,comps.path];
  

【讨论】:

【参考方案2】:

这是 Andree's answer 的 Swift 版本,有一些额外的味道 -

extension NSURL 

    func absoluteStringByTrimmingQuery() -> String? 
        if var urlcomponents = NSURLComponents(URL: self, resolvingAgainstBaseURL: false) 
            urlcomponents.query = nil
            return urlcomponents.string
        
        return nil
    

你可以这样称呼它-

let urlMinusQueryString  = url.absoluteStringByTrimmingQuery()

【讨论】:

非常感谢。我刚刚做出了改变@bcattle【参考方案3】:

Swift 版本

extension URL 
    func absoluteStringByTrimmingQuery() -> String? 
        if var urlcomponents = URLComponents(url: self, resolvingAgainstBaseURL: false) 
            urlcomponents.query = nil
            return urlcomponents.string
        
        return nil
    

希望这会有所帮助!

【讨论】:

【参考方案4】:

ios 8/OS X 10.9 开始,使用 NSURLComponents 有一种更简单的方法。

NSURL *url = [NSURL URLWithString:@"http://hostname.com/path?key=value"];
NSURLComponents *urlComponents = [[NSURLComponents alloc] initWithURL:url resolvingAgainstBaseURL:NO];

urlComponents.query = nil; // Strip out query parameters.
NSLog(@"Result: %@", urlComponents.string); // Should print http://hostname.com/path

【讨论】:

我刚刚发现此方法在 iOS 7 中不起作用。遇到 -'[__NSConcreteURLComponents string]: unrecognized selector sent to instance 0x167a12d0'。在 iOS 8 和 iOS 9 上运行良好。【参考方案5】:

您可以尝试使用NSURLquery 来获取参数,然后使用NSStringstringByReplacingOccurrencesOfString 去除该值?

NSURL *before = [NSURL URLWithString:@"http://www.example.com/folder/page.htm?param1=value1&param2=value2"];
NSString *after = [before.absoluteString stringByReplacingOccurrencesOfString:before.query withString:@""];

请注意,最终 URL 仍将以 ? 结尾,但如果需要,您也可以轻松删除它。

【讨论】:

【参考方案6】:

NSURL 有一个 query 属性,它包含 GET url 中 ? 之后的所有内容。因此,只需从 absoluteString 的末尾减去它,就可以得到没有查询的 url。

NSURL *originalURL = [NSURL URLWithString:@"https://winker@127.0.0.1:1000/file/path/?q=dogfood"];
NSString *strippedString = [originalURL absoluteString];
NSUInteger queryLength = [[originalURL query] length];
strippedString = (queryLength ? [strippedString substringToIndex:[strippedString length] - (queryLength + 1)] : strippedString);
NSLog(@"Output: %@", strippedString);

日志:

Output: https://winker@127.0.0.1:1000/file/path/

+1 用于不属于query?

【讨论】:

【参考方案7】:

您可能会喜欢NSMutableString 类的方法replaceOccurrencesOfString:withString:options:range:。我通过为NSURL 写一个category 解决了这个问题:

#import <Foundation/Foundation.h>

@interface NSURL (StripQuery)
// Returns a new URL with the query stripped out.
// Note: If there is no query, returns a copy of this URL.
- (NSURL *)URLByStrippingQuery;
@end

@implementation NSURL (StripQuery)
- (NSURL *)URLByStrippingQuery

    NSString *query = [self query];
    // Simply copy if there was no query. (query is nil if URL has no '?',
    // and equal to @"" if it has a '?' but no query after.)
    if (!query || ![query length]) 
        return [self copy];
    
    NSMutableString *urlString = [NSMutableString stringWithString:[self absoluteString]];
    [urlString replaceOccurrencesOfString:query
                               withString:@""
                                  options:NSBackwardsSearch
                                    range:NSMakeRange(0, [urlString length])];
    return [NSURL URLWithString:urlString];

@end

这样,我可以将此消息发送到现有的 NSURL 对象,并有一个新的 NSURL 对象返回给我。

我使用以下代码对其进行了测试:

int main(int argc, const char * argv[])

    @autoreleasepool 
        NSURL *url = [NSURL URLWithString:@"http://www.example.com/script.php?key1=val1&key2=val2"];
//      NSURL *url = [NSURL URLWithString:@"http://www.example.com/script.php?"];
//      NSURL *url = [NSURL URLWithString:@"http://www.example.com/script.php"];
        NSURL *newURL = [url URLByStrippingQuery];
        NSLog(@"Original URL: \"%@\"\n", [url absoluteString]);
        NSLog(@"Stripped URL: \"%@\"\n", [newURL absoluteString]);
    
    return 0;

我得到以下输出(减去时间戳):

Original URL: "http://www.example.com/script.php?key1=val1&key2=val2"
Stripped URL: "http://www.example.com/script.php?"

请注意,问号 ('?') 仍然存在。我会留给读者以安全的方式将其删除。

【讨论】:

【参考方案8】:

我看不到 NSURL 方法。您可以尝试以下方法:

NSURL *newURL = [[NSURL alloc] initWithScheme:[url scheme]
                                         host:[url host]
                                         path:[url path]];

测试看起来不错:

#import <Foundation/Foundation.h>
int main(int argc, char *argv[]) 
    NSAutoreleasePool *arp = [[NSAutoreleasePool alloc] init];

    NSURL *url = [NSURL URLWithString:@"http://www.abc.com/foo/bar.cgi?a=1&b=2"];
    NSURL *newURL = [[[NSURL alloc] initWithScheme:[url scheme]
                                              host:[url host]
                                              path:[url path]] autorelease];
    NSLog(@"\n%@ --> %@", url, newURL);
    [arp release];
    return 0;

运行它会产生:

$ gcc -lobjc -framework Foundation -std=c99 test.m ; ./a.out 
2010-11-25 09:20:32.189 a.out[36068:903] 
http://www.abc.com/foo/bar.cgi?a=1&b=2 --> http://www.abc.com/foo/bar.cgi

【讨论】:

不错的解决方案,唯一的问题是port不会被继承。 另一个问题是,如果原始url中不存在路径,这将使应用程序崩溃。 这个 API 实际上是 API_DEPRECATED。人们应该停止使用它,转而使用 NSURLComponents。【参考方案9】:

您可能需要的是 url 的主机和路径组件的组合:

NSString *result = [[url host] stringByAppendingPathComponent:[url path]];

【讨论】:

【参考方案10】:

我认为-baseURL 可能会做你想做的事。

如果没有,您可以像这样通过NSString 进行往返:

NSString *string = [myURL absoluteString];
NSString base = [[string componentsSeparatedByString:@"?"] objectAtIndex:0];
NSURL *trimmed = [NSURL URLWithString:base];

【讨论】:

No -baseURL 不会做你想做的事。【参考方案11】:

我想你要找的是baseUrl

【讨论】:

baseURL 文档有一个可怕的说明:“如果接收者是绝对 URL,则返回 nil。”不过,不确定什么是“绝对”网址。

以上是关于Objective-C中的Url减去查询字符串的主要内容,如果未能解决你的问题,请参考以下文章

Objective-C中把URL请求的参数转换为字典

如何在 Xcode(Objective-c)上的 URL 中连接字符串?

从Objective C中的字符串获取JSON URL

转换以字符串格式存储的日期值并减去 mongodb 中的当前日期

mod_rewrite:从 URL 中删除查询字符串?

将 Objective-C / iOS 字符串转换为 URL 的正确语法是啥? [关闭]