河狸家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告知給訊息中心即可;
解除模組間的耦合;
相關文章
- Flutter:如何跳轉頁面?Flutter
- 跳轉滿足條件的資料
- APP直接跳轉設定頁面APP
- 產品經理的四點思考:不該簡單滿足使用者需求
- PHP頁面跳轉如何實現延時跳轉PHP
- js頁面跳轉的問題(跳轉到父頁面、最外層頁面、本頁面)JS
- vue頁面跳轉Vue
- Flutter頁面跳轉Flutter
- javascript 跳轉頁面JavaScript
- js頁面跳轉JS
- react跳轉url,跳轉外鏈,新頁面開啟頁面React
- uni-APP 新增頁面實現路由跳轉APP路由
- js跳轉頁面方法(轉)JS
- JavaScript 頁面跳轉效果JavaScript
- router跳轉page頁面
- 如何重構CRM系統,滿足擴充套件的需求套件
- 音訊特效SDK,滿足內容生產的音訊處理需求音訊特效
- MongoDB是什麼以及它如何滿足您的應用需求MongoDB
- JavaScript頁面跳轉程式碼JavaScript
- ios跳轉到通用頁面iOS
- javascript控制頁面(含iframe進行頁面跳轉)跳轉、重新整理的方法彙總JavaScript
- Flutter頁面保活及保持頁面跳轉位置Flutter
- 直播app原始碼,跳轉站外連結或平臺內部跳轉頁面APP原始碼
- asyUI分頁中,如何實現頁面跳轉,再返回時,...UI
- 系統首頁 DIY,你的個性化需求 Pro 系統來滿足!
- 不擴容提升十倍 x86 軟體效能,雲杉網路如何用產品思路滿足客戶需求?
- Flutter頁面跳轉到IOS原生介面 如何實現?FlutteriOS
- PacketMaster——滿足客戶需求的多功能打流儀AST
- nginx 設定 404 500 頁面跳轉到指定頁面Nginx
- php怎麼直接跳轉頁面PHP
- PHP中實現頁面跳轉PHP
- 結構化資料儲存,如何設計才能滿足需求?
- 不管你需求如何,BenQ PD2700U總能滿足你ENQ
- 給你的Flutter頁面跳轉加上動畫Flutter動畫
- dynamics crm跳轉到手機版本的頁面
- 頁面間跳轉的效能優化(一)優化
- 玩家需求分析:如何滿足玩家的“爭強好勝”和“養成感”?
- Android應用中,跳轉到App的詳細設定頁面,設定許可權頁面AndroidAPP