发送带有多个附件的电子邮件(快速)

时间:2020-09-26 22:33:21

标签: ios swift email email-attachments

我想发送带有多个excel附件的电子邮件。
下面的代码具有func来创建每个文件并将其保存在创建的用户目录中。 文件保存良好。 电子邮件已生成并可以正常发送。

我无法解决的一个问题是:它为每个文件附加了两个副本,导致电子邮件具有两组附加数据。

问题似乎出在配置了func的MailComposeViewController中。

有人可以帮助我修复代码,使其仅发送一组文件吗?

class ExportToExcel: UIViewController, MFMailComposeViewControllerDelegate, UINavigationControllerDelegate {

var taskArr = [Export]()
var task: Export!
var noteID:Int = -1
var contactID:Int = -1
var companyID:Int = -1

let mailComposer = MFMailComposeViewController()

var fileNameNote = String()
var fileNameCompany = String()
var fileNameWC = String()
var fileNameBldg = String()
var fileNameCurrent = String()
var fileNameLoss = String()

fileprivate var contactDetails: ContactModel = ContactModel()
fileprivate var companyDetails: ContactModel = ContactModel()
fileprivate var quickNoteDetails: QuickNoteModel = QuickNoteModel()
fileprivate var bizDetails: BizDetailsModel = BizDetailsModel()
fileprivate var imageNames: Array<PhotoModel> = [PhotoModel]()

override func viewDidLoad() {
    super.viewDidLoad()
    
    // creating the "MeetingNotes" directory
    self.createNewDir()
    
    mailComposer.mailComposeDelegate = self
    mailComposer.delegate = self
                
    self.sendEmailButton()
}

func setFileLocation(_ fileName: String) -> URL {
    let filemgr = FileManager.default
    let dirPaths = filemgr.urls(for: .documentDirectory, in: .userDomainMask)
    let docsURL = dirPaths[0].appendingPathComponent("MeetingNotes")
    let path = docsURL.appendingPathComponent(fileName)
    
    return path
}

func createNewDir() {
    let filemgr = FileManager.default
    let dirPaths = filemgr.urls(for: .documentDirectory, in: .userDomainMask)
    let docsURL = dirPaths[0]
    let newDir = docsURL.appendingPathComponent("MeetingNotes").path
    do {
        try filemgr.createDirectory(atPath: newDir,
                    withIntermediateDirectories: true, attributes: nil)
        } catch let error as NSError {
                print("Error: \(error.localizedDescription)")
    }
}

func createNoteCSV() -> Void {
    
    fileNameNote = ("\(task.Company_Name)-\(task.Note_Date)-Note.xls").removeSpaces

    let path = setFileLocation(fileNameNote)

    var csvText = "Note Date,Note Details,Company Name,Company Phone,Contact Name,Contact Office,Contact Mobile,Contact Email,Coverages,BOP SIC,NAICS\n"
    
    let newLine = "\(task.Note_Date),\(task.Notes.removeCommas),\(task.Company_Name),\(task.Company_Phone),\(task.Contact_Name),\(task.Contact_Office),\(task.Contact_Mobile),\(task.Contact_Email),\(task.Coverages),\(task.BOP_SIC),\(task.NAICS)"
            
        csvText.append(newLine)
    do {
        try csvText.write(to: path, atomically: true, encoding: String.Encoding.utf8)
        let url = path
        let activityViewController = UIActivityViewController(activityItems: [url as Any] , applicationActivities: nil)
        DispatchQueue.main.async {
            self.present(activityViewController, animated: true, completion: nil)
        }
    } catch {
        print("Failed to create file ")
        print("\(error)")
    }
}

func createBldgCSV() -> Void {
    if !BuildingsArrayExport.array.isEmpty {
        fileNameBldg = ("\(task.Company_Name)-\(task.Note_Date)-Bldg.xls").removeSpaces

        let path = setFileLocation(fileNameBldg)

        var csvText = "Note Date,Company Name,Bldg Nickname,Bldg Address, Bldg City, Bldg State, Bldg Zipcode,Deductible,Bldg Year,Office SqFt,Bldg SqFt,Floors,Roof Type,Construction Type,Bldg Type,Bldg Value,Yr Heat Replaced,Yr Wire Replaced,Yr Roof Replaced,Yr Plumbing Replaced,Pct Bldg Occupied,Pct Tenant Occupied,Pct Sprinkler,Responible for Parking lot,Alarm Type\n"
        
        let items = BuildingsArrayExport.array
        for item in items {
            let address  = "\(item.address1) \(item.address2)"
            let newLine = "\(task.Note_Date),\(task.Company_Name),\(item.nickName),\(address.removeCommas),\(item.city.removeCommas),\(item.state),\(item.zipCode),\(item.deductible.removeCommas),\(item.buildingYr),\(item.officeSqFt),\(item.buildingSqFt),\(item.buildingStories),\(item.roofType.removeCommas),\(item.constructionType.removeCommas),\(item.buildingType.removeCommas),\(item.buildingValue.removeCommas),\(item.heatingReplaced),\(item.wiringReplaced),\(item.roofReplaced),\(item.plumbingReplaced),\(item.percentUnoccupied),\(item.percentOthersOccupied),\(item.sprinklerSystem),\(item.responsibleForParkingLot),\(item.alarmType)\n"
                    
                csvText.append(newLine)
        }
        do {
            try csvText.write(to: path, atomically: true, encoding: String.Encoding.utf8)
            let url = path
            let activityViewController = UIActivityViewController(activityItems: [url as Any] , applicationActivities: nil)
            DispatchQueue.main.async {
                self.present(activityViewController, animated: true, completion: nil)
            }
        } catch {
            print("Failed to create file ")
            print("\(error)")
        }
    } else {
        return
    }
}

