Initial commit
This commit is contained in:
BIN
EonaCatTools/Tools/ExceptionsLogger/.DS_Store
vendored
Normal file
BIN
EonaCatTools/Tools/ExceptionsLogger/.DS_Store
vendored
Normal file
Binary file not shown.
@@ -0,0 +1,5 @@
|
||||
// Dutch language file
|
||||
|
||||
"Back" = "Terug";
|
||||
"Clear" = "Legen";
|
||||
"Exceptions" = "Foutmeldingen";
|
||||
@@ -0,0 +1,5 @@
|
||||
// English language file
|
||||
|
||||
"Back" = "Back";
|
||||
"Clear" = "Clear";
|
||||
"Exceptions" = "Exceptions";
|
||||
20
EonaCatTools/Tools/ExceptionsLogger/ExceptionHandler.h
Normal file
20
EonaCatTools/Tools/ExceptionsLogger/ExceptionHandler.h
Normal file
@@ -0,0 +1,20 @@
|
||||
//
|
||||
// ExceptionHandler.h
|
||||
// Created by EonaCat
|
||||
// Copyright 2013 EonaCat. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <MessageUI/MFMailComposeViewController.h>
|
||||
|
||||
#define exceptionDelegate [[UIApplication sharedApplication] delegate]
|
||||
|
||||
@interface ExceptionHandler : UIViewController <MFMailComposeViewControllerDelegate>
|
||||
{
|
||||
BOOL dismissed;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
void createExceptionHandler(NSString *emailAddress,NSString *BCCemailAddress);
|
||||
359
EonaCatTools/Tools/ExceptionsLogger/ExceptionHandler.m
Normal file
359
EonaCatTools/Tools/ExceptionsLogger/ExceptionHandler.m
Normal file
@@ -0,0 +1,359 @@
|
||||
//
|
||||
// ExceptionHandler.m
|
||||
// Created by EonaCat
|
||||
// Copyright 2013 EonaCat. All rights reserved.
|
||||
//
|
||||
|
||||
// The ExceptionHandler needs to be imported in the ApplicationDelegate by using the #import "ExceptionHandler.h"; statement in de .m file
|
||||
// The following functions need to be created in the ApplicationDelegate.m file
|
||||
|
||||
// - (void)setExceptionHandler
|
||||
// {
|
||||
// createExceptionHandler(@"YOUREMAILADDRESS", @"");
|
||||
// }
|
||||
|
||||
// In the ApplicationDelegate file the method
|
||||
// - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
|
||||
// need to be created inside this method you will need to implement the following code:
|
||||
//
|
||||
|
||||
// //Create the exceptionHandler
|
||||
// [self performSelector:@selector(setExceptionHandler) withObject:nil afterDelay:0];
|
||||
//
|
||||
//
|
||||
// You will need to implement the application delegate of the application before you can use the Email function.
|
||||
// So be sure to import the applications's delegate headerfile and change the following line:
|
||||
// (Located in the - (void) displayComposerSheet:(NSString *)body method)
|
||||
//
|
||||
// [self presentViewController: tempMailCompose animated:YES completion:nil];
|
||||
//
|
||||
// into
|
||||
//
|
||||
// [root.navigationController presentViewController: tempMailCompose animated:YES completion:nil];
|
||||
//
|
||||
// Be sure that the following line is present in your core or appdelegate file
|
||||
// #define Delegate ((yourAppDelegateFileName*)[UIApplication sharedApplication].delegate)
|
||||
|
||||
|
||||
|
||||
#import "ExceptionHandler.h"
|
||||
#import "DeviceIdentifier.h"
|
||||
#include <libkern/OSAtomic.h>
|
||||
#include <execinfo.h>
|
||||
#import "ExceptionLogger.h"
|
||||
|
||||
const NSString *ExceptionName = @"ExceptionName";
|
||||
const NSString *ExceptionKey = @"ExceptionKey";
|
||||
const NSString *ExceptionAddresses = @"ExceptionAddresses";
|
||||
|
||||
NSString *ExceptionTitle = @"iPhone Exception";
|
||||
NSString *ExceptionEmail = @"";
|
||||
NSString *ExceptionBCCEmail = @"";
|
||||
NSString *ExceptionMessage = @"";
|
||||
NSInteger ExceptionShown = 0;
|
||||
BOOL ExceptionAlert = true;
|
||||
|
||||
volatile int32_t ExceptionCount = 0;
|
||||
const int32_t ExceptionMaximum = 5;
|
||||
|
||||
const NSInteger ExceptionHandlerSkipAddressCount = 4;
|
||||
const NSInteger ExceptionHandlerReportAddressCount = 5;
|
||||
|
||||
@implementation ExceptionHandler
|
||||
|
||||
+ (NSArray *)backtrace
|
||||
{
|
||||
void *callstack[128];
|
||||
int frames = backtrace(callstack, 128);
|
||||
char **stringSymbols = backtrace_symbols(callstack, frames);
|
||||
|
||||
int i;
|
||||
NSMutableArray *backtrace = [NSMutableArray arrayWithCapacity:frames];
|
||||
|
||||
for (i = ExceptionHandlerSkipAddressCount; i < ExceptionHandlerSkipAddressCount + ExceptionHandlerReportAddressCount; i++)
|
||||
{
|
||||
[backtrace addObject:[NSString stringWithUTF8String:stringSymbols[i]]];
|
||||
}
|
||||
free(stringSymbols);
|
||||
|
||||
return backtrace;
|
||||
}
|
||||
|
||||
- (void)alertView:(UIAlertView *)anAlertView clickedButtonAtIndex:(NSInteger)Index
|
||||
{
|
||||
if (Index == 0) // Quit button clicked
|
||||
{
|
||||
ExceptionShown = 0;
|
||||
dismissed = YES;
|
||||
}
|
||||
else if (Index == 1) // Continue button clicked
|
||||
{
|
||||
ExceptionShown = 0;
|
||||
}
|
||||
else if (Index == 2) // Email button clicked
|
||||
{
|
||||
// Create the email that needs to be send
|
||||
[self performSelector:@selector(showComposer:) withObject:ExceptionMessage afterDelay:0.1];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Displays an email composition interface inside the application. Populates all the Mail fields.
|
||||
- (void) displayComposerSheet:(NSString *)body
|
||||
{
|
||||
MFMailComposeViewController *mailController = [[MFMailComposeViewController alloc] init];
|
||||
mailController.mailComposeDelegate = self;
|
||||
|
||||
NSArray *toRecipient = [[NSArray alloc] initWithObjects:ExceptionEmail,nil];
|
||||
[mailController setToRecipients:toRecipient];
|
||||
|
||||
if (ExceptionBCCEmail.length > 0)
|
||||
{
|
||||
NSArray *bccRecipient = [[NSArray alloc] initWithObjects:ExceptionBCCEmail,nil];
|
||||
[mailController setBccRecipients:bccRecipient];
|
||||
}
|
||||
[mailController setSubject:ExceptionTitle];
|
||||
[mailController setMessageBody:body isHTML:NO];
|
||||
|
||||
UIWindow* window = [[UIApplication sharedApplication] keyWindow];
|
||||
[window addSubview:mailController.view];
|
||||
}
|
||||
|
||||
// Dismisses the email composition interface when users tap Cancel or Send. Proceeds to update the message field with the result of the operation.
|
||||
- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error
|
||||
{
|
||||
// Notifies users about errors associated with the interface
|
||||
switch (result)
|
||||
{
|
||||
case MFMailComposeResultCancelled:
|
||||
NSLog(@"Result: canceled");
|
||||
break;
|
||||
case MFMailComposeResultSaved:
|
||||
NSLog(@"Result: saved");
|
||||
break;
|
||||
case MFMailComposeResultSent:
|
||||
NSLog(@"Result: sent");
|
||||
break;
|
||||
case MFMailComposeResultFailed:
|
||||
NSLog(@"Result: failed");
|
||||
break;
|
||||
default:
|
||||
NSLog(@"Result: not sent");
|
||||
break;
|
||||
}
|
||||
[self dismissViewControllerAnimated:YES completion:nil];
|
||||
}
|
||||
|
||||
// Launches the Mail application on the device. Workaround
|
||||
-(void)launchMailAppOnDevice:(NSString *)body
|
||||
{
|
||||
NSString *recipients;
|
||||
|
||||
if ([ExceptionEmail isEqualToString:@"YOUREMAILADDRESS"])
|
||||
{
|
||||
NSLog(@"Could not send email (default values where detected!)");
|
||||
return;
|
||||
}
|
||||
|
||||
if (ExceptionBCCEmail.length > 0)
|
||||
{
|
||||
recipients = [NSString stringWithFormat:@"mailto:%@?bcc=%@?subject=%@", ExceptionEmail, ExceptionBCCEmail, ExceptionTitle];
|
||||
}
|
||||
else
|
||||
{
|
||||
recipients = [NSString stringWithFormat:@"mailto:%@?subject=%@", ExceptionEmail, ExceptionTitle];
|
||||
}
|
||||
|
||||
NSString *mailBody = [NSString stringWithFormat:@"&body=%@", body];
|
||||
|
||||
NSString *email = [NSString stringWithFormat:@"%@%@", recipients, mailBody];
|
||||
email = [email stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
|
||||
|
||||
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:email]];
|
||||
}
|
||||
|
||||
// Call this method and pass parameters
|
||||
-(void) showComposer:(id)sender
|
||||
{
|
||||
Class mailClass = (NSClassFromString(@"MFMailComposeViewController"));
|
||||
|
||||
if (mailClass != nil)
|
||||
{
|
||||
// We must always check whether the current device is configured for sending emails
|
||||
if ([mailClass canSendMail])
|
||||
{
|
||||
[self displayComposerSheet:sender];
|
||||
}
|
||||
else
|
||||
{
|
||||
[self launchMailAppOnDevice:sender];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
[self launchMailAppOnDevice:sender];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (void)saveAndQuit
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
- (void)checkForExceptions:(NSException *)exception
|
||||
{
|
||||
if (ExceptionShown == 0)
|
||||
{
|
||||
ExceptionShown = 1;
|
||||
[self saveAndQuit];
|
||||
|
||||
/*
|
||||
// Set the IMEI Number
|
||||
// Check if you got iOS5
|
||||
NSString *IMEI;
|
||||
float version = [[[UIDevice currentDevice] systemVersion] floatValue];
|
||||
if (version >= 5.0)
|
||||
{
|
||||
IMEI = [[NSString alloc] initWithString:[[UIDevice currentDevice] deviceIdentifier]];
|
||||
}
|
||||
else
|
||||
{
|
||||
IMEI = [[NSString alloc] initWithString:[[UIDevice currentDevice] uniqueIdentifier]];
|
||||
}
|
||||
*/
|
||||
|
||||
NSDate *currentTime = [NSDate date];
|
||||
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
|
||||
[dateFormatter setDateFormat:@"YYYY-MM-dd hh-mm"];
|
||||
NSString *resultString = [dateFormatter stringFromDate: currentTime];
|
||||
|
||||
ExceptionMessage = [NSString stringWithFormat:
|
||||
@"iPhone exception information:\n\n"
|
||||
@"Date: %@\n"
|
||||
@"Application Name: %@\n"
|
||||
@"Localized Application Name: %@\n"
|
||||
@"Devicetype: %@\n"
|
||||
@"============================= \n"
|
||||
@"Reason: %@\n"
|
||||
@"============================= \n\n"
|
||||
@"***************************** \n\n"
|
||||
@"Exception: %@\n\n"
|
||||
@"***************************** \n",
|
||||
resultString, [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"],
|
||||
[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleDisplayName"], [UIDevice currentDevice].model,
|
||||
[exception reason],[[exception userInfo] objectForKey:ExceptionAddresses]];
|
||||
|
||||
if (ExceptionAlert)
|
||||
{
|
||||
UIAlertView *alert =
|
||||
[[UIAlertView alloc]
|
||||
initWithTitle:@"You have found an error"
|
||||
message:[NSString stringWithFormat: @"You can try continuing using the application "
|
||||
@"but it may become unstable after a while.\n"
|
||||
@"Please send us an email with the error report "
|
||||
@"by clicking on the send report button."]
|
||||
delegate:self
|
||||
cancelButtonTitle:@"Quit"
|
||||
otherButtonTitles:@"Continue", @"Send report",nil];
|
||||
[alert show];
|
||||
}
|
||||
else
|
||||
{
|
||||
[[ExceptionLogger instance] log:ExceptionMessage];
|
||||
}
|
||||
|
||||
CFRunLoopRef runLoop = CFRunLoopGetCurrent();
|
||||
CFArrayRef allModes = CFRunLoopCopyAllModes(runLoop);
|
||||
|
||||
while (!dismissed)
|
||||
{
|
||||
for (NSString *mode in (__bridge NSArray *)allModes)
|
||||
{
|
||||
CFRunLoopRunInMode((__bridge 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:ExceptionName])
|
||||
{
|
||||
kill(getpid(), [[[exception userInfo] objectForKey:ExceptionKey] intValue]);
|
||||
}
|
||||
else
|
||||
{
|
||||
[exception raise];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
void checkForExceptions(NSException *exception)
|
||||
{
|
||||
int32_t exceptionCount = OSAtomicIncrement32(&ExceptionCount);
|
||||
if (exceptionCount > ExceptionMaximum)
|
||||
{
|
||||
NSLog(@"Maximum amount of exceptions where raised !");
|
||||
return;
|
||||
}
|
||||
|
||||
NSArray *callStack = [ExceptionHandler backtrace];
|
||||
NSMutableDictionary *userInfo =
|
||||
[NSMutableDictionary dictionaryWithDictionary:[exception userInfo]];
|
||||
[userInfo
|
||||
setObject:callStack
|
||||
forKey:ExceptionAddresses];
|
||||
|
||||
[[[ExceptionHandler alloc] init]
|
||||
performSelectorOnMainThread:@selector(checkForExceptions:)
|
||||
withObject:
|
||||
[NSException
|
||||
exceptionWithName:[exception name]
|
||||
reason:[exception reason]
|
||||
userInfo:userInfo]
|
||||
waitUntilDone:YES];
|
||||
}
|
||||
|
||||
void ExceptionCounter(int exception)
|
||||
{
|
||||
int32_t exceptionCount = OSAtomicIncrement32(&ExceptionCount);
|
||||
|
||||
if (exceptionCount > ExceptionMaximum)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
NSMutableDictionary *userInfo = [NSMutableDictionary dictionaryWithObject:[NSNumber numberWithInt:exception] forKey:ExceptionKey];
|
||||
|
||||
NSArray *callStack = [ExceptionHandler backtrace];
|
||||
[userInfo setObject:callStack forKey:ExceptionAddresses];
|
||||
|
||||
[[[ExceptionHandler alloc] init] performSelectorOnMainThread:@selector(checkForExceptions:)
|
||||
withObject: [NSException exceptionWithName:[NSString stringWithFormat:@"%@",ExceptionTitle]
|
||||
reason: [NSString stringWithFormat: NSLocalizedString(@"Signal %d was raised.", nil), signal]
|
||||
userInfo: [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:exception] forKey:ExceptionKey]]
|
||||
waitUntilDone:YES];
|
||||
}
|
||||
|
||||
void createExceptionHandler(NSString *emailAddress,NSString *BCCemailAddress)
|
||||
{
|
||||
NSSetUncaughtExceptionHandler(&checkForExceptions);
|
||||
signal(SIGABRT, ExceptionCounter);
|
||||
signal(SIGILL, ExceptionCounter);
|
||||
signal(SIGSEGV, ExceptionCounter);
|
||||
signal(SIGFPE, ExceptionCounter);
|
||||
signal(SIGBUS, ExceptionCounter);
|
||||
signal(SIGPIPE, ExceptionCounter);
|
||||
|
||||
ExceptionEmail = emailAddress;
|
||||
ExceptionBCCEmail = BCCemailAddress;
|
||||
}
|
||||
46
EonaCatTools/Tools/ExceptionsLogger/ExceptionLogger-iPad.xib
Normal file
46
EonaCatTools/Tools/ExceptionsLogger/ExceptionLogger-iPad.xib
Normal file
@@ -0,0 +1,46 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.iPad.XIB" version="3.0" toolsVersion="4471.1" systemVersion="12E55" targetRuntime="iOS.CocoaTouch.iPad" propertyAccessControl="none">
|
||||
<dependencies>
|
||||
<deployment version="768" defaultVersion="1792" identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="3697.3"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="ExceptionLogger">
|
||||
<connections>
|
||||
<outlet property="navigationBar" destination="24" id="26"/>
|
||||
<outlet property="view" destination="1" id="25"/>
|
||||
</connections>
|
||||
</placeholder>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<view contentMode="scaleToFill" id="1">
|
||||
<rect key="frame" x="0.0" y="0.0" width="768" height="1024"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<subviews>
|
||||
<navigationBar contentMode="scaleToFill" id="23">
|
||||
<rect key="frame" x="0.0" y="0.0" width="768" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
|
||||
<color key="tintColor" red="1" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<items>
|
||||
<navigationItem title="Exceptions" id="24"/>
|
||||
</items>
|
||||
</navigationBar>
|
||||
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" image="ExceptionLogger.png" id="27">
|
||||
<rect key="frame" x="277" y="814" width="215" height="170"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
</imageView>
|
||||
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" showsHorizontalScrollIndicator="NO" id="Qly-Ng-xEE">
|
||||
<rect key="frame" x="14" y="58" width="742" height="748"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<color key="backgroundColor" cocoaTouchSystemColor="tableCellGroupedBackgroundColor"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||
<textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
|
||||
</textView>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
|
||||
<simulatedStatusBarMetrics key="simulatedStatusBarMetrics" statusBarStyle="blackTranslucent"/>
|
||||
</view>
|
||||
</objects>
|
||||
<resources>
|
||||
<image name="ExceptionLogger.png" width="128" height="128"/>
|
||||
</resources>
|
||||
</document>
|
||||
24
EonaCatTools/Tools/ExceptionsLogger/ExceptionLogger.h
Normal file
24
EonaCatTools/Tools/ExceptionsLogger/ExceptionLogger.h
Normal file
@@ -0,0 +1,24 @@
|
||||
//
|
||||
// ExceptionLogger.h
|
||||
// Created by EonaCat
|
||||
// Copyright 2013 EonaCat. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface ExceptionLogger : UIViewController <UITextViewDelegate>
|
||||
{
|
||||
IBOutlet UINavigationItem *navigationBar;
|
||||
NSString *path;
|
||||
IBOutlet UITextView *textView;
|
||||
}
|
||||
|
||||
@property (nonatomic, strong) IBOutlet UINavigationItem *navigationBar;
|
||||
@property (nonatomic, strong) IBOutlet UITextView *textView;
|
||||
|
||||
+(ExceptionLogger*)instance;
|
||||
-(IBAction)updateLog:(id)sender;
|
||||
-(IBAction)Clear:(id)sender;
|
||||
-(void)log:(NSString*)exception;
|
||||
|
||||
@end
|
||||
226
EonaCatTools/Tools/ExceptionsLogger/ExceptionLogger.m
Normal file
226
EonaCatTools/Tools/ExceptionsLogger/ExceptionLogger.m
Normal file
@@ -0,0 +1,226 @@
|
||||
//
|
||||
// ExceptionLogger.m
|
||||
// Created by EonaCat
|
||||
// Copyright 2013 EonaCat. All rights reserved.
|
||||
//
|
||||
|
||||
// The ExceptionLogger needs to be imported in a view by using the #import "ExceptionLogger.h"; statement in de .m file
|
||||
// The following functions need to be created in the view.m file
|
||||
|
||||
// - (void)swipedScreen:(UISwipeGestureRecognizer*)swipeGesture
|
||||
// {
|
||||
// // Show ExceptionLogger (Check for iPhone or iPad)
|
||||
// ExceptionLogger* exceptionLogger = nil;
|
||||
// if (iPad)
|
||||
// {
|
||||
// exceptionLogger = [[ExceptionLogger alloc] initWithNibName:@"ExceptionLogger-iPad" bundle:nil];
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// exceptionLogger = [[ExceptionLogger alloc] initWithNibName:@"ExceptionLogger" bundle:nil];
|
||||
// }
|
||||
// [self.navigationController pushViewController:exceptionLogger animated:YES completion:nil];
|
||||
// [exceptionLogger release];
|
||||
// }
|
||||
|
||||
// Add these line to your ViewDidLoad method:
|
||||
//
|
||||
// // Add the ExceptionLogger Swipe Gesture
|
||||
// UISwipeGestureRecognizer *swipeRight = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipedScreen:)];
|
||||
// swipeRight.direction = UISwipeGestureRecognizerDirectionRight;
|
||||
// [self.view addGestureRecognizer:swipeRight];
|
||||
|
||||
// In your delegate file you need to write the following lines:
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
// Be sure that the following line is present in your core or delegate file
|
||||
// #define Delegate ((yourAppDelegateFileName*)[UIApplication sharedApplication].delegate)
|
||||
|
||||
#import "ExceptionLogger.h"
|
||||
|
||||
@implementation ExceptionLogger
|
||||
static ExceptionLogger* _instance = nil;
|
||||
|
||||
@synthesize textView;
|
||||
@synthesize navigationBar;
|
||||
|
||||
+(ExceptionLogger*)instance
|
||||
{
|
||||
@synchronized([ExceptionLogger class])
|
||||
{
|
||||
if (!_instance)
|
||||
{
|
||||
[self alloc];
|
||||
}
|
||||
return _instance;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
+(id)alloc
|
||||
{
|
||||
@synchronized([ExceptionLogger class])
|
||||
{
|
||||
_instance = [super alloc];
|
||||
return _instance;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void)viewDidLoad
|
||||
{
|
||||
@try
|
||||
{
|
||||
[super viewDidLoad];
|
||||
self.navigationBar.title = NSLocalizedStringFromTable(@"Exceptions", @"ExceptionsLogger", @"Exceptions");
|
||||
navigationBar.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle: NSLocalizedStringFromTable(@"Back", @"ExceptionsLogger", @"Back")
|
||||
style: UIBarButtonItemStyleBordered
|
||||
target: self
|
||||
action: @selector(Back:)];
|
||||
|
||||
navigationBar.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle: NSLocalizedStringFromTable(@"Clear", @"ExceptionsLogger", @"Clear")
|
||||
style: UIBarButtonItemStyleBordered
|
||||
target: self
|
||||
action: @selector(Clear:)];
|
||||
textView.editable = false;
|
||||
textView.text = @"";
|
||||
[self updateLog:self];
|
||||
textView.hidden = false;
|
||||
|
||||
[NSTimer scheduledTimerWithTimeInterval:5 target:self selector:@selector(updateLog:) userInfo:nil repeats:YES];
|
||||
}
|
||||
@catch(NSException* exception)
|
||||
{
|
||||
NSLog(@"Exception: ExceptionLogger > viewDidLoad\n%@",exception);
|
||||
}
|
||||
}
|
||||
|
||||
- (IBAction)Back:(id)sender
|
||||
{
|
||||
[self dismissViewControllerAnimated:YES completion:nil];
|
||||
}
|
||||
|
||||
-(void)log:(NSString*)exception
|
||||
{
|
||||
@try
|
||||
{
|
||||
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
|
||||
[dateFormatter setDateFormat:@"dd-MM-YYYY HH:mm:ss"];
|
||||
NSString *stringFromDate = [dateFormatter stringFromDate:[NSDate date]];
|
||||
NSString* stringData = [[NSString alloc] initWithFormat:@"\n%@\n\n %@", stringFromDate, exception];
|
||||
NSData *dataToWrite = [stringData dataUsingEncoding:NSUTF8StringEncoding];
|
||||
|
||||
NSString *docsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
|
||||
path = [docsDirectory stringByAppendingPathComponent:@"Exceptions.log"];
|
||||
|
||||
NSFileManager *fileManager = [NSFileManager defaultManager];
|
||||
|
||||
if (![fileManager fileExistsAtPath:path])
|
||||
{
|
||||
[fileManager createFileAtPath:path contents:nil attributes:nil];
|
||||
}
|
||||
|
||||
NSDictionary* attributes = [fileManager attributesOfItemAtPath:path error:nil];
|
||||
NSNumber* fileSize = [attributes objectForKey:NSFileSize];
|
||||
// Check if the logfile exceeds 10 MB
|
||||
|
||||
if ([fileSize intValue] > 10 * 1024)
|
||||
{
|
||||
[fileManager removeItemAtPath:path error:nil];
|
||||
[fileManager createFileAtPath:path contents:nil attributes:nil];
|
||||
}
|
||||
|
||||
NSMutableData *concatenatedData = [[NSMutableData alloc] init];
|
||||
[concatenatedData appendData: dataToWrite];
|
||||
NSData *fileData = [[NSData alloc] initWithContentsOfFile:(NSString *)path];
|
||||
[concatenatedData appendData: fileData];
|
||||
NSFileHandle *fileHandle = [NSFileHandle fileHandleForWritingAtPath:path];
|
||||
[fileHandle seekToFileOffset:0];
|
||||
[fileHandle writeData:concatenatedData];
|
||||
}
|
||||
@catch(NSException* exception)
|
||||
{
|
||||
NSLog(@"Exception: ExceptionLogger > log\n%@",exception);
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)canBecomeFirstResponder
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
-(IBAction)updateLog:(id)sender
|
||||
{
|
||||
@try
|
||||
{
|
||||
NSString *docsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
|
||||
path = [docsDirectory stringByAppendingPathComponent:@"Exceptions.log"];
|
||||
|
||||
NSFileManager *fileManager = [NSFileManager defaultManager];
|
||||
if ([fileManager fileExistsAtPath:path])
|
||||
{
|
||||
textView.text = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];[NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
|
||||
}
|
||||
}
|
||||
@catch(NSException* exception)
|
||||
{
|
||||
NSLog(@"Exception: ExceptionLogger > updateLog\n%@",exception);
|
||||
}
|
||||
}
|
||||
|
||||
-(IBAction)Clear:(id)sender
|
||||
{
|
||||
@try
|
||||
{
|
||||
NSString *docsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
|
||||
|
||||
path = [docsDirectory stringByAppendingPathComponent:@"Exceptions.log"];
|
||||
|
||||
NSFileManager *fileManager = [NSFileManager defaultManager];
|
||||
if ([fileManager fileExistsAtPath:path])
|
||||
{
|
||||
[fileManager removeItemAtPath:path error:nil];
|
||||
[fileManager createFileAtPath:path contents:nil attributes:nil ];
|
||||
}
|
||||
|
||||
[self updateLog:self];
|
||||
}
|
||||
@catch(NSException* exception)
|
||||
{
|
||||
NSLog(@"Exception: ExceptionLogger > Clear\n%@",exception);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)viewWillAppear:(BOOL)animated
|
||||
{
|
||||
@try
|
||||
{
|
||||
[super viewWillAppear:animated];
|
||||
}
|
||||
@catch(NSException* exception)
|
||||
{
|
||||
NSLog(@"Exception: ExceptionLogger > viewWillAppear\n%@",exception);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (void)viewDidAppear:(BOOL)animated
|
||||
{
|
||||
[super viewDidAppear:animated];
|
||||
}
|
||||
|
||||
// Rotate application view
|
||||
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)didReceiveMemoryWarning
|
||||
{
|
||||
[super didReceiveMemoryWarning];
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
BIN
EonaCatTools/Tools/ExceptionsLogger/ExceptionLogger.png
Normal file
BIN
EonaCatTools/Tools/ExceptionsLogger/ExceptionLogger.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
47
EonaCatTools/Tools/ExceptionsLogger/ExceptionLogger.xib
Normal file
47
EonaCatTools/Tools/ExceptionsLogger/ExceptionLogger.xib
Normal file
@@ -0,0 +1,47 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="4471.1" systemVersion="12E55" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none">
|
||||
<dependencies>
|
||||
<deployment version="768" defaultVersion="1792" identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="3697.3"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="ExceptionLogger">
|
||||
<connections>
|
||||
<outlet property="navigationBar" destination="26" id="27"/>
|
||||
<outlet property="textView" destination="CsP-Zy-WmE" id="gbE-Ge-Bdn"/>
|
||||
<outlet property="view" destination="1" id="3"/>
|
||||
</connections>
|
||||
</placeholder>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<view contentMode="scaleToFill" id="1">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="460"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<subviews>
|
||||
<navigationBar contentMode="scaleToFill" id="25">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
|
||||
<color key="tintColor" red="1" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<items>
|
||||
<navigationItem title="Exceptions" id="26"/>
|
||||
</items>
|
||||
</navigationBar>
|
||||
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" image="ExceptionLogger.png" id="28">
|
||||
<rect key="frame" x="91" y="331" width="139" height="128"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
</imageView>
|
||||
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" id="CsP-Zy-WmE">
|
||||
<rect key="frame" x="10" y="59" width="298" height="264"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||
<textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
|
||||
</textView>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
|
||||
<simulatedStatusBarMetrics key="simulatedStatusBarMetrics"/>
|
||||
</view>
|
||||
</objects>
|
||||
<resources>
|
||||
<image name="ExceptionLogger.png" width="128" height="128"/>
|
||||
</resources>
|
||||
</document>
|
||||
Reference in New Issue
Block a user