標籤:ios turn 方法 intvalue 載入 value nbsp att nec
react native 熱更新的好處
js指令碼代碼改變了,比如對ui進行了一些修改,用戶端要是想更新的話,如果直接下載apk 或者ipa,一個是浪費流量,還有比較麻煩
熱更新只要下載打包好的bundle 檔案,然後進行替換就可以了
思路比較簡單,用戶端跟服務端都維持 一個bundle版本資訊,如果服務端的版本比用戶端的 版本新就下載,然後替換掉 重新渲染就OK了
具體實現,如果沒有 熱更新,載入bundle的代碼是這樣的
jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index.ios" fallbackResource:nil];
如果加入熱更新,是這樣的
NSURL *jsCodeLocation=nil; jsCodeLocation=[self getBundle]; if(jsCodeLocation==nil) { jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index.ios" fallbackResource:nil]; }
getBundle 函數就包含載入 服務端擷取到的bundle 的邏輯
-(NSURL *) getBundle{ NSString* ss=@"#####";//服務端bundle版本號碼的地址 NSString* str = [self httpGet:ss]; NSString *pathDocuments=[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]; NSString *createPath=[NSString stringWithFormat:@"%@/%@",pathDocuments,@"version.txt"];//用檔案名稱補全路徑 Boolean bb=false; NSFileManager *defaultManager; defaultManager = [NSFileManager defaultManager]; NSURL *nsurl=nil; if ([[NSFileManager defaultManager] fileExistsAtPath:createPath])//判斷檔案是否已存在 { NSString* fileContents = [NSString stringWithContentsOfFile:createPath encoding:NSUTF8StringEncoding error:nil]; int a=[str intValue];//服務端bundle版本號碼 int b=[fileContents intValue];//用戶端bundle版本資訊 if(a>b)//如果服務端的bundle版本比加大,就刪除用戶端的bundle,然後更新成服務端的 { if ([[NSFileManager defaultManager] fileExistsAtPath:createPath])//判斷檔案是否已存在 { [defaultManager removeItemAtPath:createPath error:NULL]; } [self storeFile:@"version.txt" content:str]; bb=true; } else//如果發現下載的bundle檔案不存在,也要下載更新 { createPath=[NSString stringWithFormat:@"%@/%@",pathDocuments,@"main.jsbundle"]; if (![[NSFileManager defaultManager] fileExistsAtPath:createPath])//判斷檔案是否已存在 { bb=true; } } } else//如果用戶端的bundle是空,也要下載 { [self storeFile:@"version.txt" content:str]; bb=true; } if (bb==true) { createPath=[NSString stringWithFormat:@"%@/%@",pathDocuments,@"main.jsbundle"]; if ([[NSFileManager defaultManager] fileExistsAtPath:createPath])//判斷檔案是否已存在 { [defaultManager removeItemAtPath:createPath error:NULL]; } ss=@"####";//服務端bundle檔案的地址 str = [self httpGet:ss]; NSString *fileName=[self storeFile:@"main.jsbundle" content:str]; nsurl=[NSURL fileURLWithPath:fileName];//這是bundle 檔案的路徑 } else{ createPath=[NSString stringWithFormat:@"%@/%@",pathDocuments,@"main.jsbundle"]; nsurl=[NSURL fileURLWithPath:createPath];//這是bundle 檔案的路徑 } return nsurl; }-(NSString *) httpGet:(NSString *)ss{ //第一步,建立URL NSURL *url = [NSURL URLWithString:ss]; //第二步,通過URL建立網路請求 NSURLRequest *request = [[NSURLRequest alloc]initWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:10]; //NSURLRequest初始化方法第一個參數:請求訪問路徑,第二個參數:緩衝協議,第三個參數:網路請求逾時時間(秒) /*其中緩衝協議是個枚舉類型包含: NSURLRequestUseProtocolCachePolicy(基礎策略) NSURLRequestReloadIgnoringLocalCacheData(忽略本機快取) NSURLRequestReturnCacheDataElseLoad(首先使用緩衝,如果沒有本機快取,才從原地址下載) NSURLRequestReturnCacheDataDontLoad(使用本機快取,從不下載,如果本地沒有緩衝,則請求失敗,此策略多用於離線操作) NSURLRequestReloadIgnoringLocalAndRemoteCacheData(無視任何緩衝策略,無論是本地的還是遠端,總是從原地址重新下載) NSURLRequestReloadRevalidatingCacheData(如果本機快取是有效則不下載,其他任何情況都從原地址重新下載)*/ //第三步,串連伺服器 NSData *received = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil]; NSString *str = [[NSString alloc]initWithData:received encoding:NSUTF8StringEncoding]; return str;}//隱藏檔-(NSString *)storeFile:(NSString *)fileName content:(NSString *)writeContent{ NSString *pathDocuments=[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]; NSString *createPath=[NSString stringWithFormat:@"%@/%@",pathDocuments,fileName];//用檔案名稱補全路徑 NSError *ReadFileError; NSString *readContent ; NSData *data ; if ([[NSFileManager defaultManager] fileExistsAtPath:createPath])//判斷檔案是否已存在 { if (nil == writeContent) { readContent = [NSString stringWithContentsOfFile:createPath encoding:NSUTF8StringEncoding error:&ReadFileError]; }else{ data = [writeContent dataUsingEncoding:NSUTF8StringEncoding];//新檔案的初始資料 [[NSFileManager defaultManager] createFileAtPath:createPath contents:data attributes:nil];//建立檔案 readContent = [NSString stringWithContentsOfFile:createPath encoding:NSUTF8StringEncoding error:&ReadFileError]; } } else { if (nil == writeContent) { return nil; }else{ data = [writeContent dataUsingEncoding:NSUTF8StringEncoding];//新檔案的初始資料 [[NSFileManager defaultManager] createFileAtPath:createPath contents:data attributes:nil];//建立檔案 readContent = [NSString stringWithContentsOfFile:createPath encoding:NSUTF8StringEncoding error:&ReadFileError]; } } return createPath;}
以上就是主要代碼,有注釋說明意思
ios bundle打包指令碼如下
react-native bundle --entry-file index.ios.js --bundle-output ./bundle/index.ios.bundle --platform ios --assets-dest ./bundle --dev false
react native ios版本熱更新