From 6e70c479eba12da7f6e2c95f548cc271340eec9f Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Thu, 11 Jan 2018 17:00:53 -0500 Subject: [PATCH] Improve handling of contacts. --- .../ShareViewController.swift | 25 +++++++++++++------ 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/SignalShareExtension/ShareViewController.swift b/SignalShareExtension/ShareViewController.swift index 1d38989708..2f4377807d 100644 --- a/SignalShareExtension/ShareViewController.swift +++ b/SignalShareExtension/ShareViewController.swift @@ -441,7 +441,7 @@ public class ShareViewController: UINavigationController, ShareViewDelegate, SAE }.retainUntilComplete() } - private func itemMatchesSpecificUtiType(itemProvider: NSItemProvider, utiType: String) -> Bool { + private class func itemMatchesSpecificUtiType(itemProvider: NSItemProvider, utiType: String) -> Bool { // URLs, contacts and other special items have to be detected separately. // Many shares (e.g. pdfs) will register many UTI types and/or conform to kUTTypeData. guard itemProvider.registeredTypeIdentifiers.count == 1 else { @@ -453,17 +453,17 @@ public class ShareViewController: UINavigationController, ShareViewDelegate, SAE return firstUtiType == utiType } - private func isUrlItem(itemProvider: NSItemProvider) -> Bool { + private class func isUrlItem(itemProvider: NSItemProvider) -> Bool { return itemMatchesSpecificUtiType(itemProvider:itemProvider, utiType:kUTTypeURL as String) } - private func isContactItem(itemProvider: NSItemProvider) -> Bool { + private class func isContactItem(itemProvider: NSItemProvider) -> Bool { return itemMatchesSpecificUtiType(itemProvider:itemProvider, utiType:kUTTypeContact as String) } - private func isSpecialItem(itemProvider: NSItemProvider) -> Bool { + private class func isSpecialItem(itemProvider: NSItemProvider) -> Bool { if isUrlItem(itemProvider:itemProvider) { return true } else if isContactItem(itemProvider:itemProvider) { @@ -473,7 +473,7 @@ public class ShareViewController: UINavigationController, ShareViewDelegate, SAE } } - private func utiTypeForItem(itemProvider: NSItemProvider) -> String? { + private class func utiTypeForItem(itemProvider: NSItemProvider) -> String? { Logger.info("\(self.logTag) utiTypeForItem: \(itemProvider.registeredTypeIdentifiers)") if isUrlItem(itemProvider:itemProvider) { @@ -508,7 +508,7 @@ public class ShareViewController: UINavigationController, ShareViewDelegate, SAE } Logger.info("\(self.logTag) attachment: \(itemProvider)") - guard let utiType = utiTypeForItem(itemProvider: itemProvider) else { + guard let utiType = ShareViewController.utiTypeForItem(itemProvider: itemProvider) else { let error = ShareViewControllerError.unsupportedMedia return Promise(error: error) } @@ -516,6 +516,8 @@ public class ShareViewController: UINavigationController, ShareViewDelegate, SAE let (promise, fulfill, reject) = Promise.pending() + var customFileName: String? + itemProvider.loadItem(forTypeIdentifier: utiType, options: nil, completionHandler: { (provider, error) in @@ -533,6 +535,11 @@ public class ShareViewController: UINavigationController, ShareViewDelegate, SAE Logger.info("\(self.logTag) provider type: \(type(of:provider))") if let data = provider as? Data { + if ShareViewController.itemMatchesSpecificUtiType(itemProvider:itemProvider, + utiType:kUTTypeVCard as String) { + customFileName = "Contact.vcf" + } + let tempDirPath = NSTemporaryDirectory() var tempFileName = NSUUID().uuidString if let customFileExtension = MIMETypeUtil.fileExtension(forUTIType:utiType) { @@ -585,7 +592,9 @@ public class ShareViewController: UINavigationController, ShareViewDelegate, SAE guard let dataSource = rawDataSource else { throw ShareViewControllerError.assertionError(description: "Unable to read attachment data") } - if utiType != (kUTTypeURL as String) { + if let customFileName = customFileName { + dataSource.sourceFilename = customFileName + } else if utiType != (kUTTypeURL as String) { // Ignore the filename for URLs. dataSource.sourceFilename = url.lastPathComponent } @@ -654,7 +663,7 @@ public class ShareViewController: UINavigationController, ShareViewDelegate, SAE // Perhaps the AVFoundation APIs require some extra file system permssion we don't have in the // passed through URL. private func isVideoNeedingRelocation(itemProvider: NSItemProvider, itemUrl: URL) -> Bool { - if isSpecialItem(itemProvider:itemProvider) { + if ShareViewController.isSpecialItem(itemProvider:itemProvider) { return false }