使用委托,操作和队列

Tro*_*sen 1 cocoa objective-c amazon-s3 amazon-web-services

我正在使用AWS SDK for iOS从本地硬盘驱动器上传和下载文件到Amazon S3存储.我能够完成这项工作,但我无法让S3代表在操作完成或导致错误时正确响应以提醒我.

我有一系列要上传的文件.对于每个文件创建一个NSOperationmain例行包含较多:

    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];
Run Code Online (Sandbox Code Playgroud)

这里,delegate(s3Delegate)被创建为常规的AmazonServiceRequestDelegate,它应该能够在操作完成时触发响应.我的每一个NSOperations都被添加到我的NSOperationQueue非同时执行操作.如果我使用委托,[putObjectRequest setDelegate:s3Delegate]则操作无效.如果我删除了委托的使用,则操作正确执行但我无法接收任何操作响应,因为我没有委托.

如果我NSOperationQueue完全删除了使用,并使用[putObjectRequest setDelegate:s3Delegate]委托完美.

我的问题是在队列中使用委托我做错了什么?由于委托完全能够执行而不在队列中,这可能与不在主线程上执行有关吗?我真的希望能够使用队列来限制非并发操作的数量,但我无法弄清楚这一点.我希望有人知道这里发生了什么,任何示例代码将不胜感激.谢谢!干杯,特隆德

rom*_*rom 8

似乎aws sdk在您设置委托后的时间内表现异步.因此,为了使您的异步aws工作在(异步)NSOperation中工作,您必须付出一些魔力等待AWS完成:

在你的.h NSOperation文件中,添加一个布尔值:

@interface UploadOperation : NSOperation <AmazonServiceRequestDelegate> {
    @private
    BOOL        _doneUploadingToS3;
}
Run Code Online (Sandbox Code Playgroud)

在.m文件中,main方法如下所示:

- (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 ….
}
Run Code Online (Sandbox Code Playgroud)

不要忘记实现你的委托方法

-(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
}
Run Code Online (Sandbox Code Playgroud)

注意:这个魔法可以用于任何异步执行但必须在NSOperation中实现的东西.