diff --git a/cocos/network/CCDownloader-apple.mm b/cocos/network/CCDownloader-apple.mm index c60445e917..40aa2b06aa 100644 --- a/cocos/network/CCDownloader-apple.mm +++ b/cocos/network/CCDownloader-apple.mm @@ -61,7 +61,7 @@ -(const cocos2d::network::DownloaderHints&)getHints; -(NSURLSessionDataTask *)createDataTask:(std::shared_ptr&) task; -(NSURLSessionDownloadTask *)createFileTask:(std::shared_ptr&) task; --(void)doDestory; +-(void)doDestroy; @end @@ -99,7 +99,7 @@ namespace cocos2d { namespace network { DownloaderApple::~DownloaderApple() { DeclareDownloaderImplVar; - [impl doDestory]; + [impl doDestroy]; DLLOG("Destruct DownloaderApple %p", this); } IDownloadTask *DownloaderApple::createCoTask(std::shared_ptr& task) @@ -273,40 +273,51 @@ namespace cocos2d { namespace network { return ocTask; }; --(void)doDestory +-(void)doDestroy { // cancel all download task NSEnumerator * enumeratorKey = [self.taskDict keyEnumerator]; 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; @@ -375,15 +386,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];