熱修復(fù)
iOS應(yīng)用審核時間之長,只叫人不堪忍受麻裁;但是更讓人捶胸的是箍镜,App好不容易上線了,結(jié)果發(fā)現(xiàn)上線的APP有明顯的bug煎源。真他NND色迂,各種無語,各種不是滋味手销。這個時候會想有沒有不發(fā)布新版本解決類似這些小Bug歇僧,其實(shí)網(wǎng)上搜索一下,已經(jīng)有很多方案了锋拖。如JSPatch和WaxPatch诈悍。具體這兩個方案的原理可以參考:http://www.reibang.com/p/41ed877aa0cd 這里不細(xì)說了祸轮,本文使用的是JSPatch來完成App熱修復(fù)模塊的邏輯。
我認(rèn)為下載完補(bǔ)丁能夠修復(fù)Bug写隶,同時還要防止補(bǔ)丁有bug倔撞,要能夠?qū)σ呀?jīng)下載到本地的補(bǔ)丁進(jìn)行刪除重新修復(fù)。這樣補(bǔ)丁就應(yīng)該要有編號慕趴。
#import "PGBaseObj.h"
/**
補(bǔ)丁痪蝇,用于熱修復(fù)
*/
@interface PGPatchObject : PGBaseObj
/*
補(bǔ)丁ID
*/
@property(nonatomic, strong)NSString *mFixID;
/*
補(bǔ)丁js腳本
*/
@property(nonatomic, strong)NSString *mFixString;
@end
補(bǔ)丁模塊作統(tǒng)一的管理(下載,緩存本地冕房、刪除等)
@interface PGPatchManager : NSObject
+ (PGPatchManager *)shareInstance;
/*
其實(shí)執(zhí)行是 [JPEngine startEngine]
*/
- (void)startListen;
/*
執(zhí)行本要的腳本
*/
- (void)executeLocalHot;
/*
從服務(wù)器上獲取新的腳本
*/
- (void)getHotData;
@end
獲取新的補(bǔ)丁時需將本地已經(jīng)存在的補(bǔ)丁作入?yún)⒏嬷?wù)器躏啰,請求到新補(bǔ)丁的處理邏輯如下:
static PGPatchManager *s_patchManager = nil;
@interface PGPatchManager ()<PGApiDelegate>
@property(nonatomic, strong)NSMutableArray *arrayHots;
@end
@implementation PGPatchManager
+ (PGPatchManager *)shareInstance
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
s_patchManager = [[PGPatchManager alloc] init];
s_patchManager.arrayHots = [[NSMutableArray alloc] init];
[s_patchManager.arrayHots addObjectsFromArray:[s_patchManager localHots]];
});
return s_patchManager;
}
- (void)startListen
{
[JPEngine startEngine];
}
- (void)getHotData
{
NSMutableArray *localHotIDs = [[NSMutableArray alloc] init];
for(PGPatchObject *obj in self.arrayHots)
{
[localHotIDs addObject:obj.mFixID];
}
//本地已經(jīng)存在的補(bǔ)丁
NSString *ids = [NSString jsonStringWithArray:localHotIDs];
[PGRequestManager startPostClient:API_TYPE_PATCH param:@{@"fixIds":ids} target:self extendParam:nil];
}
- (NSMutableArray *)localHots
{
NSObject *obj = [PGCacheManager readCacheType:ECacheType_Hots];
if(obj != nil)
return (NSMutableArray *)obj;
else
return [[NSMutableArray alloc] init];
}
- (void)saveHotsToLocal
{
[PGCacheManager cacheData:self.arrayHots type:ECacheType_Hots];
}
- (void)executeLocalHot
{
for(PGPatchObject *obj in self.arrayHots)
{
[JPEngine evaluateScript:obj.mFixString];
}
}
- (void)executeHot:(NSArray *)array
{
for(PGPatchObject *obj in array)
{
[JPEngine evaluateScript:obj.mFixString];
}
}
- (void)addHot:(NSArray *)array
{
if(array == nil || array.count <= 0)
return;
for(PGPatchObject *newobj in array)
{
for(PGPatchObject *obj in self.arrayHots)
{
if([newobj.mFixID compare:obj.mFixID] != NSOrderedSame)
{
[self.arrayHots addObject:obj];
}
}
}
}
- (void)delHot:(NSArray *)array
{
if(array == nil || array.count <= 0)
return;
for(PGPatchObject *delobj in array)
{
for(PGPatchObject *obj in self.arrayHots)
{
if([delobj.mFixID compare:obj.mFixID] == NSOrderedSame)
{
[self.arrayHots removeObject:obj];
break;
}
}
}
}
#pragma mark -
- (void)dataRequestFinish:(PGResultObject *)resultObj apiType:(PGApiType)apiType
{
if(apiType == API_TYPE_PATCH)
{
if(resultObj.nCode == 0)
{
NSMutableDictionary *dic = (NSMutableDictionary *)resultObj.dataObject;
NSMutableArray *addarray = [dic objectForKey:@"add"];
NSMutableArray *delarray = [dic objectForKey:@"del"];
//執(zhí)行新的補(bǔ)丁
[self executeHot:addarray];
//刪除舊的補(bǔ)丁
[self delHot:delarray];
//添加新的補(bǔ)丁
[self addHot:addarray];
//保存新的補(bǔ)丁
[self saveHotsToLocal];
}
}
}
@end
基本邏輯就是這樣,完善的話耙册,需對補(bǔ)丁進(jìn)行安全加密给僵,網(wǎng)絡(luò)傳輸過程,本地存儲時最好都考慮一下安全性详拙。我代碼里面是沒有作加密處理的帝际,可別學(xué)我哦。
本也想畫一個補(bǔ)丁的修復(fù)邏輯流程圖饶辙,但發(fā)現(xiàn)前人已經(jīng)有現(xiàn)成的蹲诀,我就不畫了,其實(shí)是我比較懶弃揽。流程圖可參考:http://blog.csdn.net/zm53373581/article/details/50011521
上一節(jié):消息推送
下一節(jié):webView封裝