iOS 崩溃日志捕获、调试信息.. 捕获并通过电子邮件发送给开发团队
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8233388/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
iOS crash log catch, debug info.. Catch and send via email to the Dev team
提问by Mobilewits
Recently we came across a situation where we wanted to see the debug info from the app which a user has on his device. So, what I am looking for is a way to find the log on the device, paste it as inline text on a mail and allow the user to send it..
最近我们遇到了一种情况,我们想查看用户设备上的应用程序的调试信息。所以,我正在寻找一种在设备上找到日志的方法,将其作为内嵌文本粘贴到邮件中并允许用户发送它。
Any ideas? Here are the questions again.. 1)Find a debug log on the device 2)open the file and attach the contents of the file as inline text in to the mail. 3)Allow the user to email it the next time app launches..
有任何想法吗?这里又是问题。 1) 在设备上找到调试日志 2) 打开文件并将文件内容作为内嵌文本附加到邮件中。3) 允许用户在下次应用启动时通过电子邮件发送..
Thanks,
谢谢,
回答by Mobilewits
Thanks for all the inputs guys.. I clubbed your solutions into one that would solve my problem.. Here is what I made it to be.. Surely I did not compile the code, it is a half baked code.. but I will iron it soon once as I implement it in my code..
感谢所有的输入家伙..我把你的解决方案整合成一个可以解决我的问题的解决方案..这是我做的..当然我没有编译代码,它是一个半成品代码..但我会当我在我的代码中实现它时,立即熨烫它一次..
NSLog into file How to NSLog into a fileLOG2FILE
NSLog into file如何将 NSLog登录到文件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
Catch the Crash and Log them too into a File
捕获崩溃并将它们也记录到文件中
First, create a function that will handle the error and output it to the console (as well as whatever else you want to do with it):
首先,创建一个函数来处理错误并将其输出到控制台(以及您想用它做的任何其他事情):
void uncaughtExceptionHandler(NSException *exception) {
NSLog(@"CRASH: %@", exception);
NSLog(@"Stack Trace: %@", [exception callStackSymbols]);
// Internal error reporting
}
Next, add the exception handler to your app delegate:
接下来,将异常处理程序添加到您的应用程序委托:
-(BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:
(NSDictionary*)launchOptions
{
NSSetUncaughtExceptionHandler(&uncaughtExceptionHandler); // Normal launch stuff
}
Set a variable in the info.plist called Crashed and then read/write it this way
在 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];
}
Once the app launches read the info.plist and prompt the user to submit the crash logs..
一旦应用程序启动读取 info.plist 并提示用户提交崩溃日志..
{
MFMailComposeViewController *mailComposer = [[MFMailComposeViewController alloc] init];
mailComposer.mailComposeDelegate = self;[mailComposer setSubject:@"Crash Log"];
// Set up recipients
NSArray *toRecipients = [NSArray arrayWithObject:@"[email protected]"];
[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];
}
回答by Kerni
For logging your own data, use CocoalumberHyman. It is much faster than NSLog and can be turned on/off dynamically. It also provides options to save the data into a file. NSLog will slow down your app and fills the console log. Also you don't want to log too much in general. You cannot safely do logging when the crash happens. So rather once you figured out where the problem area is, add some more logging there and try to reproduce it, e.g. by using automated testing frameworks like KIF.
For catching crash report you should nothing else than a solution based on the open source framework PLCrashReporter, which can safelycatch crashes, also when you app is already in the app store! Exception catching as suggested by others is not recommended, check this articleto see why!
iTunes Connect offers you to view some crash reports too, but it takes up to 2 weeks to see some, but by far not all as e.g. pointed out by the Camera+ developers. So you better use your own solution.
PLCrashReporter will send you standard apple formatted crash reports, ready for symbolication, so you know where the crash happens in your code, including line numbers.
Some solutions based on PLCrashReporter are:
- QuincyKit: Open Source client + php server, basic crash grouping, symbolication can be automated from your mac (I am the developer of this)
- HockeyApp: Paid service, uses QuincyKit client, advanced crash grouping, symbolication fully done on the server (I am on of the developers of this)
- Bugsense: Free service, no symbolication
- AppBlade: FREE service if used with 25 devices or less, no symbolication
- Crashlytics: Private beta, unknown features, their solution seems to be based on PLCrashReporter
The proposed solutions either allow sending the data automatically on the next startup or by asking the user if he/she agrees to send.
要记录您自己的数据,请使用CocoalumberHyman。它比 NSLog 快得多,并且可以动态打开/关闭。它还提供了将数据保存到文件中的选项。NSLog 会减慢你的应用程序并填满控制台日志。此外,您一般不想记录太多。崩溃发生时,您无法安全地进行日志记录。因此,一旦您弄清楚问题所在,就在那里添加更多日志记录并尝试重现它,例如通过使用KIF 之类的自动化测试框架。
为了捕获崩溃报告,您应该使用基于开源框架PLCrashReporter的解决方案,它可以安全地捕获崩溃,即使您的应用程序已经在应用程序商店中!不推荐其他人建议的异常捕获,请查看本文以了解原因!
iTunes Connect 也为您提供了查看一些崩溃报告的功能,但查看一些崩溃报告需要长达 2 周的时间,但远非如Camera+ 开发人员所指出的那样。所以你最好使用你自己的解决方案。
PLCrashReporter 将向您发送标准的苹果格式崩溃报告,准备好符号化,因此您知道崩溃发生在代码中的位置,包括行号。
一些基于 PLCrashReporter 的解决方案是:
- QuincyKit:开源客户端 + php 服务器,基本崩溃分组,符号可以从你的 mac 自动化(我是这个的开发者)
- HockeyApp:付费服务,使用 QuincyKit 客户端,高级崩溃分组,完全在服务器上完成符号化(我是这个的开发者之一)
- Bugsense:免费服务,没有象征意义
- AppBlade:如果与 25 台或更少设备一起使用,则免费服务,无符号化
- Crashlytics:私人测试版,未知功能,他们的解决方案似乎基于 PLCrashReporter
提议的解决方案要么允许在下次启动时自动发送数据,要么通过询问用户是否同意发送。
回答by Jesse Black
This is a solution that catches crashes as they happen, it will give more human readable code info than a crash log. It will lack some of the crash log, but as Till says, you should be able to access those anyway.
这是一种在崩溃发生时捕获崩溃的解决方案,它将提供比崩溃日志更多的人类可读代码信息。它会缺少一些崩溃日志,但正如 Till 所说,无论如何你应该能够访问它们。
From another SO question about the Xcode 4.2 always returning to main upon crashing. The answer there uses this method and you can extend it to keep track of crashes.
从另一个关于 Xcode 4.2 的 SO 问题中,崩溃时总是返回 main。那里的答案使用此方法,您可以扩展它以跟踪崩溃。
implement your own exception handler in the AppDelegate
在 AppDelegate 中实现您自己的异常处理程序
// on load
NSSetUncaughtExceptionHandler(&uncaughtExceptionHandler);
void uncaughtExceptionHandler(NSException *exception) {
NSLog(@"CRASH: %@", exception);
NSLog(@"Stack Trace: %@", [exception callStackSymbols]);
// Internal error reporting
}
UPDATE I did some backtracking and this solution was offered by Zane Claes to the question Xcode 4.2 debug doesn't symbolicate stack call
更新我做了一些回溯,这个解决方案是由赞恩克拉斯提供的问题Xcode 4.2 调试不象征堆栈调用
He offers a general solution in his second comment. "I find it to be useful to write the crash log to a file and prompt the user to submit it on the next launch (in release mode only, to not get in the way of debugging). This lets me get great bug reports... and the users know that their problem is being addressed" I understand not everybody would like to ask this of the user, but there are super users out there that would be glad to help out.
他在第二条评论中提供了一个通用的解决方案。“我发现将崩溃日志写入文件并提示用户在下次启动时提交它很有用(仅在发布模式下,以免妨碍调试)。这让我得到很好的错误报告。 .. 并且用户知道他们的问题正在得到解决”我理解不是每个人都想向用户询问这个问题,但是有超级用户会很乐意提供帮助。
You could of course include a never show me this prompt again button so that people are not frustrated by reporting mechanism.
您当然可以包含一个从不再次显示此提示的按钮,这样人们就不会因报告机制而感到沮丧。
Alternatively, You could reach out to a server with the info (not sure if it will work as it is crashing, but save it and occasionally try to POST to a server with the details)
或者,您可以联系具有信息的服务器(不确定它是否会在崩溃时工作,但保存它并偶尔尝试使用详细信息发布到服务器)
回答by Sebastian
For logging & analytics under Swiftyou can use SwiftyBeaver, it is a full-featured logging platform including open-source Swift 2 & Objective-C Framework, encrypted cloud storage and Mac App.
对于Swift下的日志和分析,您可以使用SwiftyBeaver,它是一个功能齐全的日志平台,包括开源 Swift 2 和 Objective-C 框架、加密云存储和 Mac App。
Website: https://swiftybeaver.com
Framework (supporting): https://github.com/SwiftyBeaver/SwiftyBeaver
框架(支持):https: //github.com/SwiftyBeaver/SwiftyBeaver
Disclaimer: I am a founder.
免责声明:我是创始人。
回答by Jeff
I've been using Crittercismto automate this for me. Works for testing and in production too.
我一直在使用Crittercism为我自动化。也适用于测试和生产。
回答by Nick Toumpelis
BugSense provides crash reporting services for iOS. Apart from providing a fully symbolicated stack trace, BugSense provides analytics for your crashes, across all your applications.
BugSense 为 iOS 提供崩溃报告服务。除了提供完全符号化的堆栈跟踪之外,BugSense 还为您的所有应用程序的崩溃提供分析。
I think it's better than email, because when your app becomes popular you will need to manage all these emails manually, while BugSense does this automatically. However, BugSense is also open-source, so you can modify its internals any way you want and add any additional functionality.
我认为它比电子邮件更好,因为当您的应用程序流行时,您将需要手动管理所有这些电子邮件,而 BugSense 会自动执行此操作。但是,BugSense 也是开源的,因此您可以以任何方式修改其内部结构并添加任何其他功能。
In addition to that, you get us to work for you for free: If you have an idea about a cool new feature that you want us to have, we'll do it -provided we think it's cool, too.
除此之外,您还可以让我们免费为您工作:如果您对希望我们拥有的一项很酷的新功能有想法,我们会这样做——前提是我们也认为它很酷。
Disclaimer:I write the code for BugSense-iOS.framework.
免责声明:我为 BugSense-iOS.framework 编写代码。
回答by Kay
See Ryan's answer in How to view NSLog statement from iphone .app filefor a free utility provided by Apple.
有关Apple 提供的免费实用程序,请参阅如何从 iphone .app 文件查看 NSLog 语句中的Ryan 回答。
But this is still no convenient solution. If you can afford a new build, you should change your logging within the app. Jano has some very good ideas on this in How to NSLog into a file. Especially option 2 should do without too much effort.
但这仍然没有方便的解决方案。如果您负担得起新版本,则应更改应用程序中的日志记录。Jano 在How to NSLog into a file 中对此有一些很好的想法。特别是选项 2 应该不需要太多努力。
In general I would recommend hiding native logging facilities behind a facade or similar design just at the beginning of the project regardless what programming language is used.
一般而言,无论使用何种编程语言,我都会建议在项目开始时将本机日志记录工具隐藏在外观或类似设计后面。
回答by TomSwift
If you use the TestFlight with their SDK this is automated. It's a really nice system. For test builds only, however.
如果您将 TestFlight 与他们的 SDK 一起使用,这是自动化的。这是一个非常好的系统。但是,仅适用于测试版本。
回答by Prashant Gaikwad
I have used below code to catch debug logs - Swift 4.1
我使用下面的代码来捕获调试日志 - Swift 4.1
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)