以iOS为例
说下需求:在主项目中根据需要下载子项目(或文件),并子项目能利用主项目中的cordova-hot-code-push-plugin的跟随主项目更新。一个是包含全部子项目的页面,一个是选择下载子项目后的页面,都是iOS原生。
1、首先要搭建个本地服务器,可参考http://blog.csdn.net/liuyuyefz/article/details/8072485,简单快捷。
先把要下载的项目压缩包放在本地服务器的 /usr/local/apache-tomcat-7.0.32/webapps/www里面,以便下载。
2、cordova-hot-code-push-plugin插件已安装在项目。
3、本地服务器已开启。
1、首先要先设置好下载路径,下载路径要跟热更新的下载更新路径是相同的,需要注意一点,文件不是存放在项目文件夹,是存放在项目运行的路径
NSUserDefaults *user=[NSUserDefaults standardUserDefaults];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSAllLibrariesDirectory, NSUserDomainMask, YES);
NSLog(@"------------paths=%@",paths);
NSString *documentsDirectory = [NSString stringWithFormat:@"%@/Application Support/com.ionicframework.superappionic558256/cordova-hot-code-push-plugin/%@/www",[paths objectAtIndex:0],[user objectForKey:@"currentReleaseVersionName"]];
看一下拼接路径:
[paths objectAtIndex:0]:这个不必说,自然是自动获取;
Application Support:值得一提的是这个文件夹,这个文件是进入cordova,ionic页面运行后出现的(个人认为进入cordova就可以有),所以,必须要进入cordova,ionic页面先运行一次,否则没有这个文件夹。此时,肯定有人会说,既然这样那我直接让做管理子项目下载的页面控制器继承于CDVViewController,省了前面的复杂,我利用属性传值测试了一下,CDVViewController与UIViewController之间push的时候要么不传值,要么崩,但是,NSUserDefaults是可以的,原因大家自己去找吧;
com.ionicframework.superappionic558256:测试了一下,清空运行缓存再运行,两次生成的都是这个名字文件夹,这跟config.xml有关,由里面的id决定;
<widget id="com.ionicframework.superappionic558256" version="0.0.1" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
cordova-hot-code-push-plugin:插件名;
[user objectForKey:@"currentReleaseVersionName"]:当前显示给用户的版本,即chcp.json里面的release对应的值。去HCPPlugin.m里面的doLocalInit方法取值
/**
* Perform initialization of the plugin variables.执行插件的初始化
*/
- (void)doLocalInit {
_defaultCallbackStoredResults = [[NSMutableArray alloc] init];
// init plugin config from xml
_pluginXmlConfig = [HCPXmlConfig loadFromCordovaConfigXml];
// load plugin internal preferences
_pluginInternalPrefs = [HCPPluginInternalPreferences loadFromUserDefaults];
if (_pluginInternalPrefs == nil || _pluginInternalPrefs.currentReleaseVersionName.length == 0) {
_pluginInternalPrefs = [HCPPluginInternalPreferences defaultConfig];
[_pluginInternalPrefs saveToUserDefaults];
}
NSLog(@"Currently running release version %@", _pluginInternalPrefs.currentReleaseVersionName);
//取当前版本号
NSUserDefaults *user=[NSUserDefaults standardUserDefaults];
[user setObject:_pluginInternalPrefs.currentReleaseVersionName forKey:@"currentReleaseVersionName"];
// init file structure for www files
_filesStructure = [[HCPFilesStructure alloc] initWithReleaseVersion:_pluginInternalPrefs.currentReleaseVersionName];
NSLog(@"====%s",__FUNCTION__);
}
2、下载,ionic2项目创建时就自带了AFNetworking,所以用它来下载,文件都是压缩包Zip的形式,代码如下:
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
//存放文件的路径
NSString *fullPath = [NSString stringWithFormat:@"%@/%@.zip", documentsDirectory, projectName];
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"http://192.168.100.234:8080/www/%@.zip",projectName]];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSURLSessionDownloadTask *task =
[manager downloadTaskWithRequest:request
progress:nil destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) {
return [NSURL fileURLWithPath:fullPath];
}
completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) {
}];
[task resume];
下载路径URL是本地服务器的IP+www+项目名称.zip,项目压缩包是提前放在本地服务器上的。
3、解压并删除Zip
// 解压
NSString *zipPath =[NSString stringWithFormat:@"%@/%@.zip",documentsDirectory,projectName];
NSString *destinationPath = [NSString stringWithFormat:@"%@",documentsDirectory];
[SSZipArchive unzipFileAtPath:zipPath toDestination:destinationPath];
NSFileManager* fileManager=[NSFileManager defaultManager];
BOOL blHave=[[NSFileManager defaultManager] fileExistsAtPath:zipPath];
if (!blHave) {
NSLog(@"no have");
return ;
}else {
NSLog(@" have");
//移除Zip
BOOL blDele= [fileManager removeItemAtPath:zipPath error:nil];
if (blDele) {
NSLog(@"delete success");
}else {
NSLog(@"delete fail");
}
}
所以,总结全部,下载功能代码如下,
#pragma mark -文件下载
-(void)downloadFileByAFNetworkingWithProject:(NSString*)projectName documentsDirectory:(NSString*)documentsDirectory{
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
//存放文件的路径
NSString *fullPath = [NSString stringWithFormat:@"%@/%@.zip", documentsDirectory, projectName];
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"http://192.168.100.241:8080/www/%@.zip",projectName]];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSURLSessionDownloadTask *task =
[manager downloadTaskWithRequest:request
progress:nil destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) {
return [NSURL fileURLWithPath:fullPath];
}
completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) {
}];
[task resume];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
// 解压
NSString *zipPath =[NSString stringWithFormat:@"%@/%@.zip",documentsDirectory,projectName];
NSString *destinationPath = [NSString stringWithFormat:@"%@",documentsDirectory];
[SSZipArchive unzipFileAtPath:zipPath toDestination:destinationPath];
NSFileManager* fileManager=[NSFileManager defaultManager];
BOOL blHave=[[NSFileManager defaultManager] fileExistsAtPath:zipPath];
if (!blHave) {
NSLog(@"no have");
return ;
}else {
NSLog(@" have");
//移除Zip
BOOL blDele= [fileManager removeItemAtPath:zipPath error:nil];
if (blDele) {
NSLog(@"delete success");
}else {
NSLog(@"delete fail");
}
}
});
}
需要注意一点,本人在调用执行的时候,下载速度会慢于解压,导致解压时还没有Zip文件,所以解压用dispatch_after做了一个2s的时间延迟,延迟时间可根据情况做设置。
1、修改HCPContentManifest.m
官方说法
/**
* Model for content manifest.
* Content manifest is a configuration file, that holds the list of all web project files with they hashes.内容清单是一个配置文件,包含所有web项目的列表文件哈希表。
* Used to determine which files has been removed from the project, which are added or updated.用于确定哪些文件已经从项目中删除,添加或更新。
*/
// find new files
for (HCPManifestFile *newFile in comparedManifest.files) {
BOOL isFound = NO;
for (HCPManifestFile *oldFile in self.files) {
if ([newFile.name isEqualToString:oldFile.name]) {
isFound = YES;
break;
}
}
if (!isFound) {
[addedFiles addObject:newFile];
}
}
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
NSString *newProjName = [ud objectForKey:@"page"];//"proj1","proj2".etc
NSLog(@"------%s=newProjName=%@",__FUNCTION__,newProjName);
// find new files
for (HCPManifestFile *newFile in comparedManifest.files) {
BOOL isFound = NO;
BOOL isNeed = NO;
for (HCPManifestFile *oldFile in self.files) {
if ([newFile.name isEqualToString:oldFile.name]) {
isFound = YES;
NSLog(@"++++----- newFile.name ======= %@", newFile.name);
if (newProjName != nil) {
if ([newFile.name hasPrefix: newProjName]) {
NSLog(@"+++++++++++ newFile.name必须的 ======= %@", newFile.name);
isNeed = YES;
}
}
break;
}
}
if (!isFound && isNeed) {
[addedFiles addObject:newFile];
}
}
2、修改CDVViewController.m
因为是从iOS原生进入ionic,用了如下方法:
NSString *file=[NSString stringWithFormat:@"%@/index.html",_currentItems[indexPath.item]];
NSLog(@"--------file==%@",file);
[user setObject:file forKey:@"page"];
[user synchronize];
MainViewController *vc = [[MainViewController alloc] initWithFolderName:@"www" StartPage:file];
[self.navigationController pushViewController:vc animated:true];
MainViewController是继承于CDVViewController,iOS原生进入ionic是需要通过cordova,所以修改如下
- (void)loadSettings
{
CDVConfigParser* delegate = [[CDVConfigParser alloc] init];
[self parseSettingsWithParser:delegate];
// Get the plugin dictionary, whitelist and settings from the delegate.
self.pluginsMap = delegate.pluginsDict;
self.startupPluginNames = delegate.startupPluginNames;
self.settings = delegate.settings;
// And the start folder/page.
if(self.wwwFolderName == nil){
self.wwwFolderName = @"www";
}
// if(delegate.startPage && self.startPage == nil){
//self.startPage = delegate.startPage;
// }
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
self.startPage = [ud objectForKey:@"page"];
NSLog(@"-------cdv-startPage==%@",self.startPage);
// Initialize the plugin objects dict.
self.pluginObjects = [[NSMutableDictionary alloc] initWithCapacity:20];
}
3、修改HCPPlugin.m
把indexPageFromConfigXml方法里面的“_indexPage = DEFAULT_STARTING_PAGE;”改成如下:
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
NSString *startUrl=[ud objectForKey:@"page"];
_indexPage = startUrl;//DEFAULT_STARTING_PAGE;
4、更新步骤
前提:带有子项目的主项目在运行中。
子项目更新:
①、在子项目中需要的地方做修改;
②、ionic serve;
③、cordova-hcp build;
④、ionic build iOS;
⑤、将子项目platforms--iOS中的www复制,放在主项目外部的www文件;
⑥、主项目cordova-hcp build;
⑦、将主项目外部的www文件复制,放到服务器 /usr/local/apache-tomcat-7.0.32/webapps,覆盖原来的www文件,如有其它需要下载的子项目,则放入新www中。
主项目更新:
①、在主项目中需要的地方做修改;
②、ionic serve;
③、cordova-hcp build;
⑦、将主项目外部的www文件复制,放到服务器 /usr/local/apache-tomcat-7.0.32/webapps,覆盖原来的www文件。
以上就是主要功能,还有许多细节需要自己完善,里面很多操作是灵活,根据自己的需要用合适的方法就可以了,比如传值方式。
这里iOS和Android很多方法都是通用的。
(网不好,没上传图片。如果有更好的建议和方法可以留言啊!!)