iOS 模組化之 JLRoute 路由示例 ?

WhatsXie發表於2018-02-07

基於 JLRoute 實現的模組化示例,包括連結跳轉原生頁面、WebView頁面和ReactNative頁面 ?

模組化已經成為調劑龐大專案結構的一劑良藥,對專案的開發、維護和後續的擴充套件的好處已經不言而喻。

iOS 模組化之 JLRoute 路由示例 ?


? 要求

  • iOS 8.0+
  • Xcode 7.0+

? 安裝方法

安裝

iOS, 你需要在 Podfile 中新增.

source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '9.0'
use_frameworks!

pod 'JLRoutes', '~> 2.0.1'

# 'node_modules'目錄一般位於根目錄中
# 但是如果你的結構不同,那你就要根據實際路徑修改下面的`:path`
pod 'React', :path => './node_modules/react-native', :subspecs => [
    'Core',
    'RCTText',
    'RCTNetwork',
    'RCTWebSocket', # 這個模組是用於除錯功能的
    # 在這裡繼續新增你所需要的模組
]
# 如果你的RN版本 >= 0.42.0,請加入下面這行
pod "Yoga", :path => "./node_modules/react-native/ReactCommon/yoga"
複製程式碼

啟動 ReactNative 環境

1.修改專案ModuleARNPageViewController.m IP 跳轉地址

iOS 模組化之 JLRoute 路由示例 ?

2.進入專案所在目錄,執行(首次執行需要 npm install)

npm start
複製程式碼

? JLRoutes的工作流程和原理

單一的Scheme註冊過程:

iOS 模組化之 JLRoute 路由示例 ?

1.呼叫註冊方法(使用者註冊routePattern,預設優先順序0)

- (void)addRoute:(NSString *)routePattern handler:(BOOL (^__nullable)(NSDictionary<NSString *, id> *parameters))handlerBlock;
複製程式碼

2.路由解析(這些解析跟我們設定路由的規則有直接關係)

(1)判斷介面URL是否設定可選性URL並將對應的URL封裝成JLRRouteDefinition物件

(2)將JLRRouteDefinition物件裝載進一個可變陣列,記憶體保留了所有的物件!!

(JLRRouteDefinition物件包括有路徑,引數解析,block等資訊)

單一的Scheme呼叫過程:

1.呼叫URL

+ (BOOL)routeURL:(NSURL *)URL
複製程式碼

2.解析URL,將引數,路由資訊封裝成JLRRouteRequest物件

- (instancetype)initWithURL:(NSURL *)URL alwaysTreatsHostAsPathComponent:(BOOL)alwaysTreatsHostAsPathComponent
複製程式碼

3.給JLrouteRequest物件和路由陣列裡的JLRRouteDefinition物件作比對,並且返回JLRRouteResponse 物件抽出引數和URL在陣列裡

JLRRouteResponse *response = [route routeResponseForRequest:request decodePlusSymbols:shouldDecodePlusSymbols];
複製程式碼

4.呼叫JLRRouteResponse 物件裡面的回撥方法

[route callHandlerBlockWithParameters:finalParameters];
複製程式碼

JLRoutes的URL註冊規則:

iOS 模組化之 JLRoute 路由示例 ?

1.普通註冊

JLRoutes *routes = [JLRoutes globalRoutes];
[routes addRoute:@"/user/view/:userID" handler:^BOOL(NSDictionary *parameters) {
NSString *userID = parameters[@"userID"]; // defined in the route by specifying ":userID"
// present UI for viewing user with ID 'userID'
return YES; // return YES to say we have handled the route
}];
複製程式碼

URL裡,分號表示這個是引數

另外一種註冊方式,下標註冊法

JLRoutes.globalRoutes[@"/route/:param"] = ^BOOL(NSDictionary *parameters) {
// ...
};
複製程式碼

如何按照以上的方式註冊,在任何時刻(包括在其它的APP)你都可以呼叫這個URL。

NSURL *viewUserURL = [NSURL URLWithString:@"myapp://user/view/joeldev"];
[[UIApplication sharedApplication] openURL:viewUserURL];
複製程式碼

在這個例子中,在parmameters字典裡面的userID會傳給block,它是一個鍵值對。”userID”: “joeldev”。給UI層或者任何需要它的地方用的。

字典引數:

字典引數總包括至少一下3個鍵:

{
"JLRouteURL":  "(the NSURL that caused this block to be fired)",
"JLRoutePattern": "(the actual route pattern string)",
"JLRouteScheme": "(the route scheme, defaults to JLRoutesGlobalRoutesScheme)"
}
複製程式碼

處理Block

你會發現,每個註冊的block都會返回一個YES。這個值,如果你返回NO,JLRoutes會跳過這個匹配,然後繼續去匹配其它的。

如果你的block設定成nil,它會預設返回YES。

2.複雜註冊

[[JLRoutes globalRoutes] addRoute:@"/:object/:action/:primaryKey" handler:^BOOL(NSDictionary *parameters) {
NSString *object = parameters[@"object"];
NSString *action = parameters[@"action"];
NSString *primaryKey = parameters[@"primaryKey"];
// stuff
return YES;
}];
複製程式碼

這個地址會被匹配很多URL,如/user/view/joeldev or /post/edit/123。這些URL上的是引數。

NSURL *editPost = [NSURL URLWithString:@"myapp://post/edit/123?debug=true&foo=bar"];
[[UIApplication sharedApplication] openURL:editPost];
複製程式碼

這時,pramater字典就會是以下這樣的(傳參)

{
"object": "post",
"action": "edit",
"primaryKey": "123",
"debug": "true",
"foo": "bar",
"JLRouteURL": "myapp://post/edit/123?debug=true&foo=bar",
"JLRoutePattern": "/:object/:action/:primaryKey",
"JLRouteScheme": "JLRoutesGlobalRoutesScheme"
}
複製程式碼

3.Scheme(有沒有多型的感覺)

JLRoutes支援用指定的URL scheme來建立路由。相同的scheme才能被匹配。預設地,所有的URL會設定進global scheme。

[[JLRoutes globalRoutes] addRoute:@"/foo" handler:^BOOL(NSDictionary *parameters) {
// This block is called if the scheme is not 'thing' or 'stuff' (see below)
return YES;
}];
[[JLRoutes routesForScheme:@"thing"] addRoute:@"/foo" handler:^BOOL(NSDictionary *parameters) {
// This block is called for thing://foo
return YES;
}];
[[JLRoutes routesForScheme:@"stuff"] addRoute:@"/foo" handler:^BOOL(NSDictionary *parameters) {
// This block is called for stuff://foo
return YES;
}];
複製程式碼

如果你呼叫的使用,是這樣呼叫的

[[JLRoutes globalRoutes] addRoute:@"/global" handler:^BOOL(NSDictionary *parameters) {
return YES;
}];
複製程式碼

它只會呼叫global scheme的對應的URL。不會呼叫ting scheme裡面對應的URL。

當然,你可以設定,如果指定的scheme沒有這個URL,去查詢global scheme 有沒有。你需要設定一個屬性。

[JLRoutes routesForScheme:@"thing"].shouldFallbackToGlobalRoutes = YES;
複製程式碼

3.萬用字元的設定URL的方式

萬用字元為:*

萬用字元符後面所有的URL上的引數都會以一個陣列儲存在parameters字典裡面的JLRouteWildcardComponentsKey對應的value裡。

例如,如果你註冊URL如下:

[[JLRoutes globalRoutes] addRoute:@"/wildcard/*" handler:^BOOL(NSDictionary *parameters) {
NSArray *pathComponents = parameters[JLRouteWildcardComponentsKey];
if ([pathComponents count] > 0 && [pathComponents[0] isEqualToString:@"joker"]) {
// the route matched; do stuff
return YES;
}
// not interested unless the joker's in it
return NO;
}];
複製程式碼

如果呼叫的URL開始是/wildcard,這個路由就可能被觸發!!如果第一個引數是joker,就被觸發,如果不是,就被拒絕觸發。。。

4.選擇性路由

如果路由地址設定樣式有括號,如:/the(/foo/:a)(/bar/:b),其實它代表的URL有如下:

/the/foo/:a/bar/:b
/the/foo/:a
/the/bar/:b
/the
複製程式碼

5.查詢Routes

下面的方式,你可以檢視Routes裡所有註冊的URL Routes。

/// All registered routes, keyed by scheme
+ (NSDictionary <NSString *, NSArray <JLRRouteDefinition *> *> *)allRoutes;
/// Return all registered routes in the receiving scheme namespace.
- (NSArray <JLRRouteDefinition *> *)routes;
複製程式碼

自定義路由解析 如果你想自己定製一個路由編輯,你可以繼承JLRouteDefinition並且用 addRoute:方法去新增你自定義類的物件。


? 調研來源

JLRoutes:github.com/joeldev/JLR…

JLRoutes資料部落格:www.varsiri.com/archives/30…


? 聯絡

相關文章