2015-01-12 3 views
0

파일 컬렉션이 있습니다. 목록에서 모든 파일을 하나씩 업로드해야합니다. 일단 파일이 업로드되면 서버는 returnId를 보내 저장합니다. 그에 따라 진행 상황을 보여줄 필요가 있습니다. 하나씩 여러 파일을 업로드 할 때 iOS 문제가 발생합니다.

는 그러므로 나는 다음을 시도 - 인덱스 0 내 파일이 업로드되면

- (NSURLSession *)uploadSession 
{ 
    static NSURLSession *defaultSession = nil; 
    static dispatch_once_t uploadToken; 
    dispatch_once(&uploadToken, ^{ 
     NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:@"com.xyz.abc"]; 
     configuration.HTTPMaximumConnectionsPerHost = 10; 
     defaultSession = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil]; 
    }); 

    return defaultSession; 
} 

-(NSURLSessionUploadTask *)uploadFileWithUrl:(NSString *)fileUrl 
{ 
    NSURL *url = [NSURL URLWithString: @"ploadableUrl"]; 
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init]; 
    [request setURL:url]; 
    [request setHTTPMethod:@"POST"]; 
    [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; // default 
    [request setValue:@"application/json" forHTTPHeaderField:@"Accept"]; 
    NSString *base64str = [NSString stringWithFormat:@"%@:%@", kAPIAccessUsername, kAPIAccessPassword]; 
    NSData *base64data = [base64str dataUsingEncoding:NSUTF8StringEncoding]; 
    NSString *base64Encoded = [base64data base64EncodedStringWithOptions:0]; 
    NSString *authValue = [NSString stringWithFormat:@"Basic %@", base64Encoded]; 
    [request setValue:authValue forHTTPHeaderField:@"Authorization"]; 

    NSString *boundary = @"---9999999999"; 
    NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",boundary]; 
    [request setValue:contentType forHTTPHeaderField: @"Content-Type"]; // over-ridding for multipart/form-data; 

    /* body of the post */ 
    NSMutableData *reqBodyData = [NSMutableData data]; 
    [reqBodyData appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]]; 
    NSString *str = [NSString stringWithFormat:@"Content-Disposition: form-data; name=\"data\"; filename=\"%@\"\r\n", @"fileN"]; // "data" is the parameter required 
    [reqBodyData appendData:[[NSString stringWithString:str] dataUsingEncoding:NSUTF8StringEncoding]]; 
    [reqBodyData appendData:[@"Content-Type: application/octet-stream\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]]; 
    NSData *uploadableData = [NSData dataWithContentsOfURL:[NSURL fileURLWithPath:fileUrl]]; 
    [reqBodyData appendData:uploadableData]; 
    [reqBodyData appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]]; 
    [request setHTTPBody:reqBodyData]; 
    NSString *postLength = [NSString stringWithFormat:@"%ld", [reqBodyData length]]; 
    [request setValue:postLength forHTTPHeaderField:@"Content-Length"]; 
    [request setCachePolicy:NSURLRequestUseProtocolCachePolicy]; 

    NSURLSession *session = [self uploadSession]; 
    NSURLSessionUploadTask *dataTask = [session uploadTaskWithRequest:request fromFile:nil]; 
    DLog(@"upload taskIdentifier ---------------------> %lu", (unsigned long)dataTask.taskIdentifier); 
    [dataTask resume]; 
    return dataTask; 
} 

- (void)initiateUpload 
{ 
    uploadTask = [self uploadFileWithUrl:[_fileUrlCollections objectAtIndex:self.index]]; // initially index = 0 
} 

- (void)dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data 
{ 
    NSLog(@"CompletetaskIdentifier -> %ld", dataTask.taskIdentifier); 

    if (data) 
    { 
     NSError *error; 
     NSMutableDictionary *jsonDict = [NSMutableDictionary dictionaryWithDictionary:[NSJSONSerialization JSONObjectWithData:data options: NSJSONReadingMutableContainers error:&error]]; 
     if (!_uploadedIdCollections) 
      _uploadedIdCollections = [NSMutableArray arrayWithCapacity:0]; 
     [_uploadedIdCollections addObject:[jsonDict valueForKey:@"savedId"]]; 
     self.index++; 
     if([_fileUrlCollections count] > self.index) 
     { 
      NSLog(@"UPLOADING NEXT FILE"); 
      [self initiateUpload]; 
     } 
     else 
     { 
      NSLog(@"UPLOADED ALL FILES"); 
     } 
    } 
} 

