大部分人拼接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);