Iphone iOS崩溃日志捕获,调试信息。。捕获并通过电子邮件发送给开发团队

Iphone iOS崩溃日志捕获,调试信息。。捕获并通过电子邮件发送给开发团队,iphone,ios,email,crash,Iphone,Ios,Email,Crash,最近,我们遇到了一种情况,我们希望看到用户设备上的应用程序的调试信息。因此,我要寻找的是一种在设备上查找日志的方法,将其作为内联文本粘贴到邮件上,并允许用户发送 有什么想法吗?问题又来了。。 1) 在设备上查找调试日志 2) 打开文件并将文件内容作为内联文本附加到邮件中。 3) 允许用户在下次应用启动时通过电子邮件发送 谢谢,如果您将TestFlight与他们的SDK一起使用,这是自动化的。这是一个非常好的系统。但是,仅适用于测试构建 这是一个在崩溃发生时捕获崩溃的解决方案,它将提供比崩溃日志更

最近,我们遇到了一种情况,我们希望看到用户设备上的应用程序的调试信息。因此,我要寻找的是一种在设备上查找日志的方法,将其作为内联文本粘贴到邮件上,并允许用户发送

有什么想法吗?问题又来了。。 1) 在设备上查找调试日志 2) 打开文件并将文件内容作为内联文本附加到邮件中。 3) 允许用户在下次应用启动时通过电子邮件发送


谢谢,

如果您将TestFlight与他们的SDK一起使用,这是自动化的。这是一个非常好的系统。但是,仅适用于测试构建


这是一个在崩溃发生时捕获崩溃的解决方案,它将提供比崩溃日志更多的可读代码信息。它将缺少一些崩溃日志,但正如Till所说,您应该能够访问这些日志

从另一个关于Xcode 4.2总是在崩溃时返回main的问题。这里的答案是使用这种方法,您可以扩展它来跟踪崩溃

在AppDelegate中实现自己的异常处理程序

// on load
NSSetUncaughtExceptionHandler(&uncaughtExceptionHandler);

void uncaughtExceptionHandler(NSException *exception) {
    NSLog(@"CRASH: %@", exception);
    NSLog(@"Stack Trace: %@", [exception callStackSymbols]);
    // Internal error reporting
}
更新 我做了一些回溯,Zane Claes提出了这个问题的解决方案

他在第二次评论中提出了一个一般性的解决方案。“我发现将崩溃日志写入文件并提示用户在下一次启动时提交(仅在发布模式下提交,以避免妨碍调试)非常有用。这让我获得了大量的错误报告…用户知道他们的问题正在得到解决”我明白不是每个人都想问用户这个问题,但也有一些超级用户乐于提供帮助

当然,您可以包括一个永不再次显示此提示按钮,这样人们就不会对报告机制感到沮丧

或者, 你可以用这些信息联系到服务器(不确定它是否能正常工作,因为它正在崩溃,但请保存它,偶尔尝试将详细信息发布到服务器上)

查看Ryan在中的回答,获取苹果提供的免费实用程序

但这仍然不是一个方便的解决方案。如果你买得起新版本,你应该在应用程序中更改日志记录。Jano在这方面有一些非常好的想法。特别是选项2应该不需要太多的努力


一般来说,我建议在项目开始时将本机日志记录设施隐藏在门面或类似设计后面,而不管使用什么编程语言

谢谢大家的支持。。我把你的解决办法拼凑成一个能解决我问题的办法。。这是我做的。。当然我没有编译代码,这是一个半生不熟的代码。。但一旦我在代码中实现了它,我会很快将它熨平

将日志记录到文件log2文件中

#if TARGET_IPHONE_SIMULATOR == 0    
    NSArray *paths =  
    NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);        
    NSString *documentsDirectory = [paths objectAtIndex:0];    
    NSString *logPath = [documentsDirectory stringByAppendingPathComponent:@"console.log"];    
    freopen([logPath cStringUsingEncoding:NSASCIIStringEncoding],"a+",stderr);
#endif
捕获崩溃并将其记录到文件中

首先,创建一个处理错误的函数,并将其输出到控制台(以及您想对其执行的任何其他操作):

接下来,将异常处理程序添加到应用程序委托:

