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

时间:2011-11-22 20:29:22

标签: iphone ios email crash

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

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

谢谢,

9 个答案:

答案 0 :(得分:63)

感谢所有输入人员......我将你的解决方案集中到一个可以解决我的问题的解决方案。这就是我所做的......当然我没有编译代码,这是一个半生不熟的代码..但是当我在我的代码中实现它时,我会很快解雇它。

NSLog进入文件How to NSLog into a file LOG2FILE

#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

抓住崩溃并将其记录到文件中

首先,创建一个处理错误并将其输出到控制台的函数(以及您想用它做的任何其他事情):

void uncaughtExceptionHandler(NSException *exception) {    
    NSLog(@"CRASH: %@", exception);      
    NSLog(@"Stack Trace: %@", [exception callStackSymbols]);    
    // Internal error reporting
}

接下来,将异常处理程序添加到您的app delegate:

-(BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:  
(NSDictionary*)launchOptions
{   
    NSSetUncaughtExceptionHandler(&uncaughtExceptionHandler);    // Normal launch stuff
}

在info.plist中设置一个名为Crashed的变量,然后以这种方式读/写

- (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];
}

答案 1 :(得分:48)

  1. 要记录您自己的数据,请使用Cocoalumberjack。它比NSLog快得多,可以动态打开/关闭。它还提供将数据保存到文件中的选项。 NSLog将减慢您的应用程序并填充控制台日志。另外,您通常不希望记录太多。发生崩溃时,您无法安全地进行日志记录。所以,一旦你弄清楚问题区域在哪里,在那里添加更多的日志记录并尝试重现它,例如通过使用KIF等自动化测试框架。

  2. 对于捕获崩溃报告,除了基于开源框架PLCrashReporter的解决方案之外,您应该只有当{app}已经在应用商店中时safely能够发现崩溃的解决方案!不推荐像其他人建议的异常捕获,请查看this article以查看原因!

    iTunes Connect也可以让你查看一些崩溃报告,但是看一些崩溃报告需要2周时间,但到目前为止并不是全部。由Camera+ developers指出。所以你最好使用自己的解决方案。

    PLCrashReporter将向您发送标准的Apple格式崩溃报告,准备进行符号化,以便您知道代码中发生崩溃的位置,包括行号。

    基于PLCrashReporter的一些解决方案是:

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

答案 2 :(得分:5)

用于记录& Swift 下的分析,您可以使用 SwiftyBeaver ,它是一个功能齐全的日志记录平台,包括开源Swift 2& Objective-C框架,加密云存储和Mac App。

网站:https://swiftybeaver.com

框架(支持):https://github.com/SwiftyBeaver/SwiftyBeaver

免责声明:我是创始人。

答案 3 :(得分:4)

这是一个可以在发生崩溃时捕获崩溃的解决方案,它将提供比崩溃日志更多的人类可读代码信息。它将缺少一些崩溃日志,但正如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
}

UPDATE 我做了一些回溯,这个解决方案由Zane Claes提出问题Xcode 4.2 debug doesn't symbolicate stack call

他在第二次评论中提供了一般性解决方案。 “我发现将崩溃日志写入文件并提示用户在下次启动时提交它(仅在发布模式下,以免妨碍调试)是有用的。这让我得到了很好的错误报告。 ..并且用户知道他们的问题正在得到解决“我明白并不是每个人都想问这个用户,但有超级用户会很高兴帮忙。

你当然可以包括一个永远不会再显示这个提示按钮,这样人们就不会因为报告机制而感到沮丧。

可替换地, 您可以使用该信息与服务器联系(不确定它是否会在崩溃时工作,但保存它并偶尔尝试使用详细信息POST到服务器)

答案 4 :(得分:3)

我一直在使用Crittercism为我自动执行此操作。也适用于测试和生产。

答案 5 :(得分:1)

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

我认为它比电子邮件更好,因为当您的应用程序变得流行时,您需要手动管理所有这些电子邮件,而BugSense会自动执行此操作。但是,BugSense也是开源的,因此您可以根据需要修改其内部,并添加任何其他功能。

除此之外,你让我们免费为你工作:如果你对我们想要的一个很酷的新功能有所了解,我们会做 - 我们认为它也很酷。< / p>

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

答案 6 :(得分:0)

如果您将TestFlight与其SDK一起使用,则会自动执行此操作。这是一个非常好的系统。但是,仅适用于测试版本。

https://testflightapp.com/sdk/

答案 7 :(得分:0)

请参阅Ryan在How to view NSLog statement from iphone .app file中对Apple提供的免费实用程序的回答。

但这仍然不是一个方便的解决方案。如果您能负担得起新版本,则应在应用程序中更改日志记录。 Jano在How to NSLog into a file中有一些非常好的想法。特别是选项2应该不需要太多努力。

一般情况下,无论使用何种编程语言,我都建议在项目开始时将本机日志工具隐藏在外观或类似设计之后。

答案 8 :(得分:0)

我已使用以下代码捕获调试日志- Swift 4.1

σ1 = σ2 = 3