在应用程序iOS崩溃后显示alertview
我正在尝试向用户显示alertview after crash应用程序,以提供有关崩溃的一些信息。例如,;“您发生故障,我们将尽快修复。”是否可以在此处显示alertview 我从这里得到了这部分代码,并将alertview放入其中在应用程序iOS崩溃后显示alertview,ios,objective-c,exception,uialertview,Ios,Objective C,Exception,Uialertview,我正在尝试向用户显示alertview after crash应用程序,以提供有关崩溃的一些信息。例如,;“您发生故障,我们将尽快修复。”是否可以在此处显示alertview 我从这里得到了这部分代码,并将alertview放入其中 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { NSSetUncaughtEx
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
NSSetUncaughtExceptionHandler(&myExceptionHandler);
}
void myExceptionHandler(NSException *exception)
{
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:@""
message:@"You got crash, we will fix as soon as possible!"
delegate:nil
cancelButtonTitle:@"Okay"
otherButtonTitles:nil, nil];
[alert show];
NSArray *stack = [exception callStackReturnAddresses];
NSLog(@"Stack trace: %@", stack);
}
我还尝试了此代码来显示警报
[alert performSelectorOnMainThread:@selector(show) withObject:nil waitUntilDone:YES];
你不应该那样做 原因如下:
你可以改为询问用户下次启动应用程序时,在崩溃发生之前他做了什么。要检测应用程序是否崩溃,您可以使用多个第三方服务或(开源)库来检测崩溃,并(安全地)在崩溃时收集堆栈跟踪 你不应该那样做 原因如下:
你可以改为询问用户下次启动应用程序时,在崩溃发生之前他做了什么。要检测应用程序是否崩溃,您可以使用多个第三方服务或(开源)库来检测崩溃,并(安全地)在崩溃时收集堆栈跟踪 发生碰撞时,我需要显示警告警报。我这样做了,它的工作 请注意,只有在真正必要的情况下才应该使用这样的代码(就像我的情况一样,因为这不是@Kerni所说的好做法。我使用它来收集异常详细信息并将它们发送回我的web服务器,然后分析它们以修复问题) 在我的AppDelegate.m中
#import "UncaughtExceptionHandler.h"
//[...]
- (void)installUncaughtExceptionHandler
{
InstallUncaughtExceptionHandler();
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//[...]
NSSetUncaughtExceptionHandler(&uncaughtExceptionHandler);
//[...]
}
//
// UncaughtExceptionHandler.m
// UncaughtExceptions
//
// Created by Matt Gallagher on 2010/05/25.
// Copyright 2010 Matt Gallagher. All rights reserved.
//
// Permission is given to use this source code file, free of charge, in any
// project, commercial or otherwise, entirely at your risk, with the condition
// that any redistribution (in part or whole) of source code must retain
// this copyright and permission notice. Attribution in compiled projects is
// appreciated but not required.
//
#import "UncaughtExceptionHandler.h"
#include <libkern/OSAtomic.h>
#include <execinfo.h>
NSString * const UncaughtExceptionHandlerSignalExceptionName = @"UncaughtExceptionHandlerSignalExceptionName";
NSString * const UncaughtExceptionHandlerSignalKey = @"UncaughtExceptionHandlerSignalKey";
NSString * const UncaughtExceptionHandlerAddressesKey = @"UncaughtExceptionHandlerAddressesKey";
volatile int32_t UncaughtExceptionCount = 0;
const int32_t UncaughtExceptionMaximum = 10;
const NSInteger UncaughtExceptionHandlerSkipAddressCount = 4;
const NSInteger UncaughtExceptionHandlerReportAddressCount = 5;
@implementation UncaughtExceptionHandler
+ (NSArray *)backtrace
{
void* callstack[128];
int frames = backtrace(callstack, 128);
char **strs = backtrace_symbols(callstack, frames);
int i;
NSMutableArray *backtrace = [NSMutableArray arrayWithCapacity:frames];
for (
i = UncaughtExceptionHandlerSkipAddressCount;
i < UncaughtExceptionHandlerSkipAddressCount +
UncaughtExceptionHandlerReportAddressCount;
i++)
{
[backtrace addObject:[NSString stringWithUTF8String:strs[i]]];
}
free(strs);
return backtrace;
}
- (void)handleException:(NSException *)exception
{
//here you can show your alert
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:@""
message:@"You got crash, we will fix as soon as possible!"
delegate:nil
cancelButtonTitle:@"Okay"
otherButtonTitles:nil, nil];
[alert show];
NSString* reason = [exception reason];
if([reason length]>200)
{
reason = [[reason substringToIndex:200] stringByAppendingString:@" [...]"];
}
CFRunLoopRef runLoop = CFRunLoopGetCurrent();
CFArrayRef allModes = CFRunLoopCopyAllModes(runLoop);
for (NSString *mode in (__bridge NSArray *)allModes)
{
CFRunLoopRunInMode((CFStringRef)mode, 0.001, false);
}
CFRelease(allModes);
NSSetUncaughtExceptionHandler(NULL);
signal(SIGABRT, SIG_DFL);
signal(SIGILL, SIG_DFL);
signal(SIGSEGV, SIG_DFL);
signal(SIGFPE, SIG_DFL);
signal(SIGBUS, SIG_DFL);
signal(SIGPIPE, SIG_DFL);
if ([[exception name] isEqual:UncaughtExceptionHandlerSignalExceptionName])
{
kill(getpid(), [[[exception userInfo] objectForKey:UncaughtExceptionHandlerSignalKey] intValue]);
}
else
{
[exception raise];
}
}
@end
void HandleException(NSException *exception)
{
int32_t exceptionCount = OSAtomicIncrement32(&UncaughtExceptionCount);
if (exceptionCount > UncaughtExceptionMaximum)
{
return;
}
NSArray *callStack = [exception callStackSymbols];
NSMutableDictionary *userInfo =
[NSMutableDictionary dictionaryWithDictionary:[exception userInfo]];
[userInfo
setObject:callStack
forKey:UncaughtExceptionHandlerAddressesKey];
[[[UncaughtExceptionHandler alloc] init]
performSelectorOnMainThread:@selector(handleException:)
withObject:
[NSException
exceptionWithName:[exception name]
reason:[exception reason]
userInfo:userInfo]
waitUntilDone:YES];
}
void SignalHandler(int signal)
{
int32_t exceptionCount = OSAtomicIncrement32(&UncaughtExceptionCount);
if (exceptionCount > UncaughtExceptionMaximum)
{
return;
}
NSMutableDictionary *userInfo =
[NSMutableDictionary
dictionaryWithObject:[NSNumber numberWithInt:signal]
forKey:UncaughtExceptionHandlerSignalKey];
NSArray *callStack = [UncaughtExceptionHandler backtrace];
[userInfo
setObject:callStack
forKey:UncaughtExceptionHandlerAddressesKey];
[[[UncaughtExceptionHandler alloc] init]
performSelectorOnMainThread:@selector(handleException:)
withObject:
[NSException
exceptionWithName:UncaughtExceptionHandlerSignalExceptionName
reason:
[NSString stringWithFormat:
NSLocalizedString(@"Signal %d was raised.", nil),
signal]
userInfo:
[NSDictionary
dictionaryWithObject:[NSNumber numberWithInt:signal]
forKey:UncaughtExceptionHandlerSignalKey]]
waitUntilDone:YES];
}
void InstallUncaughtExceptionHandler()
{
NSSetUncaughtExceptionHandler(&HandleException);
signal(SIGABRT, SignalHandler);
signal(SIGILL, SignalHandler);
signal(SIGSEGV, SignalHandler);
signal(SIGFPE, SignalHandler);
signal(SIGBUS, SignalHandler);
signal(SIGPIPE, SignalHandler);
}
我的UncaughtExceptionHandler.h
//
// UncaughtExceptionHandler.h
// UncaughtExceptions
//
// Created by Matt Gallagher on 2010/05/25.
// Copyright 2010 Matt Gallagher. All rights reserved.
//
// Permission is given to use this source code file, free of charge, in any
// project, commercial or otherwise, entirely at your risk, with the condition
// that any redistribution (in part or whole) of source code must retain
// this copyright and permission notice. Attribution in compiled projects is
// appreciated but not required.
//
#import <UIKit/UIKit.h>
@interface UncaughtExceptionHandler : NSObject<UIAlertViewDelegate>
{
NSException* currentException;
}
@end
void InstallUncaughtExceptionHandler();
//
//UncaughtExceptionHandler.h
//未捕获的异常
//
//由马特·加拉赫于2010年5月25日创作。
//版权所有2010马特·加拉赫。保留所有权利。
//
//允许以任何形式免费使用此源代码文件
//项目,商业或其他,完全由您承担风险,条件
//源代码的任何重新分发(部分或全部)都必须保留
//此版权和许可声明。编译项目的归属为
//感激但不是必需的。
//
#进口
@接口UncaughtExceptionHandler:NSObject
{
NSException*currentException;
}
@结束
void InstallUncaughtExceptionHandler();
我的UncaughtExceptionHandler.m
#import "UncaughtExceptionHandler.h"
//[...]
- (void)installUncaughtExceptionHandler
{
InstallUncaughtExceptionHandler();
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//[...]
NSSetUncaughtExceptionHandler(&uncaughtExceptionHandler);
//[...]
}
//
// UncaughtExceptionHandler.m
// UncaughtExceptions
//
// Created by Matt Gallagher on 2010/05/25.
// Copyright 2010 Matt Gallagher. All rights reserved.
//
// Permission is given to use this source code file, free of charge, in any
// project, commercial or otherwise, entirely at your risk, with the condition
// that any redistribution (in part or whole) of source code must retain
// this copyright and permission notice. Attribution in compiled projects is
// appreciated but not required.
//
#import "UncaughtExceptionHandler.h"
#include <libkern/OSAtomic.h>
#include <execinfo.h>
NSString * const UncaughtExceptionHandlerSignalExceptionName = @"UncaughtExceptionHandlerSignalExceptionName";
NSString * const UncaughtExceptionHandlerSignalKey = @"UncaughtExceptionHandlerSignalKey";
NSString * const UncaughtExceptionHandlerAddressesKey = @"UncaughtExceptionHandlerAddressesKey";
volatile int32_t UncaughtExceptionCount = 0;
const int32_t UncaughtExceptionMaximum = 10;
const NSInteger UncaughtExceptionHandlerSkipAddressCount = 4;
const NSInteger UncaughtExceptionHandlerReportAddressCount = 5;
@implementation UncaughtExceptionHandler
+ (NSArray *)backtrace
{
void* callstack[128];
int frames = backtrace(callstack, 128);
char **strs = backtrace_symbols(callstack, frames);
int i;
NSMutableArray *backtrace = [NSMutableArray arrayWithCapacity:frames];
for (
i = UncaughtExceptionHandlerSkipAddressCount;
i < UncaughtExceptionHandlerSkipAddressCount +
UncaughtExceptionHandlerReportAddressCount;
i++)
{
[backtrace addObject:[NSString stringWithUTF8String:strs[i]]];
}
free(strs);
return backtrace;
}
- (void)handleException:(NSException *)exception
{
//here you can show your alert
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:@""
message:@"You got crash, we will fix as soon as possible!"
delegate:nil
cancelButtonTitle:@"Okay"
otherButtonTitles:nil, nil];
[alert show];
NSString* reason = [exception reason];
if([reason length]>200)
{
reason = [[reason substringToIndex:200] stringByAppendingString:@" [...]"];
}
CFRunLoopRef runLoop = CFRunLoopGetCurrent();
CFArrayRef allModes = CFRunLoopCopyAllModes(runLoop);
for (NSString *mode in (__bridge NSArray *)allModes)
{
CFRunLoopRunInMode((CFStringRef)mode, 0.001, false);
}
CFRelease(allModes);
NSSetUncaughtExceptionHandler(NULL);
signal(SIGABRT, SIG_DFL);
signal(SIGILL, SIG_DFL);
signal(SIGSEGV, SIG_DFL);
signal(SIGFPE, SIG_DFL);
signal(SIGBUS, SIG_DFL);
signal(SIGPIPE, SIG_DFL);
if ([[exception name] isEqual:UncaughtExceptionHandlerSignalExceptionName])
{
kill(getpid(), [[[exception userInfo] objectForKey:UncaughtExceptionHandlerSignalKey] intValue]);
}
else
{
[exception raise];
}
}
@end
void HandleException(NSException *exception)
{
int32_t exceptionCount = OSAtomicIncrement32(&UncaughtExceptionCount);
if (exceptionCount > UncaughtExceptionMaximum)
{
return;
}
NSArray *callStack = [exception callStackSymbols];
NSMutableDictionary *userInfo =
[NSMutableDictionary dictionaryWithDictionary:[exception userInfo]];
[userInfo
setObject:callStack
forKey:UncaughtExceptionHandlerAddressesKey];
[[[UncaughtExceptionHandler alloc] init]
performSelectorOnMainThread:@selector(handleException:)
withObject:
[NSException
exceptionWithName:[exception name]
reason:[exception reason]
userInfo:userInfo]
waitUntilDone:YES];
}
void SignalHandler(int signal)
{
int32_t exceptionCount = OSAtomicIncrement32(&UncaughtExceptionCount);
if (exceptionCount > UncaughtExceptionMaximum)
{
return;
}
NSMutableDictionary *userInfo =
[NSMutableDictionary
dictionaryWithObject:[NSNumber numberWithInt:signal]
forKey:UncaughtExceptionHandlerSignalKey];
NSArray *callStack = [UncaughtExceptionHandler backtrace];
[userInfo
setObject:callStack
forKey:UncaughtExceptionHandlerAddressesKey];
[[[UncaughtExceptionHandler alloc] init]
performSelectorOnMainThread:@selector(handleException:)
withObject:
[NSException
exceptionWithName:UncaughtExceptionHandlerSignalExceptionName
reason:
[NSString stringWithFormat:
NSLocalizedString(@"Signal %d was raised.", nil),
signal]
userInfo:
[NSDictionary
dictionaryWithObject:[NSNumber numberWithInt:signal]
forKey:UncaughtExceptionHandlerSignalKey]]
waitUntilDone:YES];
}
void InstallUncaughtExceptionHandler()
{
NSSetUncaughtExceptionHandler(&HandleException);
signal(SIGABRT, SignalHandler);
signal(SIGILL, SignalHandler);
signal(SIGSEGV, SignalHandler);
signal(SIGFPE, SignalHandler);
signal(SIGBUS, SignalHandler);
signal(SIGPIPE, SignalHandler);
}
//
//UncaughtExceptionHandler.m
//未捕获的异常
//
//由马特·加拉赫于2010年5月25日创作。
//版权所有2010马特·加拉赫。保留所有权利。
//
//允许以任何形式免费使用此源代码文件
//项目,商业或其他,完全由您承担风险,条件
//源代码的任何重新分发(部分或全部)都必须保留
//此版权和许可声明。编译项目的归属为
//感激但不是必需的。
//
#导入“UncaughtExceptionHandler.h”
#包括
#包括
NSString*常量UncaughtExceptionHandlerSignalExceptionName=@“UncaughtExceptionHandlerSignalExceptionName”;
NSString*常量UncaughtExceptionHandlerSignalKey=@“UncaughtExceptionHandlerSignalKey”;
NSString*常量UncaughtExceptionHandlerAddressSkey=@“UncaughtExceptionHandlerAddressSkey”;
volatile int32_t UncaughtExceptionCount=0;
常量int32_t UncaughtExceptionMaximum=10;
const NSInteger uncaughtexception handlerskipaddresscount=4;
const NSInteger UncaughtExceptionHandlerReportAddressCount=5;
@实现UncaughtExceptionHandler
+(NSArray*)回溯
{
void*callstack[128];
int frames=backtrace(调用堆栈,128);
char**strs=回溯_符号(调用堆栈、帧);
int i;
NSMutableArray*回溯=[NSMutableArray阵列容量:帧];
为了(
i=未捕获的例外HandlerSkipAddressCount;
i200)
{
原因=[[reason sub]