iOS开发--NSURL大部分人都用错了

大部分人拼接URL参数/路径时, 都会选择字符串拼接,因为直观,容易理解.这样真的好吗? 本文带你认识NSURL的用法

一 对URL的操作:

1 域名固定,拼接path

APP内域名统一,各个接口只需要拼接不同的path就可以得到对应的完成的URL字符串

host = http://baidu.com/

1.1 有人这样封装到APIManger:

+(NSString *)loginUrl{
return @"http://baidu.com/t1";
}
+(NSString *)logoutUrl{
return @"http://baidu.com/l2";
}

1.2 有人这样,方便切换host:

static NSString * host = @"http://baidu.com";

+(NSString *)loginUrl{
return [NSString stringWithFormat:@"%@/t1",host];
}
+(NSString *)logoutUrl{
return [NSString stringWithFormat:@"%@/l2",host];
}

1.3 有人为了更方便会这样,使用宏定义:

static NSString * host = @"http://baidu.com";

#define KLOGINURL [APIManger share].loginUrl
#define KLOGOUTURL [APIManger share].logoutUrl
-(NSString *)loginUrl{
return [NSString stringWithFormat:@"%@/t1",host];
}
-(NSString *)logoutUrl{
return [NSString stringWithFormat:@"%@/l2",host];
}

1.4 以上3种均没有问题.上线运行不会出现问题,但是以上3种方式均是使用了普通字符串的操作得到URL的完整路径

1.5 大部分APP域名是服务端获取的.这对APP来说会产生不确定性

服务器下发URL,请求的时候需要APP拼接参数,需要考虑到各种情况比如:

服务器下发: host = @“http://www.baidu.com” 改成 @“http://www.baidu.com?client=ios”

+(NSString *)logoutUrl{
return [NSString stringWithFormat:@"%@?userName=%@&passWord=%@",host,@"userName",@"passWord"];
}

拼接完毕是: http://www.baidu.com?userName=un&passWord=pwd

服务器下发: host = @“http://www.baidu.com?c=ios”

拼接完毕是: http://www.baidu.com?c=ios?userName=un&passWord=pwd

拼接的就会出问题.

2 获取url的某个部分

2.1 获取host,参数,协议,path等等

有人会使用字符串截取,有人会用正则表达式

反思

苹果的NSURL对象对这种常规操作有没有支持?
如何优雅的避免拼接的url格式不对
NSURL有没有属性可以直接获取host,参数,协议,path等等

二 避免url拼接错误

1 拼接key value (下文有测试代码)

NSURLComponents *components = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:NO];
NSMutableArray *array = [NSMutableArray arrayWithArray:components.queryItems];
NSURLQueryItem *item = [NSURLQueryItem queryItemWithName:@"dd" value:@"4"];
[array addObject:item];
components.queryItems = array;

2 拼接path

NSString *base = @"http://www.baidu.com/";
url = [NSURL URLWithString:@"at/bt/ct" relativeToURL:[NSURL URLWithString:base]];

三 NSURL常用接口

 NSString *domain = @"http://username:[email protected]:80/at/bt/ct?ad=1&bd=2&cd=3#asdf";

NSURL *url = [NSURL URLWithString:domain];

NSLog(@"absoluteString = %@ \n baseURL = %@\n scheme = %@\n resourceSpecifier =%@\n host = %@\n user = %@\n password = %@ \n path = %@ \n fragment = %@ \n query = %@ \n  relativePath =%@ \n port = %@",
      url.absoluteString,
      url.baseURL,
      url.scheme,
      url.resourceSpecifier,
      url.host,
      url.user,
      
      url.password,
      url.path,
      url.fragment,
      url.query,
      url.relativePath,
      url.port
      );

NSURLComponents *components = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:NO];

NSMutableArray *array = [NSMutableArray arrayWithArray:components.queryItems];

NSURLQueryItem *item = [NSURLQueryItem queryItemWithName:@"dd" value:@"4"];
[array addObject:item];

NSLog(@"queryItems = %@",components.queryItems);
NSLog(@"path = %@",components.queryItems);
components.queryItems = array;
NSLog(@"queryItems-1 = %@",components.queryItems);
NSLog(@"queryItems-2 = %@",[components URLRelativeToURL:nil]);

components.path = [components.path stringByAppendingPathComponent:@"dt/et"];
NSLog(@"queryItems-3 = %@",[components URLRelativeToURL:nil]);


NSString *base = @"http://www.baidu.com/";
url = [NSURL URLWithString:@"at/bt/ct" relativeToURL:[NSURL URLWithString:base]];

NSLog(@"url = %@, absoluteString = %@",url,url.absoluteString);

注意:

stringByAppendingPathComponent 方法会把双斜杠(//)变成单斜杠(/)

NSString *str = [domain stringByAppendingPathComponent:@"t/12/324"];
NSLog(@"%@---%@",domain,str);

你可能感兴趣的:(iOS开发--NSURL大部分人都用错了)