email in iOS

Jason, looking back at your project file, I see that you do have addAttachement.

I knew that you were trying to use MFMailComposeViewController. Others were trying to add an attachment to mailto url scheme.

Sorry not to notice that you already had attachment in your project. I do appreciate the contributions that all are making in extending the capabilities of Xojo iOS.

Hi, When I played with Jason’s bit of code, i just get the message ‘Email not available’ even though i have email set up on my device - I am currently testing on an iPod as I dont have an iPhone, only androids :wink: - but if there is a way of using the htmlviewer to also do the attachment then I could program around it.

thanks again all

Yes it appears that there may be a bug in iOS 8 where canSendMail returns false even when mail is setup so I don’t think the built in class from apple will work…

fingers crossed for a Xojo update soon to add this in and also the picker control :wink:

Unfortunately Xojo adding this won’t help much I’m afraid. I think it may be an apple problem.

There may be a workaround using a web service and httpsocket. But that requires creating the web service that will receive all elements of the message (to, from, subject, body, attachments), and send that from the web app. It is not that difficult to do with Web Edition, but that does require having a web host.

Exactly, the beauty of the apple method is that it caches the email to the user’s outbox so that it can be created without an internet connection and actually delivered when one is/becomes present. I also wonder if an app could be rejected because it does not use the MessageUI API and instead employs an httpsocket. I wouldn’t doubt it if a reviewer decided to reject an app for that. Unfortunately the apple method does not work for now so I’m not sure what to say.

I just tried the mailto: approach and it neither works in HTMLViewer nor with ShowURL. So that leaves very few possibilities. If the documented method does not work, the minimum is to look for alternatives.

I have seen on the Internet smtp OC classes for iOS as well, so chances are some apps in iTunes Store already use that. Actually, there are several apps doing it (searched for ‘smtp’). So seems to me reviewers had to approve them at some point. Now the challenge will be to implement smtp through declares or something else.

Technically, using httpsocket to use a web service is no different than using a mail form on a site in Safari. I do not see why reviewers should frown. But they have proven in the MAS they have ample stocks of stupidity left. …

Exactly. That is what I am worried about.

Proof is in the pudding… But at one point, the dozen or so apps using what appears to be web APIs to manage email should not have been accepted. Starting with Yahoo and Google mail…

One cannot live in fear :wink:

I am completing an app in which I use an HTMLViewer to display a short help/manual about it. I just added the possibility to send email through a web app hosted on my site. After spending a while designing an iOS app, I was sensitized to the particulars of the iOS 8 design, so I made the screen as close as I could to the native interface, made sure I managed rotation elegantly, created webpages for iPhone and iPad so they be real nice.

Apart from a small lag when the app starts, the look and feel of the mail form app is real close to a native page.

That would not resolve the possibility to send an attachment, but for simply allowing users to communicate, I am convinced it will be great.

Has anyone been able to get this working?

Besides the “canSendMail” problem mentioned above, I am also getting a crash when I try to add an attachment… Here is part of the log:

Any help on resolving this is appreciated…

