我有真正的误解与MFMailComposeViewController在Swift(iOS8)在模
我创建一个csv文件,并尝试通过电子邮件发送。显示用于发送邮件的窗口,但未填写电子邮件正文,并且没有附加文件。应用程序在此屏幕上挂起:
按钮“取消”不工作。在控制台中几秒钟后出现: viewServiceDidTerminateWithError: Error Domain=_UIViewServiceInterfaceErrorDomain Code=3 "The operation couldn’t be completed. (_UIViewServiceInterfaceErrorDomain error 3.)" UserInfo=0x7f8409f29b50 {Message=Service Connection Interrupted} <MFMailComposeRemoteViewController: 0x7f8409c89470> timed out waiting for fence barrier from com.apple.MailCompositionService 有我的代码: func actionSheet(actionSheet: UIActionSheet!,clickedButtonAtIndex buttonIndex: Int) { if buttonIndex == 0 { println("Export!") var csvString = NSMutableString() csvString.appendString("Date;Time;Systolic;Diastolic;Pulse") for tempValue in results { //result define outside this function var tempDateTime = NSDate() tempDateTime = tempValue.datePress var dateFormatter = NSDateFormatter() dateFormatter.dateFormat = "dd-MM-yyyy" var tempDate = dateFormatter.stringFromDate(tempDateTime) dateFormatter.dateFormat = "HH:mm:ss" var tempTime = dateFormatter.stringFromDate(tempDateTime) csvString.appendString("n(tempDate);(tempTime);(tempValue.sisPress);(tempValue.diaPress);(tempValue.hbPress)") } let fileManager = (NSFileManager.defaultManager()) let directorys : [String]? = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory,NSSearchPathDomainMask.AllDomainsMask,true) as? [String] if ((directorys) != nil) { let directories:[String] = directorys!; let dictionary = directories[0]; let plistfile = "bpmonitor.csv" let plistpath = dictionary.stringByAppendingPathComponent(plistfile); println("(plistpath)") csvString.writeToFile(plistpath,atomically: true,encoding: NSUTF8StringEncoding,error: nil) var testData: NSData = NSData(contentsOfFile: plistpath) var myMail: MFMailComposeViewController = MFMailComposeViewController() if(MFMailComposeViewController.canSendMail()){ myMail = MFMailComposeViewController() myMail.mailComposeDelegate = self // set the subject myMail.setSubject("My report") //Add some text to the message body var sentfrom = "Mail sent from BPMonitor" myMail.setMessageBody(sentfrom,isHTML: true) myMail.addAttachmentData(testData,mimeType: "text/csv",fileName: "bpmonitor.csv") //Display the view controller self.presentViewController(myMail,animated: true,completion: nil) } else { var alert = UIAlertController(title: "Alert",message: "Your device cannot send emails",preferredStyle: UIAlertControllerStyle.Alert) alert.addAction(UIAlertAction(title: "OK",style: UIAlertActionStyle.Default,handler: nil)) self.presentViewController(alert,completion: nil) } } else { println("File system error!") } } } 尝试改为使用UIActivityViewController发送邮件: let fileURL: NSURL = NSURL(fileURLWithPath: plistpath) let actViewController = UIActivityViewController(activityItems: [fileURL],applicationActivities: nil) self.presentViewController(actViewController,completion: nil) 看到大致相同的屏幕发送电子邮件,一会儿后返回到上一个屏幕。在控制台中,现在又出现了另一个错误: viewServiceDidTerminateWithError: Error Domain=_UIViewServiceInterfaceErrorDomain Code=3 "The operation couldn’t be completed. (_UIViewServiceInterfaceErrorDomain error 3.)" UserInfo=0x7faab3296ad0 {Message=Service Connection Interrupted} Errors encountered while discovering extensions: Error Domain=PlugInKit Code=13 "query cancelled" UserInfo=0x7faab3005890 {NSLocalizedDescription=query cancelled} <MFMailComposeRemoteViewController: 0x7faab3147dc0> timed out waiting for fence barrier from com.apple.MailCompositionService 有关于PlugInKit的东西。 使用UIDocumentInteractionController改为UIActivityViewController: let docController = UIDocumentInteractionController(URL: fileURL) docController.delegate = self docController.presentPreviewAnimated(true) ... func documentInteractionControllerViewControllerForPreview(controller: UIDocumentInteractionController!) -> UIViewController! { return self } 我看到这个屏幕与内容的CSV文件:http://prntscr.com/4ilgax我按右上角的按钮导出,看到这个屏幕http://prntscr.com/4ilguk在那里我选择MAIL和几秒钟我看到http://prntscr.com/4ilh2h然后返回显示文件的内容!在控制台中使用与使用UIActivityViewController时相同的消息。
* *重要 – 请勿使用模拟器。 * *
即使在2016年,模拟器非常简单地不支持从应用程序发送邮件。 事实上,模拟器根本没有邮件客户端。 但!看到底部的消息! 亨利给了完全答案。你必须 – 在较早阶段分配和启动MFMailComposeViewController,和 – 把它保存在一个静态变量中,然后, – 每当需要时,获取静态MFMailComposeViewController实例并使用它。 你几乎肯定必须在每次使用后循环全??局MFMailComposeViewController。重复使用同一个是不可靠的。 有一个全局例程,释放然后重新初始化单例MFMailComposeViewController。每次完成邮件编写器后,调用该全局例程。 在任何singleton。不要忘记,你的应用程序委托是,当然是一个单例,所以做那里… @property (nonatomic,strong) MFMailComposeViewController *globalMailComposer; -(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { ........ // part 3,our own setup [self cycleTheGlobalMailComposer]; // needed due to the worst programming in the history of Apple ......... } 和… -(void)cycleTheGlobalMailComposer { // cycling GlobalMailComposer due to idiotic iOS issue self.globalMailComposer = nil; self.globalMailComposer = [[MFMailComposeViewController alloc] init]; } 然后使用邮件,这样的东西… -(void)helpEmail { // APP.globalMailComposer IS READY TO USE from app launch. // recycle it AFTER OUR USE. if ( [MFMailComposeViewController canSendMail] ) { [APP.globalMailComposer setToRecipients: [NSArray arrayWithObjects: emailAddressNSString,nil] ]; [APP.globalMailComposer setSubject:subject]; [APP.globalMailComposer setMessageBody:msg isHTML:NO]; APP.globalMailComposer.mailComposeDelegate = self; [self presentViewController:APP.globalMailComposer animated:YES completion:nil]; } else { [UIAlertView ok:@"Unable to mail. No email on this device?"]; [APP cycleTheGlobalMailComposer]; } } -(void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error { [controller dismissViewControllerAnimated:YES completion:^ { [APP cycleTheGlobalMailComposer]; } ]; } {nb,fixed typo per Michael Salamone below。} 为了方便起见,在您的前缀文件中有以下宏 #define APP ((AppDelegate *)[[UIApplication sharedApplication] delegate]) 还有一个“小”的问题,可能会花费你的天:http://stackoverflow.com/a/17120065/294884 只是为2016年FTR这里的基本swift代码发送电子邮件IN APP, class YourClass:UIViewController,MFMailComposeViewControllerDelegate { func clickedMetrieArrow() { print("click arrow! v1") let e = MFMailComposeViewController() e.mailComposeDelegate = self e.setToRecipients( ["help@smhk.com"] ) e.setSubject("Blah subject") e.setMessageBody("Blah text",isHTML: false) presentViewController(e,completion: nil) } func mailComposeController(controller: MFMailComposeViewController,didFinishWithResult result: MFMailComposeResult,error: NSError?) { dismissViewControllerAnimated(true,completion: nil) } 然而!注意! 这些天,它是糟糕的发送电子邮件“在应用程序”。 今天好多了,只是切断电子邮件客户端。 添加到plist … <key>LSApplicationQueriesSchemes</key> <array> <string>instagram</string> </array> 然后代码就好了 func pointlessMarketingEmailForClient() { let subject = "Some subject" let body = "Plenty of <i>email</i> body." let coded = "mailto:blah@blah.com?subject=(subject)&body=(body)".stringByAddingPercentEncodingWithAllowedCharacters(.URLQueryAllowedCharacterSet()) if let emailURL:NSURL = NSURL(string: coded!) { if UIApplication.sharedApplication().canOpenURL(emailURL) { UIApplication.sharedApplication().openURL(emailURL) } else { print("fail A") } } else { print("fail B") } } 这些天,这比尝试从“内部”的应用程序电子邮件更好。 再次记住,iOS模拟器根本没有电子邮件客户端(也不能使用应用程序中的作曲家发送电子邮件)。您必须在设备上测试。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |