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?
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.