The most commonly used mode of iOS decoupling and componentalization is unified hop routing. Currently, the commonly used iOS open source routing frameworks are JLRoutes, MGJRouter, HHRouter, etc. These routing frameworks have their own advantages and disadvantages and can basically meet most requirements. At present, it is most commonly used as a route jump to realize basic component-based development and decoupling between modules. However, in practical development, it will be found that they cannot be completely used to complete all inter-module communication, such as synchronous and asynchronous communication between modules. For example, after configuring the URL of the relevant route hop, how to dynamically modify the relevant hop logic after going online? How to dynamically modify related parameters when modules are communicating with each other? Can APP realize 302 jump similar to Web? FFRouter was born! FFRouter is a routing framework born after referring to other open source frameworks. FFRouter not only supports route jump, but also supports synchronous and asynchronous communication between modules. Rewrite engine was added, which can dynamically modify the corresponding routing logic and parameters after the APP goes online, and support the use of regular syntax to create Rewrite rules, making it more flexible. As for URL Rewrite, Tmall was used to solve the problem of URL platform display consistency in App, and played an important role in full-link interface degradation scheme and conference offline during Double 11. FFRouter’s URL Rewrite also referred to tmall’s scheme. The main uses of FFRouter are as follows: (from Github :FFRouter)

Making links:FFRouter

function

  • Have basic URL registration, Route, unregister, print Log, etc
  • URL registration with wildcard character (*) is supported
  • Support URL Rewrite
  • Rewrite is supported to retrieve original URL parameters or URLComponents and to Encode or Decode them
  • Object can be obtained from URL
  • When a Route URL is supported, an Object can be obtained through asynchronous callback
  • Passing unconventional objects when Route urls are supported
  • Supports unified callback when routing an unregistered URL

The installation

CocoaPods

target 'MyApp' do
  pod 'FFRouter'
end
Copy the code

Run the pod install

Manual installation

Add the FFRouter folder to your project

Method of use

First of all,

#import "FFRouter.h"
Copy the code
1. Basic use
/** Register url with 'routeURL:' and 'routeURL:' @param handlerBlock URL is a callback */ + after the Route (void)registerRouteURL:(NSString *)routeURL handler:(FFRouterHandler)handlerBlock; /** Register URL with 'routeObjectURL:' and 'routeObjectURL:' @param handlerBlock Is a callback to the URL that has been routeed. An Object */ + is returned in the callback (void)registerObjectRouteURL:(NSString *)routeURL handler:(FFObjectRouterHandler)handlerBlock; /** Register URL with 'routeCallbackURL: targetCallBack:' and 'routeCallbackURL: withParameters:' TargetCallBack: 'used with, An asynchronous callback returns an Object@param routeURL the URL to be registered. @param handlerBlock The callback to the URL after it is routeed. The handlerBlock has a targetCallBack corresponding to 'routeCallbackURL: targetCallBack:' and 'routeCallbackURL: withParameters: TargetCallBack: 'targetCallBack, Can be used in an asynchronous callback returns an Object * / + (void) registerCallbackRouteURL: (routeURL nsstrings *) handler:(FFCallbackRouterHandler)handlerBlock; /** canRouteURL:(NSString *)URL; /** canRouteURL:(NSString *)URL; /** routeURL (NSString *)URL; /** Route a URL, @param URL specifies the URL of the Route. @param parameters specifies the extra parameter */ + (void)routeURL:(NSString *)URL withParameters:(NSDictionary<NSString *, id> *)parameters; /** routeObjectURL (NSString *)URL; /** routeObjectURL (NSString *)URL; /** Route a URL with extra parameters, Object */ + (id)routeObjectURL:(NSString *)URL  withParameters:(NSDictionary<NSString *, id> *)parameters; /** Route a URL,targetCallBack can be asynchronous callback to return an Object @param URL to Route @param targetCallBack asynchronous callback */ + (void)routeCallbackURL:(NSString *)URL targetCallback:(FFRouterCallback)targetCallback; /** Route a URL with an extra parameter. TargetCallBack can be asynchronously called back to return an Object @param URL. @param parameters */ + (void)routeCallbackURL:(NSString *)URL withParameters:(NSDictionary<NSString *, id> *)parameters targetCallback:(FFRouterCallback)targetCallback; / * * the Route an unregistered URL callback @ param handler callback * / + (void) routeUnregisterURLHandler (FFRouterUnregisterURLHandler) handler; /** unregister a URL @param URL URL to be unregistered */ + (void)unregisterRouteURL:(NSString *)URL; /** unregister all urls */ + (void)unregisterAllRoutes; @param enable YES or NO, default is NO */ + (void)setLogEnabled:(BOOL)enable;Copy the code
【 note 】

