我有真正的误解与MFMailComposeViewController在Swift(iOS8)在模拟器

前端之家收集整理的这篇文章主要介绍了我有真正的误解与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模拟器根本没有电子邮件客户端(也不能使用应用程序中的作曲家发送电子邮件)。您必须在设备上测试。

猜你在找的Swift相关文章