iOS杂谈傲视苍穹iOS《Objective-C》VIP专题iOS面试

iOS NSURL 的使用

2017-06-27  本文已影响216人  iTruda

作为一名开发人员,大家肯定对URL非常熟悉吧,但是有多少人对它去做过更深入的了解呢?在很多人眼里也许它就仅仅是一个URL,一个获取数据的接口而已。然而在我看来,它不仅是URL,还是一个通信链。为什么说是通信链呢,因为它可以按我自己制定的规则协议去传达我想要做的事情,尤其是在项目中解耦是非常的好用,这正是我今天所要分享的内容。相信很多人对URL并没有一个完整的认识,我先大致介绍下URL吧。

coverImage.jpg

URL的定义:

在www上,每一信息资源都有统一的且在网上唯一的地址,该地址就叫URL(Uniform Resource Locator,统一资源定位符),它是www的统一资源定位标志,就是指网络地址。

URL的组成:

URL的一般语法格式为(带方括号[]的为可选项):
protocol://hostname[:port]/path/[;parameters][?query]#fragment
完整的、带有授权部分的普通统一资源标志符语法格式为:
协议://用户名:密码@子域名.域名.顶级域名:端口号/目录/文件名.文件后缀?参数=值#标志

URL的格式说明:

1.protocol(协议):

指定使用的传输协议,下表列出 protocol 属性的有效方案名称。 最常用的是 HTTP协议,它也是目前www中应用最广的协议。

2.hostname(主机名):

是指存放资源的服务器的域名系统(DNS) 主机名或 IP 地址。有时,在主机名前也可以包含连接到服务器所需的用户名和密码(格式:username:password@hostname)。

3.port(端口号):

整数,可选,省略时使用方案的默认端口,各种传输协议都有默认的端口号,如http的默认端口为80。如果输入时省略,则使用默认端口号。有时候出于安全或其他考虑,可以在服务器上对端口进行重定义,即采用非标准端口号,此时,URL中就不能省略端口号这一项。

4.path(路径):

由零或多个“/”符号隔开的字符串,一般用来表示主机上的一个目录或文件地址。

5.parameters(参数):

这是用于指定特殊参数的可选项。

6.query(查询):

可选,用于给动态网页(如使用CGI、ISAPI、PHP/JSP/ASP/ASP.NET等技术制作的网页)传递参数,可有多个参数,用“&”符号隔开,每个参数的名和值用“=”符号隔开。

7.fragment(信息片断):

字符串,用于指定网络资源中的片断。例如一个网页中有多个名词解释,可使用fragment直接定位到某一名词解释。

而在 Objective-C 中,这些组成部分可以用系统提供的方法可以很方便的获取到,而不用麻烦的处理一堆字符串,下面给大家举个栗子🌰。

    NSString *urlStr = @"https://www.testurl.com:8080/path/subpath;parms=test_parms?uid=123&gid=45#fragment=009&fragment";
    NSURL    *URL = [NSURL URLWithString:urlStr];
    NSString *absoluteString = URL.absoluteString;
    NSString *baseURL = URL.baseURL.absoluteString;
    NSString *scheme = URL.scheme;
    NSString *host = URL.host;
    NSString *path = URL.path;
    NSArray  *pathComponents = URL.pathComponents;
    NSString *lastPathComponent = URL.lastPathComponent;
    NSString *pathExtension = URL.pathExtension;
    NSString *query = URL.query;
    NSString *fragment = URL.fragment;
    NSString *parameterString = URL.parameterString;
    NSString *relativePath = URL.relativePath;
    NSString *port = [URL.port stringValue];
    NSString *user = URL.user;
    NSString *password = URL.password;
    
    // absoluteString = https://www.testurl.com:8080/path/subpath;parms=test_parms?uid=123&gid=45#fragment=009&fragment
    NSLog(@"absoluteString = %@", absoluteString);
    // baseURL = (null)
    NSLog(@"baseURL = %@", baseURL);
    // scheme = https
    NSLog(@"scheme = %@", scheme);
    // host = www.testurl.com
    NSLog(@"host = %@", host);
    // port = 8080
    NSLog(@"port = %@", port);
    // path = /path/subpath
    NSLog(@"path = %@", path);
    // pathComponents = ("/", path, subpath)
    NSLog(@"pathComponents = %@", pathComponents);
    // lastPathComponent = subpath
    NSLog(@"lastPathComponent = %@", lastPathComponent);
    // pathExtension = @""  //<object returned empty description>
    NSLog(@"pathExtension = %@", pathExtension);
    // query = uid=123&gid=45
    NSLog(@"query = %@", query);
    // fragment = fragment=009&fragment
    NSLog(@"fragment = %@", fragment);
    // relativePath = /path/subpath (The same as path if baseURL is nil)
    NSLog(@"relativePath = %@", relativePath);
    // parameterString = parms=test_parms
    NSLog(@"parameterString = %@", parameterString);
    // user = (null)
    NSLog(@"user = %@", user);
    // password = (null)
    NSLog(@"password = %@", password);

