2011-11-22 6 views
1

iOS 용 로컬 하드 드라이브에서 Amazon S3 스토리지로 파일을 업로드 및 다운로드하는 데 iOS 용 AWS SDK을 사용하고 있습니다. 이 작업을 할 수는 있지만 작업이 완료되거나 오류가 발생하면 S3 담당자가 제대로 응답하도록 알릴 수 없습니다.대리인, 작업 및 대기열 사용

업로드 할 파일 배열이 있습니다. 각 파일에 대해 나는 main 루틴이 대부분으로 구성 NSOperation을 만듭니다

AmazonCredentials * credentials = [[AmazonCredentials alloc] initWithAccessKey:ACCESS_KEY_ID withSecretKey:SECRET_KEY]; 
    putObjectRequest = [[S3PutObjectRequest alloc] initWithKey:pathCopy inBucket:[self bucket]]; 
    putObjectRequest.filename = pathSource; 
    putObjectRequest.credentials=credentials; 
    [putObjectRequest setDelegate:s3Delegate]; 

여기서, 대리인 (s3Delegate)이 작업이 완료되면 응답을 해고 할 수 있어야 정기적 AmazonServiceRequestDelegate으로 작성됩니다. 내 NSOperations은 각각 NSOperationQueue에 추가되어 비 동시성으로 작업을 실행합니다. 위임자 인 [putObjectRequest setDelegate:s3Delegate]을 사용하면 작업이 작동하지 않습니다. 대리자 사용을 제거하면 올바르게 수행되지만 대리자가 없으므로 작업에 대한 응답을받을 수 없습니다.

NSOperationQueue의 사용을 완전히 제거하고 [putObjectRequest setDelegate:s3Delegate]을 사용하면 대리인이 완벽하게 작동합니다.

내 질문에 내가 대기열에서 대리인을 사용하여 잘못하고 무엇입니까? 델리게이트가 대기열에없는 동안 완벽하게 수행 할 수 있기 때문에 이것은 주 스레드에서 수행하지 않는 것과 관련 될 수 있습니까? 정말 비 동시 작업의 수를 제한하기 위해 대기열을 사용할 수 있기를 원하지만이 문제를 파악할 수는 없습니다. 나는 누군가가 여기에서 무슨 일이 일어나고 있는지를 알기를 바랍니다. 그리고 어떤 예제 코드도 크게 감사 할 것입니다. 감사! 건배, 트론

답변

8

aws sdk는 대리인을 설정할 때 비동기 적으로 작동하는 것으로 보입니다. 부울, 당신의 .H NSOperation 파일에서

를 추가 :

@interface UploadOperation : NSOperation <AmazonServiceRequestDelegate> { 
    @private 
    BOOL  _doneUploadingToS3; 
} 
을 은 그래서 (비동기)에 NSOperation을 비동기식 AWS 물건 작업을하기 위해, 당신은 AWS가 완료 될 때까지 기다려야 마법을 넣어 가지고

하고하는 .m 파일에서 당신의 주요 방법은 다음과 같이 표시됩니다

- (void) main 
{ 
    .... do your stuff ….. 

    _doneUploadingToS3 = NO; 

    S3PutObjectRequest *por = nil; 
    AmazonS3Client *s3Client = [[AmazonS3Client alloc] initWithAccessKey:ACCESS_KEY withSecretKey:SECRET_KEY]; 
    s3Client.endpoint = endpoint; 

    @try { 
     por = [[[S3PutObjectRequest alloc] initWithKey:KEY inBucket:BUCKET] autorelease]; 
     por.delegate = self; 
     por.contentType = @"image/jpeg"; 
     por.data = _imageData; 

     [s3Client putObject:por]; 
    } 
    @catch (AmazonClientException *exception) { 
     _doneUploadingToS3 = YES; 
    } 

    do { 
     [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]; 
    } while (!_doneUploadingToS3); 

    por.delegate = nil; 

    .... continue with your stuff …. 
} 

을 대리자 메서드를 구현하는 것을 잊지 마세요

-(void)request:(AmazonServiceRequest *)request didCompleteWithResponse:(AmazonServiceResponse *)response 
{ 
    _doneUploadingToS3 = YES; 
} 

-(void)request:(AmazonServiceRequest *)request didFailWithError:(NSError *)error 
{ 
    _doneUploadingToS3 = YES; 
} 

-(void)request:(AmazonServiceRequest *)request didFailWithServiceException:(NSException *)exception 
{ 
    _doneUploadingToS3 = YES; 
} 

- (void) request:(AmazonServiceRequest *)request didSendData:(NSInteger)bytesWritten totalBytesWritten:(NSInteger)totalBytesWritten totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite 
{ 
    // Do what you want 
} 

-(void)request:(AmazonServiceRequest *)request didReceiveResponse:(NSURLResponse *)response 
{ 
    // Do what you want 
} 

-(void)request:(AmazonServiceRequest *)request didReceiveData:(NSData *)data 
{ 
    // Do what you want 
} 

참고 :이 마법은 비동기 적으로 수행되지만 NSOperation에서 구현되어야하는 모든 작업에 사용할 수 있습니다.

+0

고맙습니다! 그것은 당신의 제안과 완벽하게 작동했습니다. 이 작업을 코드로 사용하는 트릭이 있습니다. 'do {[[NSRunLoop currentRunLoop] runMode : NSDefaultRunLoopMode beforeDate : [NSDate distantFuture]];} while (! _doneUploadingToS3);'이 스 니펫없이 작업을 실행하려고했는데 작동하지 않았다. 이를 포함 시키면 대리인이 원활하게 작동합니다. 왜이 코드가 왜 그렇게 중요하며 어떻게 동작하는지 설명해 주시겠습니까? 다시 한번 감사드립니다. 건배, Trond –

+1

이 루프는 _doneUploadingToS3이 YES로 설정 될 때까지 기다립니다. 그때까지는 (CPU를 과부하하지 않고) 반복합니다. AWS SDK의 완료 메소드 중 하나가 실행되면 _doneUploadingToS3이 YES로 설정되고 나머지 메인 메소드가 실행됩니다. – romrom

+0

정말 고마워요! 이것은 정확하게 나의 문제였습니다.태그 : AmazonServiceRequestDelegate가 작동하지 않음 Nsoperation nsoperationqueue – Jords