熱修復(fù)
iOS應(yīng)用審核時(shí)間之長(zhǎng),只叫人不堪忍受;但是更讓人捶胸的是,App好不容易上線了,結(jié)果發(fā)現(xiàn)上線的APP有明顯的bug。真他NND,各種無語,各種不是滋味。這個(gè)時(shí)候會(huì)想有沒有不發(fā)布新版本解決類似這些小Bug,其實(shí)網(wǎng)上搜索一下,已經(jīng)有很多方案了。如JSPatch和WaxPatch。具體這兩個(gè)方案的原理可以參考:http://m.itdecent.cn/p/41ed877aa0cd 這里不細(xì)說了,本文使用的是JSPatch來完成App熱修復(fù)模塊的邏輯。
我認(rèn)為下載完補(bǔ)丁能夠修復(fù)Bug,同時(shí)還要防止補(bǔ)丁有bug,要能夠?qū)σ呀?jīng)下載到本地的補(bǔ)丁進(jìn)行刪除重新修復(fù)。這樣補(bǔ)丁就應(yīng)該要有編號(hào)。
#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ǔ)丁時(shí)需將本地已經(jīng)存在的補(bǔ)丁作入?yún)⒏嬷?wù)器,請(qǐng)求到新補(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
基本邏輯就是這樣,完善的話,需對(duì)補(bǔ)丁進(jìn)行安全加密,網(wǎng)絡(luò)傳輸過程,本地存儲(chǔ)時(shí)最好都考慮一下安全性。我代碼里面是沒有作加密處理的,可別學(xué)我哦。
本也想畫一個(gè)補(bǔ)丁的修復(fù)邏輯流程圖,但發(fā)現(xiàn)前人已經(jīng)有現(xiàn)成的,我就不畫了,其實(shí)是我比較懶。流程圖可參考:http://blog.csdn.net/zm53373581/article/details/50011521
上一節(jié):消息推送
下一節(jié):webView封裝