iPhone的错误记录和/或报告的最佳实践

JJ *_*rer 29 iphone error-handling error-logging bug-reporting hockeyapp

当我进行Web开发时,我使用自定义记录器来捕获致命错误并将跟踪追加到文件并向用户显示消息.我偶尔可以看一下文件是否发生了变化,这意味着,有些用户遇到了错误,我可以深入了解他们遇到的问题.

我想在iphone上有类似的东西,但有一些警告:

  • 在开发过程中,重置错误列表或关闭通知应该是微不足道的.
  • 在开发过程中,错误消息也应该出现在一些显而易见的地方,比如在控制台的屏幕上
  • 部署后,应该礼貌地将错误发送给母舰进行分析(针对下次更新中的错误修复)
  • 在尝试在开发期间跟踪问题时打开跟踪/信息日志记录
  • 关闭"Release"的控制台日志记录,以加快用户的速度
  • 应该自己清理,以便在电话上成为一个好公民

一些相关链接

似乎有一个共同的工具包来做到这一点 - 你如何处理这个?

[2011年10月更新]已经有一些不同成熟度的发展......

  • PLCrashReporter.
  • 昆西坐在PLC之上.
  • Bugsense商业崩溃记者.
  • Crittercism崩溃和错误报告(一些免费包,一些付费).
  • 测试航班现在有一个可以捕捉崩溃的SDK(但还没有应用商店应用,只有开发应用).
  • 与Test Flight一样,Hockey旨在将临时分发与崩溃报告相结合.

Dan*_*n J 37

这就是我们的工作:

  • 让iPhone通过现有的App Store机制处理自己的崩溃转储. 更新:发现iTunes Connect在提供崩溃报告时不可靠,我建议使用Fabric/Crashlytics,或者像CrittercismRollbar这样的竞争对手.
  • 我们发布的产品没有任何痕迹,这似乎与大多数其他iPhone应用程序一致.
  • 如果报告了错误,那么我们使用跟踪的构建重现它.

更详细:

  • 我们在许多不同的粒度级别为NSLog跟踪定义宏.
  • 使用Xcode构建设置来更改跟踪级别,该级别控制将多少跟踪编译到产品中,例如,有Release和Debug构建配置.
  • 如果没有定义跟踪级别,那么我们在模拟器中显示完整跟踪,并且在真实设备上运行时没有跟踪.

我在下面列出了示例代码,展示了我们如何编写它,以及输出的样子.

我们定义了多个不同的跟踪级别,以便开发人员可以识别哪些跟踪线很重要,并且可以根据需要过滤掉较低级别的详细信息.

示例代码:

- (void)myMethod:(NSObject *)xiObj
{
  TRC_ENTRY;
  TRC_DBG(@"Boring low level stuff");
  TRC_NRM(@"Higher level trace for more important info");
  TRC_ALT(@"Really important trace, something bad is happening");
  TRC_ERR(@"Error, this indicates a coding bug or unexpected condition");
  TRC_EXIT;
}
Run Code Online (Sandbox Code Playgroud)

示例跟踪输出:

2009-09-11 14:22:48.051 MyApp[3122:207] ENTRY:+[MyClass myMethod:]
2009-09-11 14:22:48.063 MyApp[3122:207] DEBUG:+[MyClass myMethod:]:Boring low level stuff
2009-09-11 14:22:48.063 MyApp[3122:207] NORMAL:+[MyClass myMethod:]:Higher level trace for more important info
2009-09-11 14:22:48.063 MyApp[3122:207] ALERT:+[MyClass myMethod:]:Really important trace, something bad is happening
2009-09-11 14:22:48.063 MyApp[3122:207] ERROR:+[MyClass myMethod:]:Error, this indicates a coding bug or unexpected condition
2009-09-11 14:22:48.073 MyApp[3122:207] EXIT:+[MyClass myMethod:]
Run Code Online (Sandbox Code Playgroud)

我们的跟踪定义:

#ifndef TRC_LEVEL
#if TARGET_IPHONE_SIMULATOR != 0
#define TRC_LEVEL 0
#else
#define TRC_LEVEL 5
#endif
#endif

/*****************************************************************************/
/* Entry/exit trace macros                                                   */
/*****************************************************************************/
#if TRC_LEVEL == 0
#define TRC_ENTRY    NSLog(@"ENTRY: %s:%d:", __PRETTY_FUNCTION__,__LINE__);
#define TRC_EXIT     NSLog(@"EXIT:  %s:%d:", __PRETTY_FUNCTION__,__LINE__);
#else
#define TRC_ENTRY
#define TRC_EXIT
#endif

/*****************************************************************************/
/* Debug trace macros                                                        */
/*****************************************************************************/
#if (TRC_LEVEL <= 1)
#define TRC_DBG(A, ...) NSLog(@"DEBUG: %s:%d:%@", __PRETTY_FUNCTION__,__LINE__,[NSString stringWithFormat:A, ## __VA_ARGS__]);
#else
#define TRC_DBG(A, ...)
#endif

#if (TRC_LEVEL <= 2)
#define TRC_NRM(A, ...) NSLog(@"NORMAL:%s:%d:%@", __PRETTY_FUNCTION__,__LINE__,[NSString stringWithFormat:A, ## __VA_ARGS__]);
#else
#define TRC_NRM(A, ...)
#endif

#if (TRC_LEVEL <= 3)
#define TRC_ALT(A, ...) NSLog(@"ALERT: %s:%d:%@", __PRETTY_FUNCTION__,__LINE__,[NSString stringWithFormat:A, ## __VA_ARGS__]);
#else
#define TRC_ALT(A, ...)
#endif

#if (TRC_LEVEL <= 4)
#define TRC_ERR(A, ...) NSLog(@"ERROR: %s:%d:%@", __PRETTY_FUNCTION__,__LINE__,[NSString stringWithFormat:A, ## __VA_ARGS__]);
#else
#define TRC_ERR(A, ...)
#endif
Run Code Online (Sandbox Code Playgroud)

Xcode设置:

在Xcode构建设置中,选择"添加用户定义的设置"(通过单击构建配置屏幕左下角的小齿轮),然后定义一个名为的新设置GCC_PREPROCESSOR_DEFINITIONS并为其赋值TRC_LEVEL=0.

唯一的细微之处在于,如果更改此设置,Xcode不知道要进行干净的构建,所以请记住如果更改它,请手动执行清理.