通过iOS中的共享扩展程序从Mail App共享附件

时间:2016-04-08 10:02:14

标签: ios swift share-extension

现在我正在开发应该实现共享扩展以从Mail App共享附件的应用程序。它应该支持不同的文件扩展名(几乎所有类型的文档)。从Apple docs我明白我必须在我的Info.plist中使用Predicate,但在SO的答案中我发现我必须在代码中使用它。现在我坚持不懈,无法继续前进。以下是我想从此post使用的谓词。

SUBQUERY (
            extensionItems,
            $extensionItem,
            SUBQUERY (
            $extensionItem.attachments,
            $attachment,

            (
                       ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "com.adobe.pdf"
                    || ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.image"
                    || ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.png"
                    || ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.jpeg"
                    || ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.jpeg-2000"
                    || ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.tiff"
                    || ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "com.compuserve.gif"
                    || ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "com.microsoft.bmp"
                    || ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "com.microsoft.word.doc"
                    || ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "org.openxmlformats.wordprocessingml.document"
            )
).@count == $extensionItem.attachments.@count
).@count == 1

任何人都可以建议如何在我的swift代码中使用这个谓词:

    for attachment in content.attachments as! [NSItemProvider] {
        if attachment.hasItemConformingToTypeIdentifier(contentType) {

            attachment.loadItemForTypeIdentifier(contentType, options: nil) { data, error in
                if error == nil {
                    let url = data as! NSURL
                    if let fileData = NSData(contentsOfURL: url) {
                        self.selectedFile = NSData(data: fileData)
                    }
                } else {

                    let alert = UIAlertController(title: "Error", message: "Error loading file", preferredStyle: .Alert)

                    let action = UIAlertAction(title: "Error", style: .Cancel) { _ in
                        self.dismissViewControllerAnimated(true, completion: nil)
                    }

                    alert.addAction(action)
                    self.presentViewController(alert, animated: true, completion: nil)
                }
            }
        }
    }

这是我的NSExtensionActivationRule:

        <key>NSExtensionActivationRule</key>
        <dict>
            <key>NSExtensionActivationSupportsAttachmentsWithMaxCount</key>
            <integer>1</integer>
        </dict>

提前致谢。

1 个答案:

答案 0 :(得分:3)

所以最后我在问题上找到了答案!以防万一有人会遇到同样的问题.. 首先,我必须在Info.plist中使用PREDICATE语句(子查询)而不是密钥NSExtensionActivationSupportsAttachmentsWithMaxCount。像:

        <key>NSExtensionActivationRule</key>
        <string>SUBQUERY (
            extensionItems,
            $extensionItem,
            SUBQUERY (
            $extensionItem.attachments,
            $attachment,
            (
            ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "com.adobe.pdf"
            || ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.image"
            || ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.plain-text"
            || ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.png"
            || ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.jpeg"
            || ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.jpeg-2000"
            || ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.tiff"
            || ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "com.compuserve.gif"
            || ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "com.microsoft.bmp"
            || ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "com.microsoft.word.doc"
            )
            ).@count == 1   // Important! to activate extension only on 1 chosen image
            ).@count == 1
        </string>

第二:使用必要的TypeIdentifier(UTI)正确获取所有附件:

    if let content = extensionContext!.inputItems.first as? NSExtensionItem {
        if let contents = content.attachments as? [NSItemProvider] {
            for attachment in contents{
                attachment.loadItemForTypeIdentifier("public.item", options: nil) { data, error in
                    let url = data as! NSURL
                    let fileExtension = url.pathExtension as String!
                    let fileName = self.generateImageName() as String
                    if let fileData = NSData(contentsOfURL: url) {
                        self.uploadFile("\(fileName).\(fileExtension)", data: fileData)
                    }
                }
            }
        }
    }

“public.item” - 是通用UTI,支持NSExtensionActivationRule字符串中列出的所有类型的文件扩展名。 您可以在https://developer.apple.com

上获得必要的UTI

开发动作扩展程序,祝你好运!欢迎任何问题!