Protocol-based Routing Design in iOS

  IOS development, router, Routing

I. background

Some time ago, we reconstructed the structure of our own App and abandoned the previous simple MVC development pattern. The reason is that with more and more App business lines and more and more complex functions of individual pages, MVC development pattern leads to more and more codes for the whole Controller-layer. This article will share the Router module in refactoring.

Using routing mode can solve the coupling between pages in our project (because our App is driven by the view life cycle, so here it is the page, actually it is the controller layer). because too many functions of a page will lead to too many classes, which will often lead to too many import and difficult management. Moreover, when executing interface jump in iOS, it is easy to generate coupling between modules.

When iOS executes the interface jump, the code is as follows:

[firstViewController.navigationController pushViewController:destinationViewController];

If the header file is directly introduced into the firstViewController, the coupling between modules will result. We need a routing module here to solve similar problems. Our design is that each module has its own routing management. The main responsibilities of routing should be:

  • Management module internal jump.
  • Declare the module’s external interface
  • Declare module dependencies

Second, the jump between modules

This design is loosely coupled. The module we are searching for can be replaced by the module with the same function at any time, thus we realize the decoupling of the two modules.

The current route design is limited to the following:

  • The string identifies the corresponding interface, such as URL Router.
  • Using Object-C characteristics, directly call the method of the destination module
  • Use protocol to Match with an Interface

Iii. URL Router

At present, the vast majority of routes open a page by a string, and the code is roughly as follows:

//注册某个页面在路由的url地址
[URLRouter registURL:@“Desination” handler:^(NSDictionary * userDic){
};
//使用路由
[URLRouter openURL:@“app://***Module/Destionation”];

Passing a string of parameter URL can jump between pages. This scheme can change routing rules at any time when running again, pointing to different pages, and can also support multi-level page jump. This scheme has great flexibility.

Moreover, this scheme is most easily implemented across platforms. iOS, Android,PC and PC can all be routed according to URL.

In iOS, inter-process communication can be carried out through URL Scheme, and a page in App can be opened outside App. This scheme can be perfectly compatible with URL Router.

Of course, that shortcoming of this scheme are also obvious:

First, URL-based design is only suitable for UI interface. Functional modules cannot adopt this scheme, so this scheme is only suitable for view-driven modules.

Second, it is difficult to maintain this scheme. A large number of character strings need to be maintained, as well as parameter transmission.

Third, the security is not high, because errors can only be detected at runtime, similar to the problem that selector used strings to find in early swift.

Protocol Router

This is the routing mode we have adopted. The code is as follows:

id<***ServiceProtocol> service = [[ProtocolRouter shareInstance] findService:@protocol(***service)];

This design scheme is relatively safe, can detect problems in the compilation stage, and is more suitable for swift’s design idea. Any module can be used, including functional modules, not only UI modules. This kind of scheme will lack the corresponding dynamics, but one layer of URL Router’s Adapter layer can be specially used for the requirements of dynamics.

The protocol-based design scheme will not cause coupling, and we can easily replace the target module with the same function. this scheme is also suitable for various decoupling, such as Appdelegate decoupling.

These are the steps we take to implement componentization in the program. With the increase of App capacity, componentization is an essential step. It can make our App more standardized and the reuse of modules higher.

By Cui Xiaodi

Source: Yixin Institute of Technology