From 151e7a7a53b92081f96144a85ff458a50bbd2f32 Mon Sep 17 00:00:00 2001 From: Pan Demosthenous Date: Wed, 2 Dec 2015 15:16:00 +1100 Subject: [PATCH 1/3] CCDownloader-apple : call onTaskFinish when the download session completes for a data task --- cocos/network/CCDownloader-apple.mm | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/cocos/network/CCDownloader-apple.mm b/cocos/network/CCDownloader-apple.mm index 5b5045e2a8..6b9151a619 100644 --- a/cocos/network/CCDownloader-apple.mm +++ b/cocos/network/CCDownloader-apple.mm @@ -361,15 +361,34 @@ namespace cocos2d { namespace network { // clean wrapper C++ object DownloadTaskWrapper *wrapper = [self.taskDict objectForKey:task]; - // if no error, callback has been called in finish task - if (_outer && error) + if(_outer) { - std::vector buf; // just a placeholder - _outer->onTaskFinish(*[wrapper get], + if(error) { + std::vector buf; // just a placeholder + _outer->onTaskFinish(*[wrapper get], cocos2d::network::DownloadTask::ERROR_IMPL_INTERNAL, (int)error.code, [error.localizedDescription cStringUsingEncoding:NSUTF8StringEncoding], buf); + } + else if(![wrapper get]->storagePath.length()) { + // call onTaskFinish for a data task + // (for a file download task, callback is called in didFinishDownloadingToURL) + std::string errorString; + + const int64_t buflen = [wrapper totalBytesReceived]; + char buf[buflen]; + + [wrapper transferDataToBuffer:buf lengthOfBuffer:buflen]; + + std::vector data(buf, buf + buflen); + + _outer->onTaskFinish(*[wrapper get], + cocos2d::network::DownloadTask::ERROR_NO_ERROR, + 0, + errorString, + data); + } } [self.taskDict removeObjectForKey:task]; [wrapper release]; From 528a94d36fc97e1e86697f061e57505580ca4bc1 Mon Sep 17 00:00:00 2001 From: Pan Demosthenous Date: Wed, 2 Dec 2015 15:21:42 +1100 Subject: [PATCH 2/3] fixes a crash in destructor of CCDownloader-apple when completing a data download --- cocos/network/CCDownloader-apple.mm | 61 +++++++++++++++++------------ 1 file changed, 36 insertions(+), 25 deletions(-) diff --git a/cocos/network/CCDownloader-apple.mm b/cocos/network/CCDownloader-apple.mm index 6b9151a619..fe5a065645 100644 --- a/cocos/network/CCDownloader-apple.mm +++ b/cocos/network/CCDownloader-apple.mm @@ -266,33 +266,44 @@ namespace cocos2d { namespace network { for (NSURLSessionDownloadTask *task in enumeratorKey) { DownloadTaskWrapper *wrapper = [self.taskDict objectForKey:task]; - NSString *tempFilePath = [NSString stringWithFormat:@"%s%s", [wrapper get]->storagePath.c_str(), _hints.tempFileNameSuffix.c_str()]; - NSString *tempFileDir = [tempFilePath stringByDeletingLastPathComponent]; - NSFileManager *fileManager = [NSFileManager defaultManager]; - BOOL isDir = false; - if ([fileManager fileExistsAtPath:tempFileDir isDirectory:&isDir]) - { - if (NO == isDir) - { - // TODO: the directory is a file, not a directory, how to echo to developer? - continue; - } + + // no resume support for a data task + std::string storagePath = [wrapper get]->storagePath; + if(storagePath.length() == 0) { + [task cancel]; } - else - { - NSURL *tempFileURL = [NSURL fileURLWithPath:tempFileDir]; - if (NO == [fileManager createDirectoryAtURL:tempFileURL withIntermediateDirectories:YES attributes:nil error:nil]) - { - // create directory failed - continue; - } + else { + [task cancelByProducingResumeData:^(NSData *resumeData) { + if (resumeData) + { + NSString *tempFilePath = [NSString stringWithFormat:@"%s%s", storagePath.c_str(), _hints.tempFileNameSuffix.c_str()]; + NSString *tempFileDir = [tempFilePath stringByDeletingLastPathComponent]; + NSFileManager *fileManager = [NSFileManager defaultManager]; + BOOL isDir = false; + if ([fileManager fileExistsAtPath:tempFileDir isDirectory:&isDir]) + { + if (NO == isDir) + { + // TODO: the directory is a file, not a directory, how to echo to developer? + DLLOG("DownloaderAppleImpl temp dir is a file!"); + return; + } + } + else + { + NSURL *tempFileURL = [NSURL fileURLWithPath:tempFileDir]; + if (NO == [fileManager createDirectoryAtURL:tempFileURL withIntermediateDirectories:YES attributes:nil error:nil]) + { + // create directory failed + DLLOG("DownloaderAppleImpl create temp dir failed"); + return; + } + } + + [resumeData writeToFile:tempFilePath atomically:YES]; + } + }]; } - [task cancelByProducingResumeData:^(NSData *resumeData) { - if (resumeData) - { - [resumeData writeToFile:tempFilePath atomically:YES]; - } - }]; } _outer = nullptr; From ef931b61afab383845b24932817a051d1b76d291 Mon Sep 17 00:00:00 2001 From: Pan Demosthenous Date: Wed, 2 Dec 2015 15:23:05 +1100 Subject: [PATCH 3/3] correct typo in method name of doDestroy --- cocos/network/CCDownloader-apple.mm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cocos/network/CCDownloader-apple.mm b/cocos/network/CCDownloader-apple.mm index fe5a065645..840c53180e 100644 --- a/cocos/network/CCDownloader-apple.mm +++ b/cocos/network/CCDownloader-apple.mm @@ -59,7 +59,7 @@ -(const cocos2d::network::DownloaderHints&)getHints; -(NSURLSessionDataTask *)createDataTask:(std::shared_ptr&) task; -(NSURLSessionDownloadTask *)createFileTask:(std::shared_ptr&) task; --(void)doDestory; +-(void)doDestroy; @end @@ -97,7 +97,7 @@ namespace cocos2d { namespace network { DownloaderApple::~DownloaderApple() { DeclareDownloaderImplVar; - [impl doDestory]; + [impl doDestroy]; DLLOG("Destruct DownloaderApple %p", this); } IDownloadTask *DownloaderApple::createCoTask(std::shared_ptr& task) @@ -259,7 +259,7 @@ namespace cocos2d { namespace network { return ocTask; }; --(void)doDestory +-(void)doDestroy { // cancel all download task NSEnumerator * enumeratorKey = [self.taskDict keyEnumerator];