Last Exception Backtrace:
0 CoreFoundation 0x226f75f2 __exceptionPreprocess + 122
1 libobjc.A.dylib 0x2fe31c72 objc_exception_throw + 34
2 CoreFoundation 0x226fcab8 -[NSObject(NSObject) doesNotRecognizeSelector:] + 184
3 CoreFoundation 0x226fa994 forwarding + 708
4 CoreFoundation 0x2262bb84 _CF_forwarding_prep_0 + 20
5 Regatta Manager Assistant 0x0033d712 Extensions.NSDataFromFolderitem%p%o<xojo.IO.FolderItem> (Extensions:52)
6 Regatta Manager Assistant 0x0033fd5a Extensions.MFMailComposeViewController.addAttachment%%o<Extensions.MFMailComposeViewController>o<xojo.IO.FolderItem>yy (Extensions:219)
7 Regatta Manager Assistant 0x002c6628 raceNumberView.raceNumberView.exportBut_Action%%o<raceNumberView.raceNumberView>o (raceNumberView:113)
8 Regatta Manager Assistant 0x003ee318 -[XOJButtonExtraInfo touchUpInside:] (RBUIButton.mm:52)
9 UIKit 0x25bcc9b2 -[UIApplication sendAction:to:from:forEvent:] + 66
10 UIKit 0x25bcc954 -[UIControl sendAction:to:forEvent:] + 40
11 UIKit 0x25bb7538 -[UIControl _sendActionsForEvents:withEvent:] + 580
12 UIKit 0x25bcc384 -[UIControl touchesEnded:withEvent:] + 580
13 UIKit 0x25b910b2 _UIGestureRecognizerUpdate + 10154
14 CoreFoundation 0x226be010 CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION + 16
15 CoreFoundation 0x226bb6f4 __CFRunLoopDoObservers + 272
16 CoreFoundation 0x226bbaf6 __CFRunLoopRun + 910
17 CoreFoundation 0x22608b2c CFRunLoopRunSpecific + 472
18 CoreFoundation 0x2260893e CFRunLoopRunInMode + 102
19 GraphicsServices 0x299bf04c GSEventRunModal + 132
20 UIKit 0x25bfaf1c UIApplicationMain + 1436
21 Regatta Manager Assistant 0x003eb6ba runIOSMainLoop() (iOSAppDelegate.mm:163)
22 Regatta Manager Assistant 0x00102652 xojo._RuntimeRun (#rbframework:458)
23 Regatta Manager Assistant 0x000fc5a0 _Main (main:37)
24 Regatta Manager Assistant 0x000fc0a0 main (main:693)
25 libdyld.dylib 0x303cdaaa tlv_initializer + 2

Until we can figure out why canSendMail always returns false, you won’t be able to send emails anyway. But the fix for that crash is to remove the “alloc” from this line in NSDataFromFolderitem:

dim NSDataRef as ptr = dataWithContentsOfFile(alloc(NSClassFromString("NSData")), f.Path)
So it should be:

dim NSDataRef as ptr = dataWithContentsOfFile(NSClassFromString("NSData"), f.Path)

Jason…

Thanks… that did take care of the attachment problem… and yes, canSendMail continue to return False for me… which is a show-stopper for me…

Jason…

I do not know if this helps or not… but this is the crash I get if I do not check canSendMail and instead I just called .PresentInView(self).

Last Exception Backtrace:
0 CoreFoundation 0x226f75f2 __exceptionPreprocess + 122
1 libobjc.A.dylib 0x2fe31c72 objc_exception_throw + 34
2 UIKit 0x25e7dc1e -[UIViewController _presentViewController:withAnimationController:completion:] + 2914
3 UIKit 0x25e7f6f6 __62-[UIViewController presentViewController:animated:completion:]_block_invoke + 254
4 UIKit 0x25c7bc50 -[UIViewController presentViewController:animated:completion:] + 192
5 Regatta Manager Assistant 0x002578d8 Extensions.MFMailComposeViewController.PresentInView%%o<Extensions.MFMailComposeViewController>o (Extensions:182)
6 Regatta Manager Assistant 0x001de568 raceNumberView.raceNumberView.exportBut_Action%%o<raceNumberView.raceNumberView>o (raceNumberView:116)

Right, since you can’t send mail an exception is thrown and your app is killed by the OS. The note from the docs on canSendMail:

Discussion You should call this method before attempting to display the mail composition interface. If it returns NO, you must not display the mail composition interface.

I am able to email from other apps (Keynote for example) OK… so I would assume that my email settings are ok and that the problem is with the declare…

Jason…

I am fairly clueless when it comes to declares… especially for iOS… so feel free to tell me to stop wasting your time.

If I add the line:

dim p As Ptr = NSClassFromString(“MFMailComposeViewController”)

to your canSendMail method and check the value of p after it executes, it is zero. Is this expected?

Thanks

I have updated the project, and it now works! (Thanks Joe for the dlopen hint) Remember that you must deploy to a device for it to work, interesting things happen if it is used in the simulator.
https://www.dropbox.com/s/5cksy1cj3cg7zc1/mail%20view%20.xojo_binary_project?dl=0