Exception handling
One way to report about exceptions on iOS
Section titled “One way to report about exceptions on iOS”Go to Main.cs file in iOS project and change existed code, like presented below:
static void Main(string[] args) { try { UIApplication.Main(args, null, "AppDelegate"); } catch (Exception ex) { Debug.WriteLine("iOS Main Exception: {0}", ex);
var watson = new LittleWatson(); watson.SaveReport(ex); } }ILittleWatson interface, used in portable code, could look like this:
public interface ILittleWatson{ Task<bool> SendReport();
void SaveReport(Exception ex);}Implementation for iOS project:
[assembly: Xamarin.Forms.Dependency(typeof(LittleWatson))]namespace SomeNamespace{ public class LittleWatson : ILittleWatson { private const string FileName = "Report.txt";
private readonly static string DocumentsFolder; private readonly static string FilePath;
private TaskCompletionSource<bool> _sendingTask;
static LittleWatson() { DocumentsFolder = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); FilePath = Path.Combine(DocumentsFolder, FileName); }
public async Task<bool> SendReport() { _sendingTask = new TaskCompletionSource<bool>();
try { var text = File.ReadAllText(FilePath); File.Delete(FilePath); if (MFMailComposeViewController.CanSendMail) { var email = ""; // Put receiver email here. var mailController = new MFMailComposeViewController(); mailController.SetToRecipients(new string[] { email }); mailController.SetSubject("iPhone error"); mailController.SetMessageBody(text, false); mailController.Finished += (object s, MFComposeResultEventArgs args) => { args.Controller.DismissViewController(true, null); _sendingTask.TrySetResult(true); };
ShowViewController(mailController); } } catch (FileNotFoundException) { // No errors found. _sendingTask.TrySetResult(false); }
return await _sendingTask.Task; }
public void SaveReport(Exception ex) { var exceptionInfo = $"{ex.Message} - {ex.StackTrace}"; File.WriteAllText(FilePath, exceptionInfo); }
private static void ShowViewController(UIViewController controller) { var topController = UIApplication.SharedApplication.KeyWindow.RootViewController; while (topController.PresentedViewController != null) { topController = topController.PresentedViewController; }
topController.PresentViewController(controller, true, null); } }}And then, somewhere, where app starts, put:
var watson = DependencyService.Get<ILittleWatson>(); if (watson != null) { await watson.SendReport(); }