Я создал приложение, которое загружает файл plist с Amazon S3. Я использовал AFAmazonS3Client клиент, основанный на AFNetworking.

-(void) getFile:(NSString *)fileName{
    self.s3Manager = [[AFAmazonS3Manager alloc] initWithAccessKeyID:@"..." secret:@"..."];
    self.s3Manager.requestSerializer.region = AFAmazonS3SAEast1Region;
    self.s3Manager.requestSerializer.bucket = @"verba";

    NSString* documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    documentsPath = [documentsPath stringByAppendingPathComponent:fileName];

    NSOutputStream *stream = [[NSOutputStream alloc] initToFileAtPath:documentsPath append:NO];

    [self.s3Manager getObjectWithPath:@""
                         outputStream:stream
                             progress:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) {
         NSLog(@"%f%% Downloaded", (totalBytesRead / (totalBytesExpectedToRead * 1.0f) * 100));
    } success:^(id responseObject) {
         NSLog(@"Download Complete");
    } failure:^(NSError *error) {
        NSLog(@"Error: %@", error);
    }];
}

Затем я проверил, находится ли файл plist в папке с документами. И это было. Итак, я попытался открыть файл plist, и результат был нулевым:

-(NSString*) loadListName:(NSString*)fileName{
    NSString* documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    NSString* filePath = [documentsPath stringByAppendingPathComponent:fileName];

    NSDictionary *temp;
    if ([[NSFileManager defaultManager] fileExistsAtPath: filePath]){
        temp = [NSDictionary dictionaryWithContentsOfFile:filePath];
    } else {
        NSLog(@"File not found.");
    }

    NSString *listName = [temp objectForKey:@"name"];

    return listName;
}

Поэтому я попытался добавить файл plist вручную. Я загрузил и скопировал его в папку с документами, а затем dictionaryWithContentsOfFile смог открыть файл. Поэтому я полагаю, что файл plist был поврежден, когда я загружал файл с помощью AFAmazonS3Client.

Что я делаю не так?

Обновление 1

Я понимаю, что все файлы, загруженные с S3, повреждены. Я не знаю, правильно ли я обрабатываю NSOutputStream или, может быть, еще что-нибудь.

2
Sebastian 24 Окт 2014 в 17:11

2 ответа

Лучший ответ

По какой-то причине метод getObjectWithPath из AFAmazonS3Manager не работает должным образом.

Поэтому я переписываю свой метод, используя AFHTTPRequestOperation прямо из AFNetworking.

- (void)downloadFile:(NSString *)fileName block:(void (^)(NSError *error))block {

    NSString *urlString = @"https://[bucket].[server area].amazonaws.com/";
    urlString = [urlString stringByAppendingPathComponent:fileName];

    NSURL *url = [NSURL URLWithString:urlString];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];

    AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
    NSSet *set = operation.responseSerializer.acceptableContentTypes;

    if ([[fileName pathExtension] isEqualToString:@"m4a"]) {
        NSLog(@"%@ set as audio/mp4", fileName);
        operation.responseSerializer.acceptableContentTypes = [set setByAddingObject:@"audio/mp4"];
    } else if ([[fileName pathExtension] isEqualToString:@"png"]) {
        NSLog(@"%@ set as image/png", fileName);
        operation.responseSerializer.acceptableContentTypes = [set setByAddingObject:@"image/png"];
    } else if ([[fileName pathExtension] isEqualToString:@"plist"]) {
        NSLog(@"%@ set as application/x-plist", fileName);
        operation.responseSerializer.acceptableContentTypes = [set setByAddingObject:@"application/x-plist"];
    }

    NSString* documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];

    NSString *fullPath = [documentsPath stringByAppendingPathComponent:[url lastPathComponent]];

    [operation setOutputStream:[NSOutputStream outputStreamToFileAtPath:fullPath append:NO]];

    [operation setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) {
        NSLog(@"bytesRead: %lu, totalBytesRead: %lld, totalBytesExpectedToRead: %lld", (unsigned long)bytesRead, totalBytesRead, totalBytesExpectedToRead);
    }];

    [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {

        if (block) {
            block(nil);
        }

        NSLog(@"RES: %@", [[[operation response] allHeaderFields] description]);

        NSError *error;
        NSDictionary *fileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:fullPath error:&error];

        if (error) {
            NSLog(@"ERR: %@", [error description]);
        } else {
            NSNumber *fileSizeNumber = [fileAttributes objectForKey:NSFileSize];
            long long fileSize = [fileSizeNumber longLongValue];

            NSLog(@"%lld", fileSize);
        }


    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        if (block) {
            block(error);
        }
        NSLog(@"ERR: %@", [error description]);
    }];

    [operation start];
}
2
Sebastian 25 Окт 2014 в 23:31

Будьте осторожны, потому что в последней версии Xcode каждый раз, когда вы перезапускаете приложение в симуляторе, папка документов удаляется.

-1
PlugInBoy 24 Окт 2014 в 14:06