NSURL/NSURLComponents

发布于:2014-04-14 10:14阅读数:

这里有一个直观的描述来解释什么是一维数据类型:number或string被格式化为多种多样的值,可以通过数学运算或某种转换方法可以算出它们的值。比如:十六进制的颜色值 #EE8262 的红绿蓝三原色

这里有一个直观的描述来解释什么是“一维数据类型”:number或string被格式化为多种多样的值,可以通过数学运算或某种转换方法可以算出它们的值。比如:十六进制的颜色值 #EE8262红绿蓝三原色的值通过掩码或移位运算得出;正则表达式可以通过少量字符中复杂的样本中进行匹配。
 
在所有的一维数据类型中,URI有着至高地位。单独就人类可阅读的字符串这一点来说,它存在并将永远存在于计算机中任何你能够想象到的对位置信息进行编码的数据中。
 
它最基础的表示法中,URI由一个scheme和一个hierarchical part组成,带有query和fragment(后两者非必需):
  1. <scheme name> : <hierarchical part> [ ? <query> ] [ # <fragment> ] 
 
很多像HTTP的协议中会定义有一定的规范结构,例如:username、password、port, 以及hierarchical part中的path:
  1. foo  ://     username    :   password    @   example.com     :   8042    /over/there/index   .   dtb     ?   type=animal&name=narwhal    #   nose 
  2. scheme   username        password        hostname        port    path        extension       query       fragment 
 
对网络编程的扎实理解植根于对于URL各个部分的完全的熟悉。作为软件开发工程师,这意味着在你的编程语言标准库中存在着对URI进行指挥功能的命令。
 
如果某门语言在标准库中没有URL模块,你要跑着离开这门语言(不能用走的!一定要跑!),这不是一门真正的编程语言。
 
在Foundation库中,NSURL用来代表URL。
 
NSURL 可以通过 URLWithString: 类方法实例化。
  1. NSURL *url = [NSURL URLWithString:@"http://example.com"]; 
 
如果传入值不是合法URL,这个方法会返回一个 nil 值。
 
我们几周前提到过 NSString 也有一些关于path处理的残留功能,但这些功能对于处理 NSURL 实在是太麻烦了。把 NSString 转化为 NSURL 带来的额外转化成本让这件事并不那么方便,你总是要花时间在这个上面。如果一个值就是一个URL,那么它就应该被保存为 NSURL,把这两种类型搞混是懒惰而鲁莽的API设计。
 
附加提示:@@ 是创建 NSURL 的字面量的绝佳方法(例如:@@"http://example.com"),怎么样,很方便吧?
 
NSURL 也有一个类方法 +URLWithString:relativeToURL: 可以根据一个base URL地址和关联字符串来构造URL。这个方法的行为由于其对子目录的/符号的处理而变得非常混乱无序。
 
这里有一些这个方法用法的典型参考:
  1. NSURL *baseURL = [NSURL URLWithString:@"http://example.com/v1/"]; 
  2.  
  3. [NSURL URLWithString:@"foo" relativeToURL:baseURL]; 
  4. // http://example.com/v1/foo 
  5.  
  6. [NSURL URLWithString:@"foo?bar=baz" relativeToURL:baseURL]; 
  7. // http://example.com/v1/foo?bar=baz 
  8.  
  9. [NSURL URLWithString:@"/foo" relativeToURL:baseURL]; 
  10. // http://example.com/foo 
  11.  
  12. [NSURL URLWithString:@"foo/" relativeToURL:baseURL]; 
  13. // http://example.com/v1/foo 
  14.  
  15. [NSURL URLWithString:@"/foo/" relativeToURL:baseURL]; 
  16. // http://example.com/foo/ 
  17.  
  18. [NSURL URLWithString:@"http://example2.com/" relativeToURL:baseURL]; 
  19. // http://example2.com/ 
 
URL Components
 
NSURL 根据RFC 2396的定义提供accessor方法用于获取URL每一部分的值:
 
– absoluteString – absoluteURL – baseURL – fileSystemRepresentation – fragment – host – lastPathComponent – parameterString – password – path – pathComponents – pathExtension – port – query – relativePath – relativeString – resourceSpecifier – scheme – standardizedURL – user
 
NSURL官方文档中的文档和样例是让你熟悉各种URL组成部分的绝佳参考。
 
虽然可以通过URL来存储用户名和密码,但建议用 NSURLCredential 装载用户名和密码,用keychain来存储它们更适合。
 
NSURLComponents
 
苹果在 iOS 7 和 Mac OS X 10.9 Mavericks 中悄悄添加了 NSURLComponents,这样就可以完美替代 NSMutableURL 了。但文档还不是很完善,所以这个类仍然是近期Foundation新增类中隐晦的一块。
 
创建 NSURLComponents 实例和创建 NSURL 实例的方法差不多,通过一个 NSString 和一个非必需的base URL参数创建(+componentsWithString: & +componentsWithString:resolvingAgainstBaseURL:)。也可以用 alloc init 创建一个空的容器,和NSDateComponents差不多。
 
NSURL 和 NSURLComponents 的不同之处在于,URL component属性是 readwrite 的。它提供了安全直接的方法来修改URL的各个部分:
  • scheme
  • user
  • password
  • host
  • port
  • path
  • query
  • fragment
如果尝试赋值一个非法的scheme或port,会抛出一个异常。
 
另外,NSURLComponents 也有 readwrite 属性对每个component进行[percent-encoded]。
  • percentEncodedUser
  • percentEncodedPassword
  • percentEncodedHost
  • percentEncodedPath
  • percentEncodedQuery
  • percentEncodedFragment
对这些percent encoding属性的get操作可能会造成retain增加。set操作会默认认为该component已经正确encode了。试图赋值一个非法的percent encode值会抛出异常。虽然 ';' 是一个合法的路径字符,但建议还是percent-encoded一下来兼容NSURL(传递给-stringByAddingPercentEncodingWithAllowedCharacters: URLPathAllowedCharacterSet参数 会将所有的 ';' 字符percent-encode)。
 
Percent-Encoding
 
说起percent-encoding...
 
NSURL 对 CFURLRef 的转换是无缝的。底层的C API有 NSURL 的所有功能。包括 CFURLCreateStringByAddingPercentEscapes 和 CFURLCreateStringByReplacingPercentEscapesUsingEncoding 异常:
 
  • CFURLCreateStringByAddingPercentEscapes:创建一个字符串的copy,用同义的percent-encoded字符代替原有的字符。
  1. CFStringRef CFURLCreateStringByAddingPercentEscapes ( 
  2.    CFAllocatorRef   allocator, 
  3.    CFStringRef      originalString, 
  4.    CFStringRef      charactersToLeaveUnescaped, 
  5.    CFStringRef      legalURLCharactersToBeEscaped, 
  6.    CFStringEncoding encoding 
  7. ); 
 
  • CFURLCreateStringByReplacingPercentEscapesUsingEncoding: 创建一个新字符串,用同义的percent-encoded字符代替原有的所有可替换字符。
  1. CFStringRef CFURLCreateStringByReplacingPercentEscapesUsingEncoding ( 
  2.    CFAllocatorRef   allocator, 
  3.    CFStringRef      origString, 
  4.    CFStringRef      charsToLeaveEscaped, 
  5.    CFStringEncoding encoding 
  6. ); 
Bookmark URL
 
最后一个话题是关于 bookmark URL 的,bookmard URL可以在应用多次启动间安全地引用文件。可以认为是一种对文件描述符的持久化。
 
一个bookmark是一个唯一的数据类型,包含一个描述文件位置的 NSData 对象。鉴于path和文件引用URL在多次启动间可能被破坏,bookmark就可以被用来重建某个文件的URL地址,即使文件被改名或移动了位置也可以。
 
你可以苹果官方的文件系统编程指南的"Locating Files Using Bookmarks"部分中阅读更多关于bookmark URL的内容。
 

CocoaChina是全球最大的苹果开发中文社区,官方微信每日定时推送各种精彩的研发教程资源和工具,介绍app推广营销经验,最新企业招聘和外包信息,以及Cocos2d引擎、Cocos Studio开发工具包的最新动态及培训信息。关注微信可以第一时间了解最新产品和服务动态,微信在手,天下我有!

请搜索微信号“CocoaChina”关注我们!

搜索CocoaChina微信公众号:CocoaChina

顶部