按钮“取消”不工作。在控制台中几秒钟后出现:
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") } }
这些天,这比尝试从“内部”的应用程序电子邮件更好。