----------------------------- 分割线(下面才是重点) -----------------------------

URL的使用:

文章开头我说URL还是一个通信链,因为我可以通过一个URL可以得到我任何想要的信息,当然前提是我们得有一套规则协议去约束URL。下面举几个小例子:
协议规则:https://www.test.com/path?action=xxx&id=xxx
前缀是:https://www.test.com/path?
action:告诉我想要做的事
id:具体详情id(如果不需要的话,可以不传)
🌰1:
URL = https://www.test.com/path?action=video&id=12345
说明:https://www.test.com/path-> 前缀,action=video -> 做跳转到视频详情处理,id=12345 -> 视频id是12345。

🌰2:
URL = https://www.test.com/path?action=user&id=666
说明:https://www.test.com/path -> 前缀,action=user -> 做跳转到用户主页处理,id=666 -> 用户id是666。

当然根据你自己的需求,这个URL随便你怎么定制,比如:URL = xhc://home.com/video/detail?id=12345(跳转首页模块下的视频详情,视频id是12345),URL = xhc://store.com/goods/detail?id=88888(跳转商城模块下的商品详情,商品id是88888)
通过以上的例子大家应该知道了URL是如何传递信息的。有的同学也许会有疑问,这有什么用呢,我明明知道跳转到哪里,直接push不就得了。但是如果是动态类型的跳转呢?如果是降低耦合度呢?该如何去做。
就拿第一种情况来说(动态类型的跳转),我们在点击一个首页banner时需要根据服务端的配置数据,进行动态的跳转,配置不同,跳转页面不同。我们可以像上面这样去规划,做一个中间层去管理,也许跳转类型少看不出什么效果,但是跳转类型多的话,这种方法效果还是不错的,至少各种跳转逻辑很清晰,而且服务端也好控制。
第二种种情况(项目模块之间解耦),其实是涉及到组件化架构的,我们为了降低项目内部的耦合度,使每个模块之间解耦,为了解耦我们需要做的一件事情就是设计一个类似于路由的中间层,让Router去处理各种逻辑,在此当然不止是跳转,比如点赞,获取一个NSObject对象等等。而这个Router的设计就需要用到上面的原理,其实说白了就是按约定好的规则去解析URL,最后按各种参数返回给你,至于做什么,你自己处理,但前提是你得先注册这个URL的规则匹配,这个Router的设计有兴趣的同学可以看看蘑菇街的MGJRouter。后面我有空会把组件化架构整理一下,供大家参考理解,共同学习交流。

也许有人会问,这不就是字符串嘛,干嘛还非得搞个URL去处理。当然字符串也可以处理,但是我感觉用系统的NSURL一些方法处理起来更方便一点,获取某些参数或值的时候更简洁一点,当然这也看个人喜好和业务需求,怎样用方便,喜欢用什么就用什么,毕竟条条大路通罗马。😂😂😂

上一篇 下一篇

猜你喜欢

热点阅读