     // more of the same func types, but deleted to reduce post size


func sendEmailButton() {
    
    guard appOwnerEmail != nil else {
        return
    }
    self.createNoteCSV()
    self.createCompanyCSV()
    self.createBldgCSV()
    self.createWcCSV()
    self.createLossCSV()
    self.createCurrentCSV()

    let mailComposeViewController = configuredMailComposeViewController(appOwnerEmail)
    if MFMailComposeViewController.canSendMail() {
        self.present(mailComposeViewController, animated: true, completion: nil)
    } else {
        self.showSendMailErrorAlert()
    }
}

 // During this function, it will post all data twice.  This includes 
 // 2 x each xls and 2 x each image.
 // The "do" portion of this func gets executed twice.  
 // That is the issue

func configuredMailComposeViewController(_ email: String) -> MFMailComposeViewController {
    mailComposer.setSubject("\(task.Company_Name) meeting note")
    mailComposer.setMessageBody("Meetings note details)", isHTML: true)
    mailComposer.setToRecipients([appOwnerEmail])
    mailComposer.setCcRecipients([""])
    mailComposer.setBccRecipients([""])

    let filemgr = FileManager.default
    let dirPaths = filemgr.urls(for: .documentDirectory,
                                in: .userDomainMask)
                
    do {
        
        let fileNoteURL = setFileLocation(fileNameNote)
        let attachmentNoteData = try Data(contentsOf: fileNoteURL)
        mailComposer.addAttachmentData(attachmentNoteData, mimeType: "application/xls", fileName: fileNameNote)

        let fileCompanyURL = setFileLocation(fileNameCompany)
        let attachmentCompanyData = try Data(contentsOf: fileCompanyURL)
        mailComposer.addAttachmentData(attachmentCompanyData, mimeType: "application/xls", fileName: fileNameCompany)

        if !BuildingsArrayExport.array.isEmpty {
            let fileBldgURL = setFileLocation(fileNameBldg)
            let attachmentBldgData = try Data(contentsOf: fileBldgURL)
            mailComposer.addAttachmentData(attachmentBldgData, mimeType: "application/xls", fileName: fileNameBldg)
        }

        if !WorkersCompArrayExport.array.isEmpty {
            let fileWCURL = setFileLocation(fileNameWC)
            let attachmentWCData = try Data(contentsOf: fileWCURL)
            mailComposer.addAttachmentData(attachmentWCData, mimeType: "application/xls", fileName: fileNameWC)
        }

        if !CurrentPolicyArrayExport.array.isEmpty {
            let fileCPURL = setFileLocation(fileNameCurrent)
            let attachmentCPData = try Data(contentsOf: fileCPURL)
            mailComposer.addAttachmentData(attachmentCPData, mimeType: "application/xls", fileName: fileNameCurrent)
        }

        if !LossItemsArrayExport.array.isEmpty {
            let fileLossURL = setFileLocation(fileNameLoss)
            let attachmentLossData = try Data(contentsOf: fileLossURL)
            mailComposer.addAttachmentData(attachmentLossData, mimeType: "application/xls", fileName: fileNameLoss)
        }

        imageNames = AppDelegate.getUserDatabase().getPhotoList(noteID)
        for imageName in imageNames {
            let name = imageName.name
            let imageURL = dirPaths[0].appendingPathComponent(name)
            let attachmentImages = try Data(contentsOf: imageURL)
                mailComposer.addAttachmentData(attachmentImages, mimeType: "application/jpg", fileName: name)
                mailComposer.mailComposeDelegate = self
                self.present(mailComposer, animated: true
                    , completion: nil)
            
        }

       if MFMailComposeViewController.canSendMail() {
            self.present(mailComposer, animated: true
                   , completion: nil)
        } else {
            print("Emails not configured")
        }
    } catch let error {
        print("We csv encountered error \(error.localizedDescription)")
    }
    
    return mailComposer
}

func showSendMailErrorAlert() {
    let sendMailErrorAlert = UIAlertController(title: "Could Not Send Email", message: "Your device could not send e-mail.  Please check e-mail configuration and try again.", preferredStyle: .alert)
    sendMailErrorAlert.addAction(UIAlertAction(title: "OK", style: .default) { _ in })
    self.present(sendMailErrorAlert, animated: true){}
    self.dismiss(animated: false, completion: nil)
}

public func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {
     
    switch result {
    case .cancelled:
        print("Mail cancelled")
    case .saved:
        AppDelegate.getUserDatabase().recordEmailSent(noteID)
        print("Mail saved")
    case .sent:
        AppDelegate.getUserDatabase().recordEmailSent(noteID)
        print("Mail sent")
    case .failed:
        break
    @unknown default:
        fatalError()
    }

    controller.dismiss(animated: true) {
         self.dismiss(animated: true, completion: nil)
     }
}
}

1 个答案:

答案 0 :(得分:0)

我发现了错误,它是由另一个viewController引起的。 我会保留冗长的代码来支持可能需要帮助通过电子邮件导出多个文件的其他人。