[英]Show alertview after crash app iOS
我试图在崩溃应用程序后向用户显示alertview,以提供有关崩溃的一些信息。 如; “您当机,我们将尽快修复。” 是否可以在此处显示alertview?
我从这里得到了这部分代码,并在其中放入了alertview。
- (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 在此处所说的好习惯。我用它来收集异常详细信息并将其发送回我的网站服务器,然后对其进行分析以解决问题。
在我的AppDelegate.m中
#import "UncaughtExceptionHandler.h"
//[...]
- (void)installUncaughtExceptionHandler
{
InstallUncaughtExceptionHandler();
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//[...]
NSSetUncaughtExceptionHandler(&uncaughtExceptionHandler);
//[...]
}
我的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.m
//
// 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);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.