【问题标题】:iOS8: UIDocumentPickerViewController get NSDataiOS8:UIDocumentPickerViewController 获取 NSData
【发布时间】:2016-04-27 03:17:31
【问题描述】:

我已经根据docs 实现了UIDocumentPickerViewController,现在尝试在委托方法中从选取的文件中获取NSData,但[[NSData alloc] initWithContentsOfURL:] 返回nil:

- (void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentAtURL:(NSURL *)url{
    NSData* documentData = [[NSData alloc] initWithContentsOfURL:url];
    //documentData is nil
    documentData = [[NSData alloc] initWithContentsOfFile:[url path]];
    //documentData is still nil :(
}

我正在使用 Xcode6 beta6,iPhone 模拟器,文档选择器模式为 UIDocumentPickerModeImport。 正在尝试检索保存到 iCloude Drive 的文档。

【问题讨论】:

    标签: ios objective-c ios8


    【解决方案1】:

    在这里详细阐述@cescofry 关于 iWork 文件(.pages、.numbers、.key)的回答,这样其他人就不必重新发现这个问题了。 (这也适用于非 iWork 文件。)

    如果您从 iCloud 拉取 iWork 文件,在获得有效的 NSData 对象之前,您需要担心两个主要的事情。 A)通过 NSFileCoordinator 对象(由@cescofry 覆盖)和 B)iWork 文件实际上是目录/包而不是单个文件的安全范围。你想要的coordinateReadingItemAtURL:options 参数是NSFileCoordinatorReadingForUploading。这将读取单个文件,就像您使用了 0 一样,但会自动将目录转换为 zip 文件。去掉添加的.zip,您将拥有一个有效的 Pages/Numbers/Keynote 文件。 (它也有效。)

    [url startAccessingSecurityScopedResource];
    NSFileCoordinator *coordinator = [[NSFileCoordinator alloc] init];
    NSError *error;
    __block NSData *fileData;
    
    [coordinator coordinateReadingItemAtURL:url options:NSFileCoordinatorReadingForUploading error:&error byAccessor:^(NSURL *newURL) {
       // File name for use in writing the file out later
       NSString *fileName = [newURL lastPathComponent];
       NSString *fileExtension = [newURL pathExtension];
    
       if([fileExtension isEqualToString:@"zip"]) {
         if([[[newURL URLByDeletingPathExtension] pathExtension] isEqualToString:@"pages"] ||
            [[[newURL URLByDeletingPathExtension] pathExtension] isEqualToString:@"numbers"] ||
            [[[newURL URLByDeletingPathExtension] pathExtension] isEqualToString:@"key"] ) {
           // Remove .zip if it is an iWork file
           fileExtension = [[newURL URLByDeletingPathExtension] pathExtension];
           fileName = [[newURL URLByDeletingPathExtension] lastPathComponent];
         }
       }
    
       NSError *fileConversionError;
       fileData = [NSData dataWithContentsOfURL:newURL options:NSDataReadingUncached error:&fileConversionError];
    
       // Do something with the file data here
    
    }
    [url stopAccessingSecurityScopedResource];
    

    这里有关于 NSFileCoordinator 选项的相关 Apple 文档: https://developer.apple.com/library/ios/documentation/Foundation/Reference/NSFileCoordinator_class/#//apple_ref/c/tdef/NSFileCoordinatorReadingOptions

    【讨论】:

      【解决方案2】:

      需要通过文件协调器访问来自文档选择器的 URL。此外,还需要在范围内查看 url:

      [url startAccessingSecurityScopedResource];
      
      __block NSData *data
      
       NSFileCoordinator *coordinator = [[NSFileCoordinator alloc] init];
       NSError *error;
       [coordinator coordinateReadingItemAtURL:url options:0 error:&error byAccessor:^(NSURL *newURL) {
          data = [NSData dataWithContentsOfURL:url];
       }];
      
       [url stopAccessingSecurityScopedResource];
      

      更多来自Apple documentation

      【讨论】:

        【解决方案3】:

        问题在于,实际上 Page 文档 (*.pages) 不是文件,而是文件夹。因此,当我尝试从文件夹路径中获取 NSData 时,它返回 nil。

        默认 Mail.app 将文档附加为 zip 存档。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-11-20
          • 1970-01-01
          • 1970-01-01
          • 2011-06-05
          • 2012-06-22
          • 1970-01-01
          相关资源
          最近更新 更多