-(BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:  
(NSDictionary*)launchOptions
{   
    NSSetUncaughtExceptionHandler(&uncaughtExceptionHandler);    // Normal launch stuff
}
在info.plist中设置一个名为crash的变量,然后以这种方式读/写它

- (void)readPlist
 {
      NSString *localizedPath = [[NSBundle mainBundle] pathForResource:fileName ofType:@"plist"];        
      NSMutableDictionary* plistDict = [[NSMutableDictionary alloc] initWithContentsOfFile:localizedPath];

    NSString *crashed;
    crashed = [plistDict objectForKey:@"Crashed"];
}


- (void)writeToPlist
{
    NSMutableDictionary* plistDict = [[NSMutableDictionary alloc] initWithContentsOfFile:filePath];

    [plistDict setValue:@"YES" forKey:@"Crashed"];
    [plistDict writeToFile:filePath atomically: YES];
}
应用程序启动后,阅读info.plist并提示用户提交崩溃日志。

{
    MFMailComposeViewController *mailComposer = [[MFMailComposeViewController alloc] init];
    mailComposer.mailComposeDelegate = self;[mailComposer setSubject:@"Crash Log"];
    // Set up recipients
    NSArray *toRecipients = [NSArray arrayWithObject:@"first@example.com"]; 
    [mailComposer setToRecipients:toRecipients];
    // Attach the Crash Log..
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *logPath = [documentsDirectory stringByAppendingPathComponent:@"console.log"];
    NSData *myData = [NSData dataWithContentsOfFile:logPath];
    [mailComposer addAttachmentData:myData mimeType:@"Text/XML" fileName:@"Console.log"];
    // Fill out the email body text
    NSString *emailBody = @"Crash Log";
    [mailComposer setMessageBody:emailBody isHTML:NO];
    [self presentModalViewController:mailComposer animated:YES];
}
我一直在用它来为我实现自动化。也适用于测试和生产

  • 要记录您自己的数据,请使用。它比NSLog快得多,并且可以动态打开/关闭。它还提供了将数据保存到文件中的选项。NSLog将减慢应用程序的速度并填充控制台日志。另外,一般来说,您也不想记录太多日志。当崩溃发生时,您无法安全地进行日志记录。因此,一旦你发现了问题所在,就在那里添加更多的日志记录,并尝试复制它,例如使用自动化测试框架,如

  • 要捕获崩溃报告,您应该使用基于开源框架的解决方案,该解决方案可以捕获崩溃,当您的应用已经在应用商店中时也是如此!不建议按照其他人的建议捕获异常,请查看原因

    iTunes Connect也为您提供了查看一些崩溃报告的功能,但要查看一些报告需要2周的时间,但到目前为止,并不是所有的报告都如。所以你最好使用你自己的解决方案

    PLCrashReporter将向您发送标准的苹果格式的崩溃报告,准备进行符号化,这样您就可以知道代码中崩溃发生的位置,包括行号

    基于PLCrashReporter的一些解决方案包括:

    • :开源客户端+php服务器,基本崩溃分组,符号化可以从您的mac上自动完成(我是这个的开发者)
    • :付费服务,使用QuincyKit客户端,高级崩溃分组,符号化完全在服务器上完成(我是这方面的开发人员之一)
    • :免费服务,无象征意义
    • :如果与25台或更少的设备一起使用,则免费服务,无符号
    • :私有测试版,未知功能,他们的解决方案似乎基于PLCrashReporter
  • 建议的解决方案要么允许在下次启动时自动发送数据,要么询问用户是否同意发送数据


  • BugSense为iOS提供崩溃报告服务。除了提供完全符号化的堆栈跟踪,BugSense还为所有应用程序的崩溃提供分析

    我认为它比电子邮件好,因为当你的应用程序变得流行时,你需要手动管理所有这些电子邮件,而BugSense会自动管理。然而,BugSense也是开源的,所以您可以以任何方式修改它的内部结构,并添加任何附加功能

    除此之外,你还可以让我们免费为你工作:如果你有一个很酷的新功能的想法,你想让我们拥有,我们会做的——只要我们认为它也很酷

    免责声明:我为BugSense iOS.framework编写代码。

    用于日志记录和分析
    {
        MFMailComposeViewController *mailComposer = [[MFMailComposeViewController alloc] init];
        mailComposer.mailComposeDelegate = self;[mailComposer setSubject:@"Crash Log"];
        // Set up recipients
        NSArray *toRecipients = [NSArray arrayWithObject:@"first@example.com"]; 
        [mailComposer setToRecipients:toRecipients];
        // Attach the Crash Log..
        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString *documentsDirectory = [paths objectAtIndex:0];
        NSString *logPath = [documentsDirectory stringByAppendingPathComponent:@"console.log"];
        NSData *myData = [NSData dataWithContentsOfFile:logPath];
        [mailComposer addAttachmentData:myData mimeType:@"Text/XML" fileName:@"Console.log"];
        // Fill out the email body text
        NSString *emailBody = @"Crash Log";
        [mailComposer setMessageBody:emailBody isHTML:NO];
        [self presentModalViewController:mailComposer animated:YES];
    }
    
    var paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
    let documentsDirectory = paths[0]
    let fileName = "Logfile.txt"
    let logFilePath = (documentsDirectory as NSString).appendingPathComponent(fileName)
    freopen(logFilePath.cString(using: String.Encoding.ascii)!, "a+", stderr)