iOS 将文件导入我的应用程序

Posted

技术标签:

【中文标题】iOS 将文件导入我的应用程序【英文标题】:iOS import files into my application 【发布时间】:2016-04-13 16:14:24 【问题描述】:

我正在创建一个 ios 应用程序,用户可以通过它在他们的设备上打印文件。在我的应用程序中,我可以通过 iCloud Drive、Dropbox 等其他应用程序提供的DocumentPicker 访问设备上的文件。

现在,我想添加一个功能,用户可以通过其他应用程序与我的应用程序共享文件。我为此创建了一个Action Extension。 例如,如果我在照片应用程序中选择一个图像并选择Share,我会在共享表中获得我的扩展名,当我选择它时,我还会获得文件的 URL。接下来,我正在创建此文件的 zip 文件以将其发送到我的服务器。但问题是,zip 文件总是空的。我使用的代码如下:

In Action Extension 的 viewDidLoad()

if itemProvider.hasItemConformingToTypeIdentifier(kUTTypeImage as String) 
    itemProvider.loadItemForTypeIdentifier(kUTTypeImage as String, options: nil, 
        completionHandler:  (image, error) in
            NSOperationQueue.mainQueue().addOperationWithBlock 
                print("Image: \(image.debugDescription)")
                //Image: Optional(file:///Users/guestUser/Library/Developer/CoreSimulator/Devices/00B81632-041E-47B1-BACD-2F15F114AA2D/data/Media/DCIM/100APPLE/IMG_0004.JPG)
                print("Image class: \(image.dynamicType)")
                //Image class: Optional<NSSecureCoding>
                self.filePaths.append(image.debugDescription)
                let zipPath = self.createZip(filePaths)
                print("Zip: \(zipPath)")
            
         )

而我的createZip函数如下:

func createZipWithFiles(filePaths: [AnyObject]) -> String 
    let zipPath = createZipPath()  //Creates an unique zip file name

    let success = SSZipArchive.createZipFileAtPath(zipPath, withFilesAtPaths: filePaths)

    if success 
        return zipPath
    
    else 
        return "zip prepation failed"
    

有没有一种方法可以创建共享文件的 zip?

【问题讨论】:

SSZipArchive 是否返回错误?你确定你有对zipPath的写访问权和对filePaths中所有路径的读访问权吗? 不,它不会给出任何错误。它在zipPath 创建一个zip 文件,因此我在zipPath 具有写访问权限。而且,filePaths 中的文件是来自默认照片应用程序的图像文件。在日志中它说文件在提到的位置不存在,但是如果我通过终端导航(对于模拟器),我可以看到该文件。 使用image.debugDescription 不是获取图像文件路径的方法。首先,完成处理程序中image 的实际类型是什么? image.debugDescription 的输出是什么? @rmaddy: 图像类型为NSSecureCodingimage.debugDescription 的输出类似于fie:///Users/xxx/Library/Developer/CoreSimulator/Devices/---xx-xx-xx/data/Media/DCIM/100APPLE/IMG_0004.jpg 您已发布 2 功能。第一次使用 self.createZip(filePaths),第二次使用 func createZipWithFiles,但我没有看到任何 createZip 方法.. 【参考方案1】:

您的主要问题是您盲目地将image.debugDescription 添加到需要文件路径的数组中。 image.debugDescription 的输出根本不是有效的文件路径。您需要在image上使用适当的函数来获取实际的文件路径。

image 被声明为具有NSSecureCoding 的类型。根据image.debugDescription 的输出,image 似乎确实属于NSURL 类型。因此,您需要使用以下行将image 转换为NSURL

if let photoURL = image as? NSURL 

获得NSURL 后,您可以使用path 属性来获取实际需要的路径。

所以你的代码变成了:

if itemProvider.hasItemConformingToTypeIdentifier(kUTTypeImage as String) 
    itemProvider.loadItemForTypeIdentifier(kUTTypeImage as String, options: nil, 
        completionHandler:  (image, error) in
            if let photoURL = image as? NSURL 
                NSOperationQueue.mainQueue().addOperationWithBlock 
                    let photoPath = photoURL.path
                    print("photoPath: \(photoPath)")
                    self.filePaths.append(photoPath)
                    let zipPath = self.createZip(filePaths)
                    print("Zip: \(zipPath)")
                
            
    )

提示:切勿将debugDescription 用于print 语句以外的任何内容。它的输出只是一些字符串,可以包含几乎任何信息,并且输出可以从一个 iOS 版本更改为下一个。

【讨论】:

感谢您的回答。在此之前,作为一种解决方法,我在我的应用程序的沙箱中使用NSData 创建一个临时图像,然后将该图像复制到 zip 文件以上传到服务器。但是您的方式节省了创建额外图像的处理和内存开销。 @rmaddy,我在我的应用中实现了共享扩展,在 iOS 13 中,我的共享扩展应用无法打开主应用以接收共享文件/图像,因为 UIApplication.shared 现在不可用。以前的所有版本都可以正常工作。那么,开发人员如何从不同来源接收/导入数据呢?假设我想从 gmail 或驱动器打开一个文件到我的应用程序,有什么解决方法吗?

以上是关于iOS 将文件导入我的应用程序的主要内容,如果未能解决你的问题,请参考以下文章

将 100MB XML 文件导入 iOS 核心数据模型

iOS8:扩展存储提供程序(导入、导出、移动)不起作用

将文件导入应用后保存文件

如何将 CSV 导入 sanity.io

如何 Flutter 将文件写入 iOS iPhone“在我的手机上查找”文件夹

如何将 openCV 导入 iOS 8 项目