How to share a pdf that is on a Swift webview

Asked

Viewed 175 times

2

I have a webview and I call it an address that if accessed by a browser forces a PDF download, in the app I created uploaded the PDF in a webview, but I would also like to give the user the option to share this PDF by email, send to Iclouddrive, send to Ibook`s etc.

func asyncTask(parametros: String, id: String) {

        DispatchQueue.global(qos: DispatchQoS.userInitiated.qosClass).async {

            DispatchQueue.main.async 
                let boletoURL = URL(string: "http://www.meusite/01_2017.pdf")
                print(boletoURL!)
                let boletoURLRequest = URLRequest(url: boletoURL!)
                self.webView.isUserInteractionEnabled = true
                self.webView.loadRequest(boletoURLRequest)
            }
        }
    }

2 answers

1


You must use the specific apple framework to compose messages called Messageui. To attach a file to an email You need to read the data in your pdf and use the addAttachmentData method to attach it to the email. If your file is online you need to download asynchronously using Urlsession dataTaskWithURL. If you want to save the file to disk before attaching to email use downloadTaskWithURL:

import MessageUI
class ViewController: UIViewController, MFMailComposeViewControllerDelegate {
    @IBOutlet weak var button: UIButton!
    @IBAction func compose(_ sender: UIButton) {
        if MFMailComposeViewController.canSendMail() {
            let mailComposer = MFMailComposeViewController()
            mailComposer.mailComposeDelegate = self
            mailComposer.setToRecipients(["[email protected]"])
            mailComposer.setSubject("Assunto !!!")
            mailComposer.setMessageBody("Texto da mensagem", isHTML: false) // texto padrao ou codigo html
            // para mandar um arquivo que esta online voce precisa baixar ele antes:
            let text = "Se quiser mandar um arquivo de texto por exemplo"
            mailComposer.addAttachmentData(Data(text.utf8), mimeType: "text/plain", fileName: "arquivo.txt")
            // voce pode enviar mais de um arquivo attached se necessario.
            // caso voce precise baixar o arquivo antes eu recomendo URL Session dataTaskWithURL
            URLSession.shared.dataTask(with: URL(string:"https://www.domain.com/arquivo.pdf")!) { data, response, error in
                guard let data = data, error == nil else {
                    print(error ?? "nil")
                    UIApplication.shared.isNetworkActivityIndicatorVisible = false
                    self.button.isEnabled = true
                    return
                }
                print("bytes:", data.count)
                mailComposer.addAttachmentData(data, mimeType: "application/pdf", fileName: "arquivo.pdf")
                DispatchQueue.main.async {
                    self.present(mailComposer, animated: true)
                }           
            }.resume()
            button.isEnabled = false
            UIApplication.shared.isNetworkActivityIndicatorVisible = true
            print("download started !!! ao final do download a janela de email sera apresentada !!!")
        }
    }
    func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {
        controller.dismiss(animated: true) { 
            switch result {
                case .cancelled: print("cancelled")
                case .saved:     print("saved")
                case .sent:
                    let alert = UIAlertController(title: "Mail Composer", message: "Mail was successfully sent", preferredStyle: .alert)
                    alert.addAction(UIAlertAction(title: "Done", style: .default, handler: nil))
                    self.present(alert, animated: true)
                case .failed:    print("failed")
            }
        }
    }
}
  • I added a button in the webview connected it with this function that you created but nothing happens. returned this log: 2017-03-31 13:02:55.007482-0300 Unip[1449:256368] [MC] Filtering mail sheet Accounts for Bundle ID: br.com.Unip, source Account management: 1 2017-03-31 13:02:55.008939-0300 Unip[1449:256368] [MC] Result: NO

  • App transport security info plist Exception Domain list

  • returned this now: [MC] Invalidating cache

  • Julio didicil help if Voce not ask right. I believe your problem is only App security. If you want to let file download from anywhere you have to enable allow arbitrary downloads which has nothing to do with your question in question. If you go google this Voce will find a lot of results showing how to change your info.plist. That’s not the purpose of the site. If I write your entire code, you won’t learn anything and you’ll come back here and ask me to fix any errors in your code

  • Leo Dabus, the arbitrary allow is enabled. I’m not understanding your placement, I’ve been researching solutions to this for days and the most I could was share the link, then I decided to ask, if someone wants to help there is already another story, If someone comes along who actually puts the solution I will surely give the credit, only you want credit without solving the question???? , I’m really new at this and I’m here learning, who wants to teach me thank you from the heart, who does not want or need to post, just keep your knowledge for yourself.

  • If your code had really worked, I would have told you

  • kkkkk Want me to post a project zip ???

  • If I can thank you, really my intention here is not to discuss or belittle anyone, I’m here to learn

  • https://www.dropbox.com/s/8rs2ed3qedrfi/Mail%20Composer.zip? dl=1

  • 1

    I have to test it on my cell phone, right? I tested your project by emulator and nothing happened, but assuming that it will download the PDF could be missing some permission on the MAC that I don’t know, then I decided to install it on the phone and it worked. Thank you

  • It must not have worked in the emulator because Voce needs to set up an email account. Nothing

Show 6 more comments

0

Hello, for this case use the UIActivityViewController:

if  let shareURL = URL(string: "http://www.meusite/01_2017.pdf") {

    var shareItems = [Any]()
    shareItems.append("Compartilhar em...")
    shareItems.append(shareURL)

    let avController = UIActivityViewController(activityItems: shareItems, applicationActivities: nil)
    avController.excludedActivityTypes : [UIActivityType] = [
        .postToWeibo, 
        .message,
        .mail,
        .print,
        .copyToPasteboard,
        .assignToContact,
        .saveToCameraRoll,
        .addToReadingList,
        .postToFlickr,
        .postToVimeo,
        .postToTencentWeibo,
        .airDrop
    ] // caso queira excluir alguma opção

    self.present(avController, animated: true, completion: nil)
}
  • Felipe, thank you for the comment, but it didn’t just work shared the link

  • @Juliofigueiredo try instead of sending a URL, send the Data. Something like: let data = Data(contentsOfURL: shareURL). Then you add the result in: shareItems.append(data). Abs!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.