最近在iOS上又出現(xiàn)了一個(gè)熱更新的工具,rollout惩嘉,小小的體驗(yàn)了一番罢洲。
簡(jiǎn)介
它在編譯期間執(zhí)行一個(gè)upload_dsym的腳本,將收集到的文件符號(hào)dsym上傳到其服務(wù)器文黎,這樣我們就可以在它提供的后臺(tái)操作dashboard中惹苗,選擇對(duì)應(yīng)的app,選擇已存在的方法耸峭,進(jìn)行編輯桩蓉,更改返回值,替換參數(shù)劳闹,添加邏輯等等院究。還可以添加新的方法,但是類必須存在本涕,還能為缺失的方法提供實(shí)現(xiàn)业汰。
主要技術(shù)也是JavaScriptCore和Runtime。在dashboard中添加hot patch之后菩颖,客戶端重新啟動(dòng)样漆,會(huì)拉取新的配置。但在試驗(yàn)中晦闰,不是很及時(shí)放祟,要啟動(dòng)幾次才能切到新的配置,可能跟服務(wù)器在國(guó)外有關(guān)鹅髓,還有可能就是拉取到配置之后舞竿,要patch的動(dòng)作已經(jīng)完成,這種在下次啟動(dòng)就可以了窿冯。當(dāng)在工程中新添加類/方法時(shí)骗奖,在啟動(dòng)后也會(huì)將符號(hào)上傳。但是不能立馬在dashboard中看到對(duì)應(yīng)的類醒串。問(wèn)了rollout的工作人員执桌,說(shuō)是會(huì)有幾分鐘的延遲,可以過(guò)段時(shí)間刷新頁(yè)面看看芜赌。
安裝
可以通過(guò)Cocoapods或者下載他們提供的工具來(lái)安裝SDK仰挣。
我是通過(guò)Cocoapods。
另外缠沈,我們可以添加options膘壶,輸出調(diào)試信息错蝴。
RolloutOptions *option = [[RolloutOptions alloc] init];
option.verbose = RolloutOptionsVerboseLevelDebug;
[Rollout setupWithKey:@"5714eaa036053a902868e088"
#ifdef DEBUG
developmentDevice:YES
#endif
options:option];
下午操作的時(shí)候按照它的提示,在前5步完成之后颓芭,compile的時(shí)候出現(xiàn)了錯(cuò)誤顷锰。Build Phase-->Rollout.io dsym upload中路徑不存在的問(wèn)題,后來(lái)跟rollout的人反饋了這個(gè)問(wèn)題亡问,回復(fù)說(shuō)是個(gè)bug官紫,會(huì)在下次release中fix。但是現(xiàn)在晚上再重試已經(jīng)修復(fù)了州藕。真有效率啊束世。
在運(yùn)行起來(lái)之后,Waiting For App會(huì)變成Done床玻』偕妫可以進(jìn)行下一步添加hot patch了。
添加hot patch
1锈死、你可以搜索想要的方法名薪丁。
為了方便,我們選擇[ViewController viewDidLoad]方法馅精。
- toggleJS是讓我們自己添加js代碼严嗜,寫(xiě)邏輯。
- Before the function有2種操作洲敢,一種是彈個(gè)alert漫玄,可以自己設(shè)置title,msg等压彭。另一種是進(jìn)行事件統(tǒng)計(jì)睦优。
- ConditionalPatch是添加patch觸發(fā)的條件,可設(shè)置系統(tǒng)版本壮不,手機(jī)型號(hào)汗盘。
- HotPatch Type是是否允許使用patch。
下面我們就簡(jiǎn)單的選擇Before the function添加個(gè)alert询一。
然后隐孽,重新運(yùn)行。有時(shí)候并不能馬上看到效果健蕊,因?yàn)樗钱惒饺ダ⌒碌呐渲昧庹螅渲美』貋?lái)之后,在下次啟動(dòng)時(shí)生效缩功。部分配置如下晴及。
{
"__v" = 0;
"_id" = 5714f968cfbc4acb63bdc419;
"app_version" = 5714eeb692e27ab318a043ba;
bucket = sandbox;
"creation_date" = "2016-04-18T15:12:40.656Z";
data = (
{
class = Test;
configuration = "Ui5OU0NsYXNzRnJvbVN0cmluZygnVUlBcHBsaWNhdGlvbicpLmNhbGwoJ3NoYXJlZEFwcGxpY2F0aW9uJykuY2FsbCgnb3BlblVSTDonLCBSLk5TQ2xhc3NGcm9tU3RyaW5nKCdOU1VSTCcpLmNhbGwoJ1VSTFdpdGhTdHJpbmc6JywgJ2h0dHA6Ly93d3cuYmFpZHUuY29tJykpOwo=";
configurationType = javascript;
methodType = instance;
selector = test;
signature = "()->Void";
swizzlingType = createImplementation;
},
{
class = ViewController;
configuration = Ui5OU0NsYXNzRnJvbVN0cmluZygnTXlPYmplY3QnKS5jYWxsKCduZXcnKS5jYWxsKCdzYXknKTsK;
configurationType = javascript;
methodType = instance;
selector = viewDidLoad;
signature = "()->Void";
swizzlingType = replaceImplementation;
}
);
}
運(yùn)行結(jié)果如下:
2、Polyfille method
可以理解為方法替代嫡锌。只能給已存在的類添加方法虑稼×斩ぃ可以添加新的方法,或者是給已聲明未實(shí)現(xiàn)的方法添加實(shí)現(xiàn)蛛倦。
下面的例子中因?yàn)閇MyObject test]未實(shí)現(xiàn)槽卫,在MyViewController里面ViewDidload方法調(diào)用了[MyObject test]方法,正常情況下是跳轉(zhuǎn)到MyViewController頁(yè)面就會(huì)崩潰的胰蝠。等下用hot patch來(lái)解決。經(jīng)測(cè)試震蒋,如果實(shí)現(xiàn)[MyObject test]茸塞,就會(huì)走原有邏輯,patch就不起作用了查剖。如果要修改已存在方法钾虐,可參照第三條。
@interface MyObject : NSObject
- (void)say;
// 未實(shí)現(xiàn)笋庄,之后會(huì)用hot patch實(shí)現(xiàn)
- (void)test;
- (void)calculate:(int)a;
@end
@implementation MyObject
- (void)say {
NSLog(@"I am MyObject");
}
- (void)calculate:(int)a {
NSLog(@"calculate:%d", a);
}
@end
我們添加了[MyObject test]方法效扫。
然后添加實(shí)現(xiàn)。這里我們打開(kāi)百度頁(yè)面直砂。js的寫(xiě)法也比較簡(jiǎn)單菌仁。
R.NSClassFromString('UIApplication').call('sharedApplication').call('openURL:', R.NSClassFromString('NSURL').call('URLWithString:', 'http://www.baidu.com'));
調(diào)用方法就用call,傳參數(shù)静暂,直接跟在后面济丘。
運(yùn)行,跳轉(zhuǎn)到MyViewController洽蛀,會(huì)跳轉(zhuǎn)到web摹迷。
3、修改已存在的方法
還是拿[ViewController viewDidLoad]來(lái)說(shuō)郊供,在里面調(diào)用方法[MyObject say]峡碉。選擇Toggler JS。[MyObject say]是在工程中的方法驮审。
var obj = R.NSClassFromString('MyObject').call('new')
obj.call('say')
self.originalImplementation();
再次運(yùn)行鲫寄。
4、修改參數(shù)值
將calculate參數(shù)為10疯淫,修改成20塔拳。
在ViewController里
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
MyObject *obj = [[MyObject alloc] init];
[obj calculate:10];
}
運(yùn)行幾次,發(fā)現(xiàn)的確是輸出了20峡竣。