河狸家APP如何满足产品的任意页面跳转需求(runtime)

一 跳转native页面需求入口来源分析

跳转native页面的源头分五类:

1.第三方app唤起跳转,包含短信;这类多用于第三方市场商务合作以及运营活动;

2.推送消息指令跳转;这类可帮助运营提高老用户活跃,提高转化;

3.服务器下发指令跳转;(长链接场景服务端主动推消息)

4.App native内部跳转;iOS自身技术设计需要;

5.native与h5的交互跳转;在电商app中,十分广泛,可帮助产品更快试错,更快速的迭代更新;

分析了来源和意义,我们来看看电商app实现任意入口的任意跳转到底有什么好处呢?

二 电商app实现任意跳转app页面的好处

1.从产品上:服务端即可灵活的控制app,满足产品天马行空的跳转想象,更灵活的满足产品需求;

2.从运营支持上:我们要明白任何没有着落页的短信及推送消息,都是耍流氓,否则对点击了消息而没有看到着落的用户就是一种伤害;而它能解决点击每个活动消息都可以自定义着落页面;

3.从技术上:当两位领导意见分歧,一个要跳a页面,一个要跳转到b页面,此时则可搞a/b test,再结合BI数据分析,分析转化;最终帮助公司沉淀最优方案,提高转化,最终实现理想IPO上市;这就是技术的力量(哈哈平和领导的关系,维护了公司的团结稳定#共勉#)

估计大部分技术都没有意识到自己还有这种力量,以上对话勿让领导听到#奸笑#

这样看起来无论哪个入口要跳转哪个页面,技术上去做好它都变得十分有意义!

三 河狸家app早期协议

(因安全原因,由于苹果可通过class-dump命令,反编译处理,若直接暴露类名/方法/对象会引来安全问题,故以下代码的方法和类名都经过处理,命名也不规范,请谅解,注意思路)

背景:

设计理念,如同http://访问一样,只需要一个知道Url抛给底层服务,即可访问想要到达的页面,而上层工程师不需要关注中间如何访问及如何跳转;

由此,河狸家app定义了一个openUrl,来控制所有的页面跳转访问;

下面来看openUrl结构:

首先要建立协议:

1.协议头定义:考虑到第三方app唤起的原因,我们将协议头定义为URL Schemes(如微信的weixin://),这里考虑到安全问题,则隐藏河狸家app URL Schemes;用“HLJ://”代替

~urlString 形如 @"HLJ://page?jsonData={json}";

~1、区分事件类型 如"page"

~2、获取json

json对象结构形如

{

     "hljType” : enum, //跳转页面标示   建立一个页面映射表来对应enum

    “hljPageN” : “作品详情”,//页面名称

    “jData” : {

            “proId” : “sldkjf3l2”

      }

}

json对应的model对象ScEntity如图:

制定完协议结构,下面来看看过程核心代码结构:

核心管理类ScManager,负责接收openUrl协议,校验协议,解析json,定向跳转;

工程师在开发过程只需要注意在openurl中填写跳转目的页面,以及model丢出数据即可,其他则不用关注;

第一步

首先校验跳转协议,必须要遵循HLJ://才可进入跳转逻辑,否则认为非法;

再解析jsondata,并解码son串;

第二步

将json解析成字典,利用MJ将数据转成SceneBaseEntity对象

第三步,通过枚举映射表对应跳转类,并拼接model

再利用

再通过

TabBarController *rootNav = (TabBarController *) kWindow.rootViewController;

[[rootNav.viewControllers objectAtIndex:rootNav.selectedIndex] pushViewController:controller animated:YES];

实现了跳转;

优点:

1.直观;

2.工程师编码只关注目的,和对应的唯一model。

缺点:

1.它还是不够灵活,每个页面都需要在枚举表中对应上映射,无法做到不发版本即可跳转无映射的页面;

2.当项目逐渐扩大,页面无穷多个时,产品的野心也在膨胀后,要写一堆的switch判断;

那还是不完全满足啊~~~~

别急!!!!来看第四段~~~~~

四  如何设计一套协议另app能够自由任意的跳转呢?

核心:runtime运行时机制+组件化

(这里插个题外话,无论老人代码写的怎么样,都是带动的创业公司走过风雨,尊重与感谢,勿吐槽多敬重!!!)

注意:由于旧工程需要兼容,还考虑这套设计中的openurl协议涉及安卓/iOS /前端/后端,考虑团队,则需要一个过渡方案。于是只能在旧工程上switch case,并且为了兼容旧版本,最新的运行时动态跳转设计中添加了一个enum为PgType_Runtime=100;来判断走新的跳转机制;

并且我们的ScEntity增加了三个属性 cname/mcname/moname

而我们的openUrl所对应json结构也发生了如下变化;

~1、区分事件类型 如"page"

~2、获取json

json对象结构形如

{

     “type” : enum, //跳转页面标示   建立一个页面映射表来对应enum

     “pgName” : “作品详情”,//页面名称

     “cName” : “ViewController”,//页面class名

     “mCName” : “Model”,//model class名

     “mOName” : “model”,//model对象名

     “jdata” : {

              “proId” : “sldkjf3l2”

       }

}

例如要跳转作品列表:

"openUrl": "hlj://pg?jData={\"hljtype\":100,\"cName\":\"SearchtResultController\",\"mCName\":\"SeachCModel\",\"mObjName\":\"searchC\",\"pgN\":\"作品列表\",\"data\":{\"artType\":1,\"cate\":\"tag_m\"}}}"}"

第一步,

通过cName,获取cName所对应的类名pageclass,通过pageclass创建唤起的目标页面对象;

第二步,

通过mcName去获取mcName所对应的类名modelclass;

再通过objc_getClass(modelclass)获取modelclass的isa指针指向(唤起的目标页面)所对应的modelc类对象;

假如不存在modelc类,就去创建一个nsobject类,nsobject是对象的root类;([NSObject class]只是返回一个NSobject类),那么superClass为一个NSobject类;

使用objc_allocateClassPair为"class pair"分配空间,来创建一个NSobject子类;

(什么是“class pair"? objc_allocateClassPair只返回一个值:Class。)

(拓展:如果想要为类添加方法可使用class_addMethod添加了一个方法,如class_addMethod(superClass, @selector(report), (IMP)ReportFunction, "v@:");

@selector(report)获取一个SEL类型,IMP是oc实现代码块的地址,类时函数指针,通过他可以直接访问人意一个方法,免去发送消息的代价;imp(对象自己(self),方法标示SEL,第三个是方法的参数);通过IMP直接调用方法 等效调用:[self SEL:参数];   //另外增加实 例变量用class_addIvar)

注册你创建的这个类,使其可用;

第三步,

遍历外部传入的参数data的key;

利用kvc对model对象每个属性进行赋值;

伪代码表现model.key = obj;//大致是这样一个形式

且要注意一定要去判断key所对应的model中的属性(名字与key一致)是否存在;(方法在最后代码片段里)

这样就得到一个完整数据的model;

第四步,

model也是一个page页面的属性,则可以同样的方式将model赋值给pageclass

最后为检查属性是否存在的代码片段:

这样就愉快的做到了在不发布版本的前提下实现任意跳转;

五 技术上总结

协议跨平台兼容性:安卓也是走的同样的一套设计协议,这样安卓iOS都不需要发布版本则可以做到实现任意页面跳转;

架构提升:对团队工程师的模块化/封装性的要求比较高,提升app的架构设计;

开发工程师开发成本:不需要关注如何跳转,只需要调用一段代码,将想要到达的目的页面class以及传递的数据model告知给消息中心即可;

解除模块间的耦合;

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,457评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,837评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,696评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,183评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,057评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,105评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,520评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,211评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,482评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,574评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,353评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,897评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,489评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,683评论 2 335

推荐阅读更多精彩内容