, 서버가 다음, 나는 인덱스 1로 파일을 업로드하는 것을 시도하고 있음을 저장 한 후, 나에게 적절한 returnId를 보냅니다. 하지만 더 이상 업로드하지 않습니다. 누락되거나 잘못 된 것이 무엇인지 모릅니다.

즉각적인 제안이 필요합니다.

미리 감사드립니다.

답변

0

생각을 몇 :

  1. 당신은 Charles 또는 이에 상응하는 도구를 사용하여이 문제를보고 업로드가 진행되고 있는지 어떤지를 확인하고 요청이 잘못되지 않습니다 있는지 확인해야합니다.

  2. 왜 한 번에 하나씩 업로드 하시겠습니까? 당신은 상당한 성능 저하를 초래합니다. 또한 "백그라운드에서 업로드 한 사진을 대기열에 넣고이 앱이 종료 된 후에도 계속 진행할 수 있습니다."라는 전통적인 백그라운드 세션 작업과는 약간의 차이가 있습니다.

    많은 요청을 대기시키고 있다고 가정 해 봅시다. 사용자가 앱을 나가면 다운로드 할 때마다 백그라운드에서 앱을 다시 시작하고 싶지 않습니다. 당신은 오히려 NSURLSession 데몬을 가지고 마술을하고 모든 것이 끝났을 때 알려주고 싶을 것입니다. 업로드 작업은 일반적으로 요청의 본문에 대한 uploadTaskWithRequestfromFile 매개 변수를 사용하지 않고 NSMutableURLRequest의 몸을 사용하지만,하지 않기 때문에

  3. 나는이 전혀 업로드 놀랐어요. 이것은 찰스의 요청을 보아 확인할 수 있습니다.

    덧붙여서, 업로드되는 파일의 크기에 따라 이것은 메모리를보다 효율적으로 사용할 수 있습니다.

  4. 당신은 배경 세션을 사용하고
  5. : 그래서

    • 를 앱 위임에 handleEventsForBackgroundURLSession을 구현 있나요? completionHandler을 저장 하시겠습니까?

    • NSURLSessionDelegateURLSessionDidFinishEventsForBackgroundURLSession을 구현 했습니까? 일단 끝나면 위에서받은 completionHandler으로 전화를 걸겠습니까?

  6. 그런데 didReceiveData에 다음 업로드를 실행 중입니다. 의도적으로이를 순차적으로 수행하려는 경우 (논쟁의 여지가 있지만 2 번 참조) 다음 번 업로드를 URLSession:task:didCompleteWithError:에 실행하고 싶을 수 있습니다.

    어쨌든 didCompleteWithError을 구현하려는 경우 오류가 발생했는지 여부를 감지 할 수 있습니다.

  7. 여기에 작성중인 request과 관련없는 일부 req 변수에 Authorization 헤더를 지정하고 있습니다. 올바른 개체에 머리글을 설정했는지 확인하십시오.

    req 개체가 JSON이되도록 Content-Type을 설정하고 분명히 JSON이 아닙니다.

+0

감사합니다. Rob, 제안 사항. 확인해야 할 사항이 거의 없으며 4 번과 5 번 항목이 구현되었습니다. 서버가 우리가 작성한 모든 호출에 응답해야합니다 (보안 이유). Content-Type이 overrides되는 ===> NSString * contentType = [NSString stringWithFormat : @ "multipart/form-data; boundary = % @", 경계]; [요청 setValue : contentType forHTTPHeaderField : @ "Content-Type"]; // multipart/form-data에 대한 over-ridding; – Satyaranjan

+0

나는 당신을 따르지 않는다 # 6 : 당신이 여기에 사용하지 않는 일부'req' 객체에 대해 인증을 설정하고있다 ._'req'는 무엇인가? '요청'이라고하셨습니까? – Rob

+0

예. 오타를 유감스럽게 생각한다! – Satyaranjan

관련 문제