Browse Source

resume iOS download

dmuratshin 9 years ago
parent
commit
f91a602727
1 changed files with 114 additions and 93 deletions
  1. 114 93
      oxygine/src/core/ios/HttpRequestCocoaTask.mm

+ 114 - 93
oxygine/src/core/ios/HttpRequestCocoaTask.mm

@@ -17,7 +17,7 @@ static char taskKey;
 - (id)init
 {
     if (!(self = [super init]))
-		return nil;
+        return nil;
     
     return self;
 }
@@ -45,7 +45,7 @@ static char taskKey;
     oxygine::HttpRequestCocoaTask* task = [self getTask:downloadTask remove:true];
     
     NSFileManager *fileManager = [NSFileManager defaultManager];
-
+    
     
     std::string dest = oxygine::file::wfs().getFullPath(task->getFileName().c_str());
     NSURL *destUrl = [NSURL fileURLWithPath:[NSString stringWithUTF8String:dest.c_str()]];
@@ -64,13 +64,32 @@ static char taskKey;
 
 - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(nullable NSError *)error
 {
-	if (!error) {
-		// didFinishDownloadingToURL will be called in this case,
-		// which will save the file and signal completion.
-	} else {
-	    oxygine::HttpRequestCocoaTask* httpRequestTask = [self getTask:task remove:true];
-		httpRequestTask->complete_(/* data */ nil, /* error */ true);
-	}
+    NSLog(@"Session %@ download task %@ finished downloading with error %@\n",session, task, error);
+    
+    
+    oxygine::HttpRequestCocoaTask* httpRequestTask = [self getTask:task remove:true];
+    
+    if (error) {
+        NSData* resumeData = [error.userInfo objectForKey:NSURLSessionDownloadTaskResumeData];
+        if (resumeData) {
+            NSURLSessionTask *rt = [session downloadTaskWithResumeData:resumeData];
+            [rt resume];
+            
+            NSValue *taskValue = [NSValue valueWithPointer:httpRequestTask];
+            objc_setAssociatedObject(rt, &taskKey, taskValue, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+        }
+        else
+        {
+            httpRequestTask->complete_(/* data */ nil, /* error */ true);
+        }
+    }
+    
+    if (!error) {
+        // didFinishDownloadingToURL will be called in this case,
+        // which will save the file and signal completion.
+    } else {
+        
+    }
 }
 
 
@@ -91,60 +110,60 @@ static char taskKey;
 
 namespace oxygine
 {
-	int _httpRequestTaskInitialized = 0;
-
-	HttpRequests *_cls = nil;
-	
-	void _sessionConfigCommonInit(NSURLSessionConfiguration* config) {
-		config.allowsCellularAccess = YES;
-		config.timeoutIntervalForRequest = 30.0;
-		config.timeoutIntervalForResource = 60.0;
-		config.HTTPMaximumConnectionsPerHost = 10;
-	}
-	
-	NSURLSession* __defaultSession = nil;
-	NSURLSession* _getDefaultSession() {
-		if (!__defaultSession) {
-			OX_ASSERT(_cls); // Call HttpRequestTask::init()
-			NSURLSessionConfiguration* config = [NSURLSessionConfiguration defaultSessionConfiguration];
-			_sessionConfigCommonInit(config);
-			__defaultSession = [NSURLSession sessionWithConfiguration:config delegate:_cls delegateQueue:nil];
-		}
-		return __defaultSession;
-	}
-	
+    int _httpRequestTaskInitialized = 0;
+    
+    HttpRequests *_cls = nil;
+    
+    void _sessionConfigCommonInit(NSURLSessionConfiguration* config) {
+        config.allowsCellularAccess = YES;
+        config.timeoutIntervalForRequest = 30.0;
+        config.timeoutIntervalForResource = 60.0;
+        config.HTTPMaximumConnectionsPerHost = 10;
+    }
+    
+    NSURLSession* __defaultSession = nil;
+    NSURLSession* _getDefaultSession() {
+        if (!__defaultSession) {
+            OX_ASSERT(_cls); // Call HttpRequestTask::init()
+            NSURLSessionConfiguration* config = [NSURLSessionConfiguration defaultSessionConfiguration];
+            _sessionConfigCommonInit(config);
+            __defaultSession = [NSURLSession sessionWithConfiguration:config delegate:_cls delegateQueue:nil];
+        }
+        return __defaultSession;
+    }
+    
     NSURLSession* __ephemeralSession = nil;
-	NSURLSession* _getEphemeralSession() {
-		if (!__ephemeralSession) {
-			OX_ASSERT(_cls); // Call HttpRequestTask::init()
-			NSURLSessionConfiguration* config = [NSURLSessionConfiguration ephemeralSessionConfiguration];
-			_sessionConfigCommonInit(config);
-			config.URLCache = nil;
-			config.URLCredentialStorage = nil;
-			config.HTTPCookieStorage = nil;
-			
-			__ephemeralSession = [NSURLSession sessionWithConfiguration:config delegate:_cls delegateQueue:nil];
-		}
-		return __ephemeralSession;
-	}
-	
+    NSURLSession* _getEphemeralSession() {
+        if (!__ephemeralSession) {
+            OX_ASSERT(_cls); // Call HttpRequestTask::init()
+            NSURLSessionConfiguration* config = [NSURLSessionConfiguration ephemeralSessionConfiguration];
+            _sessionConfigCommonInit(config);
+            config.URLCache = nil;
+            config.URLCredentialStorage = nil;
+            config.HTTPCookieStorage = nil;
+            
+            __ephemeralSession = [NSURLSession sessionWithConfiguration:config delegate:_cls delegateQueue:nil];
+        }
+        return __ephemeralSession;
+    }
+    
     void HttpRequestTask::init()
     {
-		if (_httpRequestTaskInitialized++)
-			return;
-		
+        if (_httpRequestTaskInitialized++)
+            return;
+        
         _cls = [[HttpRequests alloc] init];
     }
     
     void HttpRequestTask::release()
     {
-		OX_ASSERT(_httpRequestTaskInitialized > 0);
-		if (--_httpRequestTaskInitialized)
-			return;
-		
-		__defaultSession = nil;
-		__ephemeralSession = nil;
-		_cls = nil;
+        OX_ASSERT(_httpRequestTaskInitialized > 0);
+        if (--_httpRequestTaskInitialized)
+            return;
+        
+        __defaultSession = nil;
+        __ephemeralSession = nil;
+        _cls = nil;
     }
     
     spHttpRequestTask HttpRequestTask::create()
@@ -155,7 +174,7 @@ namespace oxygine
     
     HttpRequestCocoaTask::HttpRequestCocoaTask()
     {
-    
+        
     }
     
     HttpRequestCocoaTask::~HttpRequestCocoaTask()
@@ -186,17 +205,17 @@ namespace oxygine
         
         releaseRef();
     }
-        
+    
     void HttpRequestCocoaTask::_run()
     {
         _mainThreadSync = true;
         
         addRef();
-		NSString *urlString = [NSString stringWithUTF8String:_url.c_str()];
+        NSString *urlString = [NSString stringWithUTF8String:_url.c_str()];
         NSURL *url =[NSURL URLWithString:urlString];
-		
-		NSURLSession *session = _cacheEnabled ? _getDefaultSession() : _getEphemeralSession();
-
+        
+        NSURLSession *session = _cacheEnabled ? _getDefaultSession() : _getEphemeralSession();
+        
         NSURLSessionTask *task = 0;
         if (_fname.empty())
         {
@@ -206,45 +225,47 @@ namespace oxygine
                 request.HTTPBody = [NSData dataWithBytes:_postData.data() length:_postData.size()];
                 request.HTTPMethod = @"POST";
             }
-			
+            
             task = [session dataTaskWithRequest:request
-                completionHandler:^(NSData *data,
-                                    NSURLResponse *response,
-                                    NSError *error) {
-                    // handle response
-					
-					bool httpError = false;
-					
-					if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
-						NSHTTPURLResponse *httpResponse = ((NSHTTPURLResponse *)response);
-						NSInteger statusCode = httpResponse.statusCode;
-						if (statusCode != 200)
-							httpError = true;
-					}
-					
-                    if (error || httpError)
-                    {
-                        onError();
-                    }
-                    else
-                    {
-						if (data)
-						{
-							const void *ptr = data.bytes;
-							size_t len = data.length;
-							_response.assign((const char*)ptr, (const char*)ptr + len);
-						}
-						onComplete();
-                    }
-					releaseRef();
-                }];
+                              completionHandler:^(NSData *data,
+                                                  NSURLResponse *response,
+                                                  NSError *error) {
+                                  // handle response
+                                  
+                                  bool httpError = false;
+                                  
+                                  if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
+                                      NSHTTPURLResponse *httpResponse = ((NSHTTPURLResponse *)response);
+                                      NSInteger statusCode = httpResponse.statusCode;
+                                      if (statusCode != 200)
+                                          httpError = true;
+                                  }
+                                  
+                                  if (error || httpError)
+                                  {
+                                      onError();
+                                  }
+                                  else
+                                  {
+                                      if (data)
+                                      {
+                                          const void *ptr = data.bytes;
+                                          size_t len = data.length;
+                                          _response.assign((const char*)ptr, (const char*)ptr + len);
+                                      }
+                                      onComplete();
+                                  }
+                                  releaseRef();
+                              }];
         }
         else
         {
             task = [session downloadTaskWithURL:url];
         }
-		NSValue *taskValue = [NSValue valueWithPointer:this];
+        
+        NSValue *taskValue = [NSValue valueWithPointer:this];
         objc_setAssociatedObject(task, &taskKey, taskValue, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+        
         log::messageln("created task session: %x", task);
         
         [task resume];