Я создал приложение, которое загружает файл 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.
Что я делаю не так?
Я понимаю, что все файлы, загруженные с S3, повреждены. Я не знаю, правильно ли я обрабатываю NSOutputStream или, может быть, еще что-нибудь.
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];
}
Будьте осторожны, потому что в последней версии Xcode каждый раз, когда вы перезапускаете приложение в симуляторе, папка документов удаляется.
Похожие вопросы
Новые вопросы
objective-c
Этот тег следует использовать только для вопросов, касающихся функций Objective-C или зависящих от кода на языке. Теги [cocoa] и [cocoa-touch] следует использовать, чтобы узнать о фреймворках или классах Apple. Используйте связанные теги [ios], [macos], [apple-watch] и [tvos] для проблем, характерных для этих платформ.
NSString
иNSSLog
его. Если проблема не очевидна, попробуйте проверить plist с помощью приложения. Или добавьте содержимое полосы к вашему вопросу, если он не слишком длинный или конфиденциальный.