0

I am presenting a share sheet to users, this obviously allows them to do a number of things but in my case, they are saving a gpx file to a location of their choice.

I would like to show a UIView when the document has been saved successfully, so my approach was to show the UIView once the share sheet is dismissed by the OS. However, the issue I am having is that if the user manually dismisses the share sheet options without saving the file the delegate method gets called and I only want the delegate method to be called if the user chooses an option from the share sheet.

My code:

func shareAction() {
    if let dir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first {
        let fileURL = dir.appendingPathComponent("\(gpxNameTextField.text!).gpx")
        URLSession.shared.dataTask(with: fileURL) { data, response, error in
            guard let data = data, error == nil else { return }
            let tmpURL = FileManager.default.temporaryDirectory
                .appendingPathComponent(response?.suggestedFilename ?? "\(self.gpxNameTextField.text!)")
            do {
                try data.write(to: tmpURL)
                DispatchQueue.main.async {
                    self.share(url: tmpURL)
                    self.deleteDraftGPXFile()
                }
            }
            catch {
                self.presentAlertView(title: "Error Saving File", message: "There was an error saving the GPX file to disk./nError: \(error.localizedDescription)")
                print(error)
            }
        }.resume()
    }
}

func share(url: URL) {
    documentInteractionController.url = url
    documentInteractionController.uti = url.typeIdentifier ?? "public.data, public.content"
    documentInteractionController.name = url.localizedName ?? url.lastPathComponent
    documentInteractionController.presentOptionsMenu(from: view.frame, in: view, animated: true)
    documentInteractionController.delegate = self
}
Chris
  • 247
  • 1
  • 4
  • 17

1 Answers1

0
func shareAction(_ callback: @escaping (Bool) -> () ) {
    if let dir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first {
        let fileURL = dir.appendingPathComponent("\(gpxNameTextField.text!).gpx")
        URLSession.shared.dataTask(with: fileURL) { data, response, error in
            guard let data = data, error == nil else { return }
            let tmpURL = FileManager.default.temporaryDirectory
                .appendingPathComponent(response?.suggestedFilename ?? "\(self.gpxNameTextField.text!)")
            do {
                try data.write(to: tmpURL)
                DispatchQueue.main.async {
                    self.share(url: tmpURL)
                    self.deleteDraftGPXFile()
                    callback(true)
                }
            }
            catch {
                self.presentAlertView(title: "Error Saving File", message: "There was an error saving the GPX file to disk./nError: \(error.localizedDescription)")
                print(error)
                callback(false)
            }
        }.resume()
    }
}

And use this method

sharedAction() { res in
if res {
// File was saved
}
  • Thanks for the suggestion but unfortunately the callback returns true as soon as the share sheet appears before any interaction by the user. – Chris Apr 04 '21 at 00:26
  • https://developer.apple.com/documentation/uikit/uidocumentinteractioncontrollerdelegate use https://developer.apple.com/documentation/uikit/uidocumentinteractioncontrollerdelegate/1616803-documentinteractioncontrollerdid – Владимир Ковальчук Apr 04 '21 at 01:09
  • Yep, that's what I am using but the delegates gets called even if the user dismisses the InteractionController by swiping down or tapping on the 'x' to close the controller. I need to ensure that the user actually shares or saves the file. – Chris Apr 04 '21 at 01:39