iOS App 動態更新

動態更新

? ? 1、控件到 window 的層級關系:

? ? 2、分析控件的詳細路徑:

? ? 3、動態修改控件:

? ? 4、工具篇:

視圖的層級關系:

? ? 每個 App , 至少有一個根 Window , 通常情況下我們只用一個 。window 有一個 rootViewController , 這就是我們所謂的根視圖 , 我們所有的控制器都是放在 rootViewController 里面的。


如果在項目里有了這么一個路徑 , 我們可以做什么呢?

? ? * 在當項目很復雜 , 可以其它地方可以直接修改這個控件的狀態

? ? * 當某個控件命名存在卻又沒有顯示出來 , 可以通過路徑來輔助查找

? ? * 由服務器下發一些配置 , 使用 Runtime 去動態的修改已上線的項目

下面將介紹如何使用代碼來找出這些視圖(控件)的路徑

分析控件的詳細路徑

1、找出根 Window :

每一個視圖、控件 , 他們最終的根都是main函數返回的 application , 通過 [UIApplication sharedApplication] 可以得到 。 application 的 windows 屬性是一個數組 , 這里面裝的是這個應用的所有 Window , 我們通常用的是第一個也就是 application.windows[0]

2、遍歷視圖 :

得到了 window 對象一切都好辦了 。 然后拿到 window 的 rootViewController , 在獲取 rootViewController 里面所有的 childViewControllers 和 view 里的 subviews , 一直遞歸下去就可以得到當前屏幕里所有視圖對象了 , 同時可以通過 runtime 把它們的 property 、 delegate 都獲取出來 。

結合 Reveal 或者 Xcode 自帶的 Captuer View Hiearachy , 我們可以推測一下這兩個的的實現原理了 :

? ? 1、根據應用得到根視圖

? ? 2、遞歸獲取里面的所有控件

? ? 3、按照他們的層級關系一層一層的畫出來

動態修改控件

1、把上面獲取到的所有控件的詳細信息上傳到服務器 。

2、根據業務需求由服務器給我們下發對應的配置列表 , 以 button 為例 : 配置列表里必須要有 :

? ? 1)、button 的全路徑 : 如 UIWindow -> UIWindow -> UIView -> UIView -> ? ? ?UILayoutContainerView -> UITabBar -> UIView —> UIButton

? ? 2)、button 的唯一標識 : 如 tag 值或自己實現的一套算法生成的唯一標識 , 目的是防止與 button 同一層次的視圖搞混 。

? ? 3)、 根據路徑及唯一標識來匹配 App 里的控件 , 匹配和上面的查找原理是相通的。

? ? 4)、 匹配成功代表 button 確實存在 , 根據業務需求做后續操作 。

提示: 匹配策略盡可能的多 , 防止意外情況某一兩個標識生成失敗或者生成相同 。

3、修改 button 的狀態。

? ? 1)、 如某個按鈕點了會 Crash 或暫時不需要被點擊 , 但是又要展示出來 , 可以直接修改 button 的 enabled 屬性 。

? ? 2)、 如某業務暫時關閉 , 可以直接修改入口 按鈕 frame為0 , 前提是要自動布局已做好 。

? ? 3)、 如給購買 按鈕 添加監聽事件 addTarget: action: forControlEvents:

target 也可以通過上面 遍歷視圖 獲取到 , action 可以由服務器下發 , 也可以一開始就寫死 , 等有需求的時候直接傳不同的參數就行了 。

4、 綁定查找控件時 , 這個界面必須要已經初始化完成了才行 , 假如界面還沒生成肯定是查找不到這個控件的 。 這里給大家提供兩種思路 :

? ? 1、使用Runtime Method Swizzing , 直接把修改控件的方法與 didMoveToSuperview 和 didMoveToWindow 動態綁定 , 等這個控件加載出來之后再去修改 , 查找路徑正確的話肯定就能找到了 。

? ? 2、在具體的類里面 , 等控件的初始化方法調用完后 , 再去執行動態修改 , 如在viewDidLoad 里面初始化控件 , 在 viewWillAppear: 里面動態修改 。

建議使用第一種適用范圍更強 。

上架后的 應用 可能會遇到的一些突發狀況 , 未測出的Crash、臨時改點小需求 , 等等 , 我們總不能每次因為一點小改動就重新提交一次 App Store , 先不說 App Store 的審核時間 , 頻繁的讓用戶去更新應用 , 用戶也會煩的 。使用這篇文章所講的來實現動態更新是再合適不過了 。

首先上面講的 動態更新 是完全脫離出來的一個模塊 , 跟業務邏輯沒有任何關系 , 只需要部署一次就行了 , 等開發下一個項目也可以直接拿過去使用 。這里的動態更新適用于局部的視圖、控件的修改 , 如果你有其它需求可以考慮 JSPatch 、wax , 下發腳本也是一個不錯的選擇 。

工具篇:

使用一些UI調試的輔助工具 , 使我們查看視圖在項目中得層次結構更為方便 。

常用的UI調試的工具:

Captuer View Hiearachy

Reveal

Xcode自帶的 Captuer View Hiearachy 實現步驟:

? ? 1、打開Xcode , 運行項目 , 選擇最頂部的 Debug

? ? 2、Debug -> View Debugging -> Show View Frames

? ? 3、Debug -> View Debugging -> Captuer View Hiearachy

Xcode里面就變成了三維的視圖了 , Xcode左側展示出來的是層級關系的樹狀圖 。

Reveal的功能相對來說更強大 , 適用于UI調試視圖查找 。使用方法請看 Reveal集成指南 。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • App動態更新1、控件到 window的層級關系:2、分析控件的詳細路徑:3、動態修改控件:4、工具篇: 視圖的層...
    __Lex閱讀 535評論 0 2
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,076評論 25 708
  • 當個正常人不好么? 問這種問題的人有兩種:超凡脫俗的牛逼,自以為是的傻逼。 我屬于哪種呢?目測不像第一種。 但是 ...
    只有一個命運閱讀 1,017評論 0 2
  • 人們在面臨痛苦的時候,心會變得很小很窄,充斥著滿滿的負能量。同時我們所有的負面情緒在胸腔里肆意。我們在痛苦的深淵里...
    今墨閱讀 1,860評論 0 4