(1) the registered URL:

[FFRouter registerRouteURL:@"protocol://page/routerDetails/:id" handler:^(NSDictionary *routerParameters) { //routerParameters contains all the parameters that have been passed}]; [FFRouter registerRouteURL:@"wildcard://*" handler:^(NSDictionary *routerParameters) {// This is a callback to the RouteURL //routerParameters contains all the parameters passed in}]; [FFRouter registerRouteURL:@"protocol://page/routerObjectDetails" handler:^(NSDictionary *routerParameters) { //routerParameters contains all the parameters that have been passed}];Copy the code

RouterParameters [FFRouterParameterURLKey] is the complete URL. If the following method is required:

+ (id)routeObjectURL:(NSString *)URL;
Copy the code

To Route a URL and get the return value, register the URL as follows:

+ (void)registerObjectRouteURL:(NSString *)routeURL handler:(FFObjectRouterHandler)handlerBlock;
Copy the code

And return the desired Object in the handlerBlock, for example:

/ / register, and returns the value of necessary [FFRouter registerObjectRouteURL: @ "protocol: / / page/routerObjectDetails" handler: ^ id (NSDictionary *routerParameters) {NSString * STR = @" return necessary Object as needed "; return STR;}]; / / get the value returned nsstrings * ret = [FFRouter routeObjectURL: @ "protocol: / / page/routerObjectDetails"].Copy the code

(3) If you want to get the returned Object through the asynchronous callback after routeURL, you can use the following method to register and Route URL:

/ / register and in the necessary time back to corresponding to the Object by the callback [FFRouter registerCallbackRouteURL: @ "protocol: / / page/RouterCallbackDetails" handler:^(NSDictionary *routerParameters, {// Return the corresponding Object targetCallBack(@" any Object");}]; // Get the returned Object [FFRouter] via the 'targetCallback' callback routeCallbackURL:@"protocol://page/RouterCallbackDetails?nickname=imlifengfeng" targetCallback:^(id callbackObjc) { self.testLabel.text = [NSString stringWithFormat:@"%@",callbackObjc]; }];Copy the code

(4) If you need to pass unconventional objects as parameters, such as UIImage, the following methods can be used:

[FFRouter routeURL:@"protocol://page/routerDetails?nickname=imlifengfeng" withParameters:@{@"img":[UIImage imageNamed:@"router_test_img"]}];
Copy the code

If you only need to pass common parameters, concatenate the parameters directly after the URL:

[FFRouter routeURL:@"protocol://page/routerDetails?nickname=imlifengfeng&id=666&parameters......"] ;Copy the code

These parameters are then retrieved from the routerParameters. For example: routerParameters [@ “nickname”]

2, the URL Rewrite
/** Rewrite a URL @param will rewrite URL @return rewrite URL */ + (NSString) *)rewriteURL:(NSString *)url; /** add a RewriteRule @param matchRule regular matching rule @param targetRule conversion rule */ + (void)addRewriteMatchRule:(NSString *)matchRule  targetRule:(NSString *)targetRule; /** Add multiple RewriteRule at the same time, the format must be @[@{@"matchRule":@"YourMatchRule",@"targetRule":@"YourTargetRule"},...  @param rules RewriteRules */ + (void)addRewriteRules:(NSArray<NSDictionary *> *)rules; /** removeRewriteMatchRule:(NSString *)matchRule; /** removeRewriteMatchRule:(NSString *)matchRule; /** Remove all RewriteRule */ + (void)removeAllRewriteRules;Copy the code
【 note 】

(1) You can use re to add a Rewrite rule, for example: To implement open URL:https://www.taobao.com/search/ the atomic bomb, the interception, switching to local registered URL: protocol: / / page/routerDetails? Product = open the nuclear bomb. First add a Rewrite rule:

[FFRouterRewrite addRewriteMatchRule:@"(?:https://)?www.taobao.com/search/(.*)" targetRule:@"protocol://page/routerDetails?product=$1"];
Copy the code

After the opening URL:https://www.taobao.com/search/ atomic bombs, will Rewrite the URL: protocol: / / page/routerDetails? Product = the atomic bomb.

[FFRouter routeURL: @ https://www.taobao.com/search/ "atomic bomb"].Copy the code

(2) Multiple rules can be added at the same time by the following methods:

+ (void)addRewriteRules:(NSArray<NSDictionary *> *)rules;
Copy the code

The rules format must be the following:

@[@{@"matchRule":@"YourMatchRule1",@"targetRule":@"YourTargetRule1"},
  @{@"matchRule":@"YourMatchRule2",@"targetRule":@"YourTargetRule2"},
  @{@"matchRule":@"YourMatchRule3",@"targetRule":@"YourTargetRule3"},]
Copy the code

(3)Rewrite rules:

  • through$scheme,$host,$port,$path,$query,$fragmentGets the corresponding part of the standard URL. through$urlGet the full URL
  • throughThe $1,$2,$3. To obtainmatchRuleArguments retrieved using parentheses in the re of
  • $: The value of the original variable,?: the value of the original variable URL Encode,$#: The value of the original variable URL after Decode

For example: the atomic bomb to Rewrite rules (? 🙂 https:// https://www.taobao.com/search/? www.taobao.com/search/ (. *)

$1= atomic bomb? 1=%e5%8e%9f%e5%ad%90%e5%bc%b9Copy the code

Similarly, https://www.taobao.com/search/%e5%8e%9f%e5%ad%90%e5%bc%b9 for Rewrite rules (? 🙂 https://? www.taobao.com/search/ (. *)

$1=% E5%8E % 9F % E5 % AD %90% E5 % BC %b9 $#1= Atomic bombCopy the code
2, FFRouterNavigation

Since routes are often used to configure jumps between UIViewControllers, an additional tool FFRouterNavigation was added to make it easier to control jumps between UIViewControllers. Specific use methods are as follows:

/ * * at the bottom of the push is automatically hidden TabBar @ param hide automatically hidden, the default is NO * / + (void) autoHidesBottomBarWhenPushed (BOOL) hide; @return currentViewController */ + (UIViewController *)currentViewController; NavigationViewController @return return NavigationViewController */ (nullable UINavigationController *)currentNavigationViewController; /** Push ViewController @param ViewController Push ViewController @param ViewController whether animated */ + (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated; / * * Push ViewController, You can set whether the current ViewController retains @param ViewController Push ViewController @param replace Whether the current ViewController retains @param Whether animated */ + (void)pushViewController:(UIViewController *)viewController replace:(BOOL)replace animated:(BOOL)animated; /** Push multiple viewControllers @param viewControllers Array @param animated */ + (void)pushViewControllerArray:(NSArray *)viewControllers animated:(BOOL)animated; /** present ViewController@param viewController@param Completion callback */ + (void)presentViewController:(UIViewController *)viewController animated:(BOOL)animated completion:(void (^ __nullable)(void))completion; / * * close the current ViewController, push, the present general @ param animated * / + (void) whether to use animation closeViewControllerAnimated (BOOL) animated;Copy the code

Thank you

The FFRouter implementation is based on the following article, thank you!

  • Tmall decouple artifact – Jump protocol and Rewrite engine
  • The componentization of Mogujie App