iOS NSURL 的使用

作為一名開發(fā)人員,大家肯定對URL非常熟悉吧,但是有多少人對它去做過更深入的了解呢?在很多人眼里也許它就僅僅是一個URL,一個獲取數(shù)據(jù)的接口而已。然而在我看來,它不僅是URL,還是一個通信鏈。為什么說是通信鏈呢,因為它可以按我自己制定的規(guī)則協(xié)議去傳達我想要做的事情,尤其是在項目中解耦是非常的好用,這正是我今天所要分享的內(nèi)容。相信很多人對URL并沒有一個完整的認識,我先大致介紹下URL吧。

coverImage.jpg

URL的定義:

在www上,每一信息資源都有統(tǒng)一的且在網(wǎng)上唯一的地址,該地址就叫URL(Uniform Resource Locator,統(tǒng)一資源定位符),它是www的統(tǒng)一資源定位標(biāo)志,就是指網(wǎng)絡(luò)地址。

URL的組成:

URL的一般語法格式為(帶方括號[]的為可選項):
protocol://hostname[:port]/path/[;parameters][?query]#fragment
完整的、帶有授權(quán)部分的普通統(tǒng)一資源標(biāo)志符語法格式為:
協(xié)議://用戶名:密碼@子域名.域名.頂級域名:端口號/目錄/文件名.文件后綴?參數(shù)=值#標(biāo)志

URL的格式說明:

1.protocol(協(xié)議):

指定使用的傳輸協(xié)議,下表列出 protocol 屬性的有效方案名稱。 最常用的是 HTTP協(xié)議,它也是目前www中應(yīng)用最廣的協(xié)議。

  • http 通過 HTTP 訪問該資源。 格式 http://
  • https 通過安全的 HTTPS 訪問該資源。 格式 https://
  • file 資源是本地計算機上的文件。 格式 file:///(注意后邊應(yīng)是三個斜杠)
  • ftp 通過 FTP 訪問該資源。 格式 ftp://
  • gopher 通過 Gopher 協(xié)議訪問該資源。
  • mailto 資源為電子郵件地址,通過 SMTP 訪問。 格式 mailto:
  • MMS 通過支持 MMS(流媒體)協(xié)議的播放該資源。(代表軟件:Windows Media Player) 格式 MMS://
  • ed2k 通過支持 ed2k(專用下載鏈接)協(xié)議的 P2P 軟件訪問該資源。(代表軟件:電驢) 格式 ed2k://
  • Flashget 通過支持 Flashget:(專用下載鏈接)協(xié)議的 P2P 軟件訪問該資源。(代表軟件:快車) 格式 Flashget://
  • thunder 通過支持 thunder(專用下載鏈接)協(xié)議的 P2P 軟件訪問該資源。(代表軟件:迅雷) 格式 thunder://
  • news 通過 NNTP 訪問該資源。
2.hostname(主機名):

是指存放資源的服務(wù)器的域名系統(tǒng)(DNS) 主機名或 IP 地址。有時,在主機名前也可以包含連接到服務(wù)器所需的用戶名和密碼(格式:username:password@hostname)。

3.port(端口號):

整數(shù),可選,省略時使用方案的默認端口,各種傳輸協(xié)議都有默認的端口號,如http的默認端口為80。如果輸入時省略,則使用默認端口號。有時候出于安全或其他考慮,可以在服務(wù)器上對端口進行重定義,即采用非標(biāo)準(zhǔn)端口號,此時,URL中就不能省略端口號這一項。

4.path(路徑):

由零或多個“/”符號隔開的字符串,一般用來表示主機上的一個目錄或文件地址。

5.parameters(參數(shù)):

這是用于指定特殊參數(shù)的可選項。

6.query(查詢):

可選,用于給動態(tài)網(wǎng)頁(如使用CGI、ISAPI、PHP/JSP/ASP/ASP.NET等技術(shù)制作的網(wǎng)頁)傳遞參數(shù),可有多個參數(shù),用“&”符號隔開,每個參數(shù)的名和值用“=”符號隔開。

7.fragment(信息片斷):

字符串,用于指定網(wǎng)絡(luò)資源中的片斷。例如一個網(wǎng)頁中有多個名詞解釋,可使用fragment直接定位到某一名詞解釋。

而在 Objective-C 中,這些組成部分可以用系統(tǒng)提供的方法可以很方便的獲取到,而不用麻煩的處理一堆字符串,下面給大家舉個栗子??。

    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可以得到我任何想要的信息,當(dāng)然前提是我們得有一套規(guī)則協(xié)議去約束URL。下面舉幾個小例子:
協(xié)議規(guī)則: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 -> 做跳轉(zhuǎn)到視頻詳情處理,id=12345 -> 視頻id是12345。

??2:
URL = https://www.test.com/path?action=user&id=666
說明:https://www.test.com/path -> 前綴,action=user -> 做跳轉(zhuǎn)到用戶主頁處理,id=666 -> 用戶id是666。

當(dāng)然根據(jù)你自己的需求,這個URL隨便你怎么定制,比如:URL = xhc://home.com/video/detail?id=12345(跳轉(zhuǎn)首頁模塊下的視頻詳情,視頻id是12345),URL = xhc://store.com/goods/detail?id=88888(跳轉(zhuǎn)商城模塊下的商品詳情,商品id是88888)
通過以上的例子大家應(yīng)該知道了URL是如何傳遞信息的。有的同學(xué)也許會有疑問,這有什么用呢,我明明知道跳轉(zhuǎn)到哪里,直接push不就得了。但是如果是動態(tài)類型的跳轉(zhuǎn)呢?如果是降低耦合度呢?該如何去做。
就拿第一種情況來說(動態(tài)類型的跳轉(zhuǎn)),我們在點擊一個首頁banner時需要根據(jù)服務(wù)端的配置數(shù)據(jù),進行動態(tài)的跳轉(zhuǎn),配置不同,跳轉(zhuǎn)頁面不同。我們可以像上面這樣去規(guī)劃,做一個中間層去管理,也許跳轉(zhuǎn)類型少看不出什么效果,但是跳轉(zhuǎn)類型多的話,這種方法效果還是不錯的,至少各種跳轉(zhuǎn)邏輯很清晰,而且服務(wù)端也好控制。
第二種種情況(項目模塊之間解耦),其實是涉及到組件化架構(gòu)的,我們?yōu)榱私档晚椖績?nèi)部的耦合度,使每個模塊之間解耦,為了解耦我們需要做的一件事情就是設(shè)計一個類似于路由的中間層,讓Router去處理各種邏輯,在此當(dāng)然不止是跳轉(zhuǎn),比如點贊,獲取一個NSObject對象等等。而這個Router的設(shè)計就需要用到上面的原理,其實說白了就是按約定好的規(guī)則去解析URL,最后按各種參數(shù)返回給你,至于做什么,你自己處理,但前提是你得先注冊這個URL的規(guī)則匹配,這個Router的設(shè)計有興趣的同學(xué)可以看看蘑菇街的MGJRouter。后面我有空會把組件化架構(gòu)整理一下,供大家參考理解,共同學(xué)習(xí)交流。

也許有人會問,這不就是字符串嘛,干嘛還非得搞個URL去處理。當(dāng)然字符串也可以處理,但是我感覺用系統(tǒng)的NSURL一些方法處理起來更方便一點,獲取某些參數(shù)或值的時候更簡潔一點,當(dāng)然這也看個人喜好和業(yè)務(wù)需求,怎樣用方便,喜歡用什么就用什么,畢竟條條大路通羅馬。??????

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容