From d994233184006278a397e854ff5968e43bf19aa5 Mon Sep 17 00:00:00 2001 From: Nikolay Demyankov Date: Wed, 2 Dec 2015 10:07:10 +0100 Subject: [PATCH] Fix for https://github.com/nordnet/cordova-hot-code-push/issues/53 . Better download process. --- src/ios/Network/HCPFileDownloader.m | 7 ++--- src/ios/Updater/HCPUpdateLoader.m | 12 ++++---- src/ios/Updater/HCPUpdateLoaderWorker.m | 39 ++++++++++++++++++------- 3 files changed, 39 insertions(+), 19 deletions(-) diff --git a/src/ios/Network/HCPFileDownloader.m b/src/ios/Network/HCPFileDownloader.m index d5726b71..8ab4a0dc 100644 --- a/src/ios/Network/HCPFileDownloader.m +++ b/src/ios/Network/HCPFileDownloader.m @@ -19,7 +19,7 @@ - (void) downloadDataFromUrl:(NSURL*) url completionBlock:(HCPDataDownloadComple NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration]; NSURLSessionDataTask* dowloadTask = [session dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { - block(data, error); + block(data, error); }]; [dowloadTask resume]; @@ -53,9 +53,8 @@ - (void) downloadFiles:(NSArray *)filesList fromURL:(NSURL *)contentURL toFolder if (error) { canceled = YES; // do not dispatch any other error } - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - block(error); - }); + // we should already be in the background thread + block(error); } }]; diff --git a/src/ios/Updater/HCPUpdateLoader.m b/src/ios/Updater/HCPUpdateLoader.m index 9e10eff4..7152fdc1 100644 --- a/src/ios/Updater/HCPUpdateLoader.m +++ b/src/ios/Updater/HCPUpdateLoader.m @@ -39,8 +39,7 @@ - (void)setup:(id)filesStructure { - (NSString *)addUpdateTaskToQueueWithConfigUrl:(NSURL *)configUrl { // TODO: add better communication between installer and loader. - // For now - skip update load request if installation or download is in progress. - if ([HCPUpdateInstaller sharedInstance].isInstallationInProgress || _isExecuting) { + if (_isExecuting) { return nil; } @@ -52,9 +51,12 @@ - (NSString *)addUpdateTaskToQueueWithConfigUrl:(NSURL *)configUrl { - (void)executeTask:(id)task { _isExecuting = YES; - [task runWithComplitionBlock:^{ - _isExecuting = NO; - }]; + // execute in background, so the callbacks don't block main thread + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + [task runWithComplitionBlock:^{ + _isExecuting = NO; + }]; + }); } @end diff --git a/src/ios/Updater/HCPUpdateLoaderWorker.m b/src/ios/Updater/HCPUpdateLoaderWorker.m index 25eba607..3aeb3a06 100644 --- a/src/ios/Updater/HCPUpdateLoaderWorker.m +++ b/src/ios/Updater/HCPUpdateLoaderWorker.m @@ -54,6 +54,9 @@ - (void)run { - (void)runWithComplitionBlock:(void (^)(void))updateLoaderComplitionBlock { NSError *error = nil; + // wait before installation is finished + [self waitForInstallationToComplete]; + // initialize before the run if (![self loadLocalConfigs:&error]) { updateLoaderComplitionBlock(); @@ -101,9 +104,9 @@ - (void)runWithComplitionBlock:(void (^)(void))updateLoaderComplitionBlock { return; } - // find files that were updated - NSArray *updatedFiles = [_oldManifest calculateDifference:newManifest].updateFileList; - if (updatedFiles.count == 0) { + // compare manifests to find out if anything has changed since the last update + HCPManifestDiff *manifestDiff = [_oldManifest calculateDifference:newManifest]; + if (manifestDiff.isEmpty) { [_manifestStorage store:newManifest inFolder:_pluginFiles.wwwFolder]; [_appConfigStorage store:newAppConfig inFolder:_pluginFiles.wwwFolder]; updateLoaderComplitionBlock(); @@ -111,7 +114,27 @@ - (void)runWithComplitionBlock:(void (^)(void))updateLoaderComplitionBlock { return; } - [self downloadUpdatedFiles:updatedFiles appConfig:newAppConfig manifest:newManifest complitionBlock:updateLoaderComplitionBlock]; + // create new download folder + [self recreateDownloadFolder:_pluginFiles.downloadFolder]; + + // if there is anything to load - do that + NSArray *updatedFiles = manifestDiff.updateFileList; + if (updatedFiles.count > 0) { + [self downloadUpdatedFiles:updatedFiles appConfig:newAppConfig manifest:newManifest complitionBlock:updateLoaderComplitionBlock]; + return; + } + + // otherwise - update holds only files for deletion; + // just save new configs and notify subscribers about success + [_manifestStorage store:newManifest inFolder:_pluginFiles.downloadFolder]; + [_appConfigStorage store:newAppConfig inFolder:_pluginFiles.downloadFolder]; + + // move download folder to installation folder + [self moveDownloadedContentToInstallationFolder]; + + updateLoaderComplitionBlock(); + + [self notifyUpdateDownloadSuccess:newAppConfig]; }]; }]; } @@ -120,9 +143,6 @@ - (void)runWithComplitionBlock:(void (^)(void))updateLoaderComplitionBlock { - (void)downloadUpdatedFiles:(NSArray *)updatedFiles appConfig:(HCPApplicationConfig *)newAppConfig manifest:(HCPContentManifest *)newManifest complitionBlock:(void (^)(void))updateLoaderComplitionBlock{ - // create new download folder - [self recreateDownloadFolder:_pluginFiles.downloadFolder]; - // download files HCPFileDownloader *downloader = [[HCPFileDownloader alloc] init]; // TODO: set credentials on downloader @@ -210,8 +230,7 @@ - (BOOL)loadLocalConfigs:(NSError **)error { * Copy all loaded files from download folder to installation folder from which we will install the update. */ - (void)moveDownloadedContentToInstallationFolder { - // ignore for now, since we are not launching installation and download tasks at the same time - //[self waitForInstallationToComplete]; + [self waitForInstallationToComplete]; NSFileManager *fileManager = [NSFileManager defaultManager]; NSError *error = nil; @@ -223,7 +242,7 @@ - (void)moveDownloadedContentToInstallationFolder { */ - (void)waitForInstallationToComplete { while ([HCPUpdateInstaller sharedInstance].isInstallationInProgress) { - [NSThread sleepForTimeInterval:0.1]; // avoid busy loop + [NSThread sleepForTimeInterval:1]; // avoid busy loop } }