IOS analysis of routing design patterns

Since the project uses a routing design pattern, every time the test tells me that I have a bug, my brother smiles and tells her that this is the server’s Bug

1. what is routing?

In the Web development process, the concept of routing is often encountered. So, what exactly is routing? In simple terms, routing is the mapping of URL to function.

2., the difference between router and route

Route is a route that maps a URL path to a function, for example:

/users -> getAllUsers () /users/count -> getUsersCount ()

This is the two route, which performs the getAllUsers () function when accessing the /users, and executes the getUsersCount () function when accessing the /users/count.

Router can be understood as a container, or a mechanism that manages a set of route. In simple terms, route simply maps URL and functions, and when you receive a URL, go to the routing map to find the corresponding function, which is handled by router. In a word, the generalization is “The router routes you to a route””.

There’s nothing wrong with it. There’s only one sentence that works: routing is the mapping of URL to function. For example, “User/login”, the login method under the User controller.

First, we compare the project structure of our previous structure model and join the routing mechanism after the implementation of the routing mechanism, not only need a mapping file, we also need a routing management mechanism, so the routing mechanism, our project framework is not the same with the original.

IOS analysis of routing design patterns
did not eat idiotic tablets before.Png

, let’s see what disadvantages it has:
(1) introduces the class class of the jump page in the current page. This creates a high coupling of the page.
(2) encountered a major bug, can not fix the problem in time, you need to wait until the update version can be resolved.
(3) push messages or 3D-Touch requirements, requiring direct jump to the internal tenth level interface, then you need to write an entry to the specified interface.

After IOS analysis of routing design patterns
ate brain fragments,.Png

Two, App routing can solve what problems?

Consider the following questions: how gracefully do we develop them at ordinary times?:

The 1.3D-Touch function, or click push messages, requires an external jump to a deep level interface within the App.

For example, WeChat’s 3D-Touch can jump directly to my “two-dimensional” code”. “My two-dimensional code” interface is in my third level interface. Or even more extreme, product demand to the more abnormal needs, and asked to jump to App tenth layers of internal interface, how to deal with?

2., a series of App between their own how to jump each other?

If you have several App, each other also want to jump between each other, how to deal with?

3. how do you remove the coupling between App components and App pages?

As the project becomes more complex, the logical association between each component and the pages is increasing. How can gracefully eliminate the coupling between components and pages?

4., how can you unify the page Jump logic at both ends of iOS and Android? How can you even unify requests for resources from the three end?

Some of the modules within the project will blend the ReactNative, Weex, and H5 interfaces that will also invoke the interface of the Native and the components of the Native. So, how can you unify the Web side and Native side requests for resources?

5., if the dynamic down configuration file is used to configure App’s jump logic, what if both sides of iOS and Android share only one set of configuration files?

6., if App appears bug, how can you do a simple thermal recovery function without using JSPatch?

For example, App online suddenly encountered an emergency bug, can you dynamically downgrade pages to H5, ReactNative, Weex? Or is it changed to a local error interface?

7. how do you do the buried point statistics between each component call and the page Jump? Where does each jump point to handwritten code? Using Runtime AOP?

8. how to join the call logic check, token mechanism, and gray level for the control logic in the process of calling between components

9. how can you call the same interface or the same component on any App interface? Can only be registered in AppDelegate single example to achieve?

For example, App has problems, and users may be forced to log out at any interface, anytime, anywhere Or force all to jump to the same local error interface? Or jump to the corresponding H5, ReactNative, Weex interface? How do you get users to pop up a View at any interface, anytime, anywhere?

All of these problems can be solved by designing a App terminal. So how do we design a route?

(void) + processActionURL: (NSString*) actionURL andWithAction: (NSString* action) {NSDictionary = ACTION_MAP * / * * @ @{browser "browser": @ "HSWebViewController" / * * / details: @ @ "news_detail", "HSNewsDetailController" / * * / post details: @ @ "topic_detail" "HSTopicDatailTableViewController" / * chapter list @ @ * "material_detail": "HSMaterialDetailTableViewController" / * * / data management @ material_manage: @ "MaterialManage" / * * / topic shows "question_detail": @ @ "HSMaterialQuestionController" / * * / @ the details of "article_detail": "@", questionnaire @ * / / * "survey_detail": "@" / * * / package details, @: @ "" meal_detail "" / * * / "course_detail" course details @: @ "/ * * / @ purchase page" Purchase: @ HSPayViewController, @ * / / * list page "search_list": @ HSComonSearchTBV, @ * / / * user help page "guide": @ HSHelpCenterViewController, @ * / / * scan two-dimensional code "QRcode": @ HSScanViewController, @ * / / * receive course "playcode": @ HSPlayCodeViewController "my course, / * * / @ my_course @:", "/ * * / personal settings @" profile_setting ": @ HSPensonalSettingController, @ * / / * system set" system_setting ": @ HSSettingController, @ * / / * user information" user_info ": @" HSUserInfoVC "}; NSDictionary * dict = [HSNetUrlProcess queryDictWithUrlString:actionURL]; if ([action isEqualToString:@" browser "]) {/ / the 0 jump to the browser HSWebViewController * webView = [[HSWebViewCont Roller alloc]init]; webView.urlStr = dict[HSOBJ_URL]; webView.hidesBottomBarWhenPushed = YES; [[HSTool getCurrentVC].navigationController pushViewController:webView animated:YES] else if;} ([action isEqualToString:@ "news_detail" //1 ") {HSNewsDetailController *newsVC=[[HSNewsDetailController alloc]init]; newsVC.param=dict [[HSTool; getCurrentVC].navigationController pushViewController:newsVC animated:YES];} else if ([action isEqualToString:@" topic_detail "//2") {HSTopicDatailTableViewController topicDetail = [[HSTopicDatailTableViewController * alloc]init]; topicDetail.param = dict; [[HSTool getCurrentVC].navigationController pushViewController:t OpicDetail animated:YES]; else if} ([action isEqualToString:@ "material_detail" //3 ") {HSMaterialDetailTableViewController *materialDeialVC=[[HSMaterialDetailTableViewController alloc]init]; materialDeialVC.param=dict [[HSTool getCurrentVC];.NavigationController pushViewController:materialDeialVC animated:YES];} else if ([action isEqualToString:@" material_manage "//4") {MaterialManage manage = [[MaterialManage * alloc]init]; manage.param = dict; [[HSTool getCurrentVC].NavigationController pushViewController:manage animated:YES] else ([action isEqualToString:@ if;} the "system_setting" //5) {HVsystemSetingTableController = [[HVsystemSetingTableC * setting Ontroller alloc]init]; [[HSTool getCurrentVC].navigationController pushViewController:setting animated:YES] else if;} ([action isEqualToString:@ "profile_setting" //6 ") {HSPensonalSettingController * personSet = [[HSPensonalSettingController alloc]init]; [[HSTool getCurrentVC].navigationController pushViewController:personSet animated:YES] else if;} ([action isEqualToString:@" user_info "//7") {HSUserInfoVC * personSet = [[HSUserInfoVC alloc]init]; personSet.param = dict; "HSTool getCurrentVC].navigationController pushViewController:personSet animated:YES];} else if ([action isEqualToString:@" guide "//8") {HSHelpCenterViewController = [[HSHelp * help CenterViewController alloc]init]; [[HSTool getCurrentVC].navigationController pushViewController:help animated:YES] else if;} ([action isEqualToString:@ "QRcode" //9 ") {if ([FLLoginDataModel! CurrentUser].isLogin) {HSLoginController log = [[HSLoginController * alloc]init]; log.hidesBottomBarWhenPushed = YES; [[HSTool getCurrentVC].navigationController return; pushViewController:log animated:YES];} NSString *mediaType = AVMediaTypeVideo; AVAuthorizationStatus = authStatus [AVCaptureDevice authorizationStatusForMediaType:mediaType]; if (authStatus = = AVAuthorizationStatusRestricted || authStatus ==AVAuthorizationStatusDenied) { UIAlertController *alert = [UIAlertController alertControllerWithTitle:@ "please open the APP camera permissions in the settings message:nil preferredStyle:UIAlertControllerStyleAlert]; UIAlertAction *action =[UIAlertAction actionWithTitle:@" Cancel "style: (UIAlertActionStyleCancel) handler:nil]; [alert addAction:action]; [[HSTool getCurrentVC] presentViewController:alert animated:YES completion:nil]; return HSScanViewController;} * scan = [[HSScanViewController alloc]init]; HSNavigationViewController *nav =[[HSNavigationViewController alloc]initWithRootViewController:scan]; [scan.navigationController.navigationBar setHidden:YES]; [[HSTool getCurrentVC] presentV IewController:nav animated:YES completion:nil] else if;} ([action isEqualToString:@ "search_list" //10 ") {HSComonSearchTBV * searchtbv = [[HSComonSearchTBV alloc]init]; searchtbv.param = dict; if (title.length> 0) {searchtbv.title = title;} [[HSTool getCurrentVC].navigationController pushViewController:searchtbv animated:YES] else if;} ([action isEqualToString:@" playcode "//11") {HSPlayCodeViewController = [[HSPlayCodeViewController * playcode alloc]init] [[HSTool getCurrentVC].navigationController; pushViewController:playcode animated:YES];} else if ([action isEqualToString:@ question_detail //12 {HSMaterialQuestionContro]) Ller * questionVC = [[HSMaterialQuestionController alloc]init]; questionVC.param = dict; [[HSTool getCurrentVC].navigationController pushViewController:questionVC animated:YES] else if;} ([action isEqualToString:@ "purchase"]) / / buy 13 interface {HSPayViewController * pay = [[HSPayViewController alloc]init]; pay.param = dict; [[HSTool getCurrentVC].navigationController pushViewController:pay animated:YES] else if;} ([action isEqualToString:@ "article_detail" //14 ") {HSNewsContentVC * article [[HSNewsContentVC = alloc]init]; article.paramDict = dict; article.isArticleDetail = YES; if (title.length> 0) {article.title = title; [[HSTool getCurrentVC].navigationController pushViewController:article animated:YES]}}; else if ([action isEqualToString:@ "survey_detail" //15 ") {else} if ([action" meal_detail "isEqualToString:@]||[action isEqualToString:@" pack_detail "//16") {HSMealDetailViewController *detailVC=[[HSMealDetailViewController alloc]init]; detailVC.param=dict [[HSTool; getCurrentVC].navigationController pushViewController:detailVC animated:YES];} else if ([action isEqualToString:@ course_detail //17 *detailVC=[[HSCourseDetailViewController alloc]init] {HSCourseDetailViewController]) if ([[HSTool getCurrentVC]; detailVC.param=dict; isKindOfClass:[HSCourseDetailV IewController class]]||[[HSTool getCurrentVC] isKindOfClass:[HSVideoDetailViewController class]]) {detailVC.isPushToSelfVC = YES;} [[HSTool getCurrentVC].navigationController pushViewController:detailVC animated:YES] else if;} ([action isEqualToString:@ "my_course" //18 ") {HSMyCourseViewController *mycourse = [[HSMyCourseViewController alloc]init] [[HSTool; getCurrentVC].navigationController pushViewController:mycourse animated:YES];} else if ([action isEqualToString:@" teacher_detail "]) {HVTeacherDetailVC * teacherDetail = [[HVTeacherDetailVC alloc]init]; teacherDetail.param = dict; [[HSTool getCurrentVC].navigationController pushViewController:t EacherDetail animated:YES]; else if} ([action isEqualToString:@ "suggest"]) {FeedBackVC * feedBack = [[FeedBackVC alloc]init]; feedBack.param = dict; [[HSTool getCurrentVC].navigationController pushViewController:feedBack animated:YES] else if;} ([action isEqualToString:@ "video_detail" HSVideoDetailViewController *videoDetail= [[HSVideoDetailViewController ") {alloc]init]; videoDetail.param = dict; [[HSTool getCurrentVC].navigationController pushViewController:videoDetail animated:YES] else ([action isEqualToString:@ if;}" "answer_detail") {// "answer/view answer_id=d8c83aa9e8707475c545a8966ae052ea& token=357487b027fda52852792171a18ac2f4 HSAnal?" YsisViewController *analysisVC = [[HSAnalysisViewController alloc]init]; analysisVC.param = dict; [[HSTool getCurrentVC].navigationController pushViewController:analysisVC animated:YES] else ([action isEqualToString:@ if;} QQ {[HSTool jumpToQQWithQQnumber:dict[HSOBJ_URL]]}]); else if ([action isEqualToString:@ phone [HSTool {jumpToPhoneWithPhonenumber:dict[HSOBJ_URL]]}]); else if ([action isEqualToString:@ "WebView"]) {HSWebViewController * webView = "HSWebViewController alloc]init]; webView.urlStr = dict[HSOBJ_URL]; webView.hidesBottomBarWhenPushed = YES; webView.shouldHideNavBar = YES; [[HSTool getCurrentVC].navigationContr Oller pushViewController:webView animated:YES] else if;} ([action isEqualToString:@ "login"]) {HSLoginController * login = [[HSLoginController alloc]init]; [[HSTool getCurrentVC].navigationController pushViewController:login animated:YES] else if;} ([action isEqualToString:@ "order_detail"]) {OrderDetailController * detail = [[OrderDetailController alloc]init]; detail.param = dict; [[HSTool getCurrentVC].navigationController pushViewController:detail animate

Whether or middleman or routing components, actually feel thoughts are similar, now for example also explain the above code: for example, there is a button on the interface, the server will give you a action and action_url, action said you jump to the page, URL said the next page web request address, click event almost all of the items are controlled by the server, the server will give you the corresponding action and url. The package such as
also provides convenience for interacting with H5,

[_bridge registerHandler:@ "WebViewAction" handler:^ (ID data, WVJBResponseCallback responseCallback) {NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:[data dataUsingEncoding: (NSUTF8StringEncoding)] options: NSJSONReadingAllowFragments error:nil]; [HSTool processActionURL:[dic stirngWithSaftKey:@ andWithAction:[dic stirngWithSaftKey:@] "action_url" "action" "}];

Remember every H5 page to a single controller, followed by a meal on the background I want a bunch of interface identifier, now only need a webVC, only needs two lines of code, and support all the native support of the event, the feeling was so easy I want to be unemployed……

In the show we modeled on UI also written more than 20 type UI styles, each style corresponds to a cell, a controller can display 20 kinds of styles, can through the back you want to configure a page, select the style you want to show from 20, you can use type1 can the type2 controller has a very high rate of reuse.

Once thought, since all events jump to Tool to deal with, that can also achieve a view production such a tool class, in fact can also, but height and layout to achieve more trouble.

But the need to have no way, then I put the direct support for parsing type controller, child controller, addsubview way directly to the controller as a universal view, but because controller is a tableview, and you must take it as a view, so the height is a very troublesome the problem, then solved by KVO, I feel very embarrassed, although can meet the demand, but always feel something strange.

Sum up:

Relatively speaking, this design is very convenient, low coupling, small thermal update and support, the style is not fixed, the event is not fixed, by the server to control, easy to use, the most important thing is, I found that I almost didn’t what bug, bug basically is the background big brother. Haha



Since the project uses a routing design pattern, every time the test tells me that I have a bug, my brother smiles and tells her that this is the server’s Bug