2

While trying to share an '.mp3' file that I have downloaded onto my app using the device's share-sheet feature, I'm able to fetch the file from the documents directory but unable to share it.

When I try to share it via Whatsapp, I get an error saying:

This item cannot be shared. Please select a different item.

If I share via AirDrop, it just says "Failed" (in red) and sharing via other options leads to a blank message (e.g. a new email with no file attached or a new msg with nothing in it)

Here are the code options I've tried so far:

Option 1 - Using UIActivityViewController

let fileURL = NSURL(fileURLWithPath: FileURLFromDocumentsDirectory)

var filesToShare = [Any]()

filesToShare.append(fileURL)

let activityViewController = UIActivityViewController(activityItems: filesToShare, applicationActivities: nil)

self.present(activityViewController, animated: true, completion: nil)

Option 2 - Using UIDocumentInteractionController

let docController : UIDocumentInteractionController?
docController = UIDocumentInteractionController(url: URL(string: fileToSharePath)!)
docController?.delegate = self
docController?.presentOptionsMenu(from: self.view.frame, in:self.view, animated:true)

In both options, I do get the file but can't share it. The phone does recognize the share as an audio file but I can't do anything with it.

Sample URL:

file:///Users/UserName/Library/Developer/CoreSimulator/Devices/C8B09E62-091F-4E61-BA6C-3D9EC23LKC01/data/Containers/Data/Application/EF2CKKJF-AB35-55G5-B778-439812EFGGG5/Documents/audioFile.mp3

The sharing works for text but not for the audio files.

Do I also need to enable some features or add some code to the AppDelegate?

Appreciate any help. Thanks.

Update #1: Code with Suggestions from @dfd [still doesn't work]

let shareAction = UIContextualAction(style: .normal, title: "Share") { (action, view, completionHandler) in
            
    let fileURL = NSURL(fileURLWithPath: (downloadedFile?.documentDirectoryURL)!)

    let activityViewController = UIActivityViewController(activityItems: [fileURL], applicationActivities: nil)

    self.present(activityViewController, animated: true, completion: nil)
                
}

Also, for all these options, I get the audio file (mp3) as an 'Audio Recording' in the Share Sheet.

zaam
  • 287
  • 1
  • 2
  • 14
  • At which line you add an audio file to filesToShare? – El Tomato Jan 03 '21 at 22:35
  • So here's the flow: Files downloaded and stored to disk > user loads these in a tableView > swipes to see and click share action - the above code is called in the 'leadingSwipeActionsConfigurationForRowAt' delegate method, where I first call the object to get the URL of the audio and then pass it in the code above. Am I missing a step? (I do get the audio file in the share sheet though, just can't pass it over from there to other apps or AirDrop) – zaam Jan 03 '21 at 23:31
  • Just only a guess, but have you tried more specific code? To use `UIActivityViewController` with certain file types and/or activity types, you may need to (a) not make your files be `[Any]` and (b) remove them from your excluded activity types. –  Jan 04 '21 at 02:07
  • Thank I've tried that again, made sure that I'm not casting the files to be any but rather passing the file URL directly in the activityController but it still doesn't work. The file I get in the shareSheet is recognized as an 'audio recording' - is it the right type for an mp3? See the updated post for the code with your suggestions (maybe I'm doing something wrong?) ---- also I've not included any excluded types at all for either options. – zaam Jan 04 '21 at 20:02

1 Answers1

0

Instead of sharing the original file, can you try to create a copy of this in a temporary directory and share that copy. Once done with sharing you can delete or leave it to the system to delete it.

Something like this (You can add more check about file and directory existance):

let fileManager = FileManager.default
let tempDirectory = fileManager.temporaryDirectory
let tempPath = tempDirectory.path + "/" + fileToSharePath.lastPathComponent
let tempURL = URL(fileURLWithPath: tempPath)
try? fileManager.copyItem(atPath:fileToSharePath.path , toPath: tempPath)


let docController : UIDocumentInteractionController?
docController = UIDocumentInteractionController(url: URL(string: tempURL)!)
docController?.delegate = self
docController?.presentOptionsMenu(from: self.view.frame, in:self.view, animated:true)
Manish Punia
  • 747
  • 4
  • 9
  • Thanks. It was a creative approach but sadly didn't work. Seem to face the same problem - can't share via any channels. The tempURL I got while sharing was file:///private/var/mobile/Containers/Data/Application/56C0AA16-BAE5-497B-AD21-57C6DFL5C137/tmp/audio.mp3 - consistent to the original method but still doesn't work. Also, I corrected the third last line and passed the tempURL directly, since it was already cast as a URL (not a string) - just in case someone else tries it. – zaam Jan 06 '21 at 16:53
  • I'm wondering if we need to make some entries in the plist file or enable some capabilities to enable sharing... can't seem figure out though... – zaam Jan 06 '21 at 17:09
  • Interesting, No we don't need to add anything in plist for this. Are you seeing any errors in the console while sharing? Are you facing issue with just audio files or other files too? – Manish Punia Jan 07 '21 at 05:22
  • No errors at all. Just audio files at the moment. I can share text without a problem. – zaam Jan 07 '21 at 14:08