Prerak Sola Prerak Sola - 2 years ago 158
Swift Question

iOS import files into my application

I am creating an iOS application through which users can print the files on their device. From my application, I can access the files on the device though the

DocumentPicker
provided by other apps such as iCloud Drive, Dropbox, etc.

Now, I want to add a functionality where user can share the file with my application through an other application. I created an
Action Extension
for that.
For example, if I select an Image in the Photos application and select
Share
I get my extension in the Share sheet and when I select it, I also get the URL of the file. Next, I am creating a zip file of this file to send it to my server. But the issue is, the zip file is always empty. The code I am using is as below:

In Action Extension's 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)")
}
})
}


And my
createZip
function is as follows:

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"
}
}


Is there a way that I can create a zip of the shared files?

Answer Source

Your primary issue is that you are blindly adding image.debugDescription to an array that is expecting a file path. The output of image.debugDescription isn't at all a valid file path. You need to use a proper function on the image to obtain the actual file path.

But image is declared to have a type of NSSecureCoding. Based on the output of image.debugDescription, it seems that image is really of type NSURL. So you need to convert image to an NSURL using a line like:

if let photoURL = image as? NSURL {
}

Once you have the NSURL, you can use the path property to get the actual needed path.

So your code becomes:

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)")
                }
            }
    })
}

Hint: Never use debugDescription for anything other than a print statement. Its output is just some string that could contain just about any information and that output can change from one iOS version to the next.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download