Initial commit

This commit is contained in:
NightBits
2018-12-19 20:42:46 +01:00
parent 55baa9dae1
commit 0891cd8242
48 changed files with 3236 additions and 2 deletions

BIN
EonaCatTools/Tools/.DS_Store vendored Normal file

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,5 @@
// Dutch language file
"Back" = "Terug";
"Clear" = "Legen";
"Exceptions" = "Foutmeldingen";

View File

@@ -0,0 +1,5 @@
// English language file
"Back" = "Back";
"Clear" = "Clear";
"Exceptions" = "Exceptions";

View 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);

View 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;
}

View 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>

View 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

View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View 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>

BIN
EonaCatTools/Tools/Lockscreen/.DS_Store vendored Normal file

Binary file not shown.

View File

@@ -0,0 +1,6 @@
// Dutch language file
"Please wait" = "Een ogenblik geduld";
"Decimal title" = "Alleen nummers";
"Decimal message" = "Alleen nummers zijn toegestaan";
"OK" = "OK";

View File

@@ -0,0 +1,6 @@
// English language file
"Please wait" = "Please wait";
"Decimal title" = "Decimals only";
"Decimal message" = "You can only insert decimals";
"OK" = "OK";

View File

@@ -0,0 +1,73 @@
#import <UIKit/UIKit.h>
//
// LockController.h
// Created by EonaCat
// Copyright 2013 EonaCat. All rights reserved.
//
typedef enum
{
AUTHENTICATE,
SET
} STYLE;
@protocol LockControllerDelegate
@required
//- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
- (void)lockControllerDidFinish:(NSString*)passcode tag:(NSInteger)tag;
- (void)lockControllerIncorrectPassword:(NSString*)incorrectPassword tag:(NSInteger)tag;
- (void)lockControllerDidCancel:(NSInteger)tag;
@end
@interface LockController : UIViewController <UITextFieldDelegate>
{
//Public
STYLE style;
NSString *passcode;
NSString *givenPasscode;
NSString *title;
UILabel *promptLabel;
UILabel *subPromptLabel;
UILabel *hintLabel;
UIAlertView *alert;
int _deviceWidth;
id <LockControllerDelegate> __weak delegate;
BOOL hideCode;
//Private
BOOL _iPad;
BOOL retry;
NSMutableString *tempString;
UITextField *hiddenField;
UINavigationItem *navigationItem;
NSMutableArray *textFieldArray;
}
@property (nonatomic, weak) id delegate;
@property (nonatomic, copy) NSString *title;
@property (nonatomic) STYLE style;
@property (nonatomic, strong) UIColor *color;
@property (nonatomic, strong) UIColor *color2;
@property (nonatomic, strong) NSString *passcode;
@property (nonatomic, strong) NSString *prompt;
@property (nonatomic, strong) NSString *subPrompt;
@property (nonatomic, strong) NSString *hint;
@property (nonatomic, strong) NSString *correct;
@property (nonatomic) NSInteger tag;
@property (nonatomic) BOOL cancel;
@property (nonatomic) NSInteger fieldsAmount;
@property (nonatomic) BOOL hideCode;
@property (nonatomic) BOOL waitingAlert;
- (id)initWithTitle:(NSString*)newTitle prompt:(NSString*)newPrompt errorMessage:(NSString*)newSubPrompt correctMessage:(NSString*)newCorrectMessage passCode:(NSString*)newPasscode hint:(NSString*)newHint color:(UIColor*)newColor color2:(UIColor*)newColor2 fieldAmount:(NSInteger)newFieldAmount style:(STYLE)newStyle delegate:(id)newDelegate tag:(NSInteger)newTag cancelButton:(BOOL)cancelButton;
- (void)incorrect;
- (void)finished;
@end

View File

@@ -0,0 +1,444 @@
#import "LockController.h"
#import <QuartzCore/QuartzCore.h>
//
// LockController.m
// Created by EonaCat
// Copyright 2013 EonaCat. All rights reserved.
//
//private methods
@interface LockController()
- (void)setupSubviews;
- (void)setupNavigationBar;
- (void)setupTextFields;
- (void)resetFields;
- (void)passcodeDidNotMatch:(NSString*)incorrectPassword;
- (void)dissmissView;
@property (nonatomic, strong) NSMutableString *tempString;
@property (nonatomic, strong) UITextField *hiddenField;
@property (nonatomic, strong) UINavigationItem *navigationItem;
@end
@implementation LockController
@synthesize delegate;
@synthesize style;
@synthesize passcode;
@synthesize prompt;
@synthesize subPrompt;
@synthesize hint;
@synthesize hiddenField;
@synthesize navigationItem;
@synthesize tempString;
@synthesize title;
@synthesize hideCode;
@synthesize waitingAlert;
- (id)initWithTitle:(NSString*)newTitle prompt:(NSString*)newPrompt errorMessage:(NSString*)newSubPrompt correctMessage:(NSString*)newCorrectMessage passCode:(NSString*)newPasscode hint:(NSString*)newHint color:(UIColor*)newColor color2:(UIColor*)newColor2 fieldAmount:(NSInteger)newFieldAmount style:(STYLE)newStyle delegate:(id)newDelegate tag:(NSInteger)newTag cancelButton:(BOOL)cancelButton
{
if (self = [super init])
{
_iPad = UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad;
if (_iPad)
{
_deviceWidth = 768;
}
else
{
_deviceWidth = 320;
}
newTitle == nil ? [NSString stringWithFormat:@"Security"] : newTitle;
newPrompt == nil ? [NSString stringWithFormat:@"Insert pincode"] : newPrompt;
newSubPrompt == nil ? [NSString stringWithFormat:@"Invalid code"] : newSubPrompt;
newHint == nil ? [NSString stringWithFormat:@"As a security you need to supply a pincode"] : newHint;
newColor == nil ? [UIColor whiteColor] : newColor;
newColor2 == nil ? [UIColor whiteColor] : newColor2;
//newFieldAmount == 0 ? 4 : newFieldAmount;
newCorrectMessage == nil ? [NSString stringWithFormat:@"Code is valid"] : newCorrectMessage;
newPasscode == nil ? [NSString stringWithFormat:@"0000"] : newCorrectMessage;
self.cancel = cancelButton;
self.tag = newTag;
self.title = newTitle;
self.prompt = newPrompt;
self.subPrompt = newSubPrompt;
self.hint = newHint;
self.color = newColor;
self.color2 = newColor2;
self.correct = newCorrectMessage;
self.passcode = newPasscode;
self.style = newStyle;
self.fieldsAmount = newFieldAmount;
self.delegate = newDelegate;
self.tempString = [NSMutableString string];
self.hideCode = true;
self.waitingAlert = false;
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
//needs a delegate
assert (delegate != nil);
//check if passcode is set for AUTHENTICATION
if (style == AUTHENTICATE)
{
assert (passcode != nil);
}
[self setupSubviews];
}
-(void)handleSingleTap:(UITapGestureRecognizer *)sender
{
[alert dismissWithClickedButtonIndex:0 animated:YES];
}
- (void)setupSubviews
{
self.view.backgroundColor = [UIColor groupTableViewBackgroundColor];
if (self.waitingAlert)
{
//Alert
alert = [[UIAlertView alloc] initWithTitle:NSLocalizedStringFromTable(@"Status", @"LockController", @"Status")
message:NSLocalizedStringFromTable(@"Please wait", @"LockController", @"Please wait")
delegate:self
cancelButtonTitle:nil
otherButtonTitles:nil, nil];
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap:)];
[alert addGestureRecognizer:singleTap];
}
//main prompt
promptLabel = [[UILabel alloc]initWithFrame:CGRectMake(0, 70, _deviceWidth, 25)];
promptLabel.textAlignment = NSTextAlignmentCenter;
promptLabel.backgroundColor = [UIColor clearColor];
promptLabel.shadowColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:.50];
promptLabel.font = [UIFont systemFontOfSize:[UIFont labelFontSize]];
promptLabel.shadowOffset = CGSizeMake(0, -0.75);
promptLabel.textColor = [UIColor blackColor];
promptLabel.text = prompt;
[self.view addSubview:promptLabel];
//subPrompt
subPromptLabel = [[UILabel alloc]initWithFrame:CGRectMake(0, 90, _deviceWidth, 25)];
subPromptLabel.textAlignment = NSTextAlignmentCenter;
subPromptLabel.backgroundColor = [UIColor clearColor];
subPromptLabel.textColor = [UIColor redColor];
subPromptLabel.font = [UIFont systemFontOfSize:14];
subPromptLabel.text = subPrompt;
subPromptLabel.hidden = true;
[self.view addSubview:subPromptLabel];
// hint
hintLabel = [[UILabel alloc]initWithFrame:CGRectMake(0, 160, _deviceWidth, 100)];
hintLabel.textAlignment = NSTextAlignmentCenter;
hintLabel.backgroundColor = [UIColor clearColor];
hintLabel.shadowColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:.50];
hintLabel.font = [UIFont systemFontOfSize:14];
hintLabel.shadowOffset = CGSizeMake(0, -0.75);
hintLabel.numberOfLines = 2;
hintLabel.textColor = [UIColor blackColor];
hintLabel.text = hint;
[self.view addSubview:hintLabel];
//bar
[self setupNavigationBar];
//text fields
[self setupTextFields];
}
- (void)setupNavigationBar
{
UINavigationBar *navBar;
navBar = [[UINavigationBar alloc]initWithFrame:CGRectMake(0,0,_deviceWidth,50)];
navBar.barStyle = UIBarStyleBlack;
[self.view addSubview:navBar];
navigationItem = [[UINavigationItem alloc]init];
if (self.cancel)
{
[navigationItem setRightBarButtonItem:[[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemCancel
target:self
action:@selector(userDidCancel:)]
animated:NO];
}
[navBar pushNavigationItem:navigationItem animated:NO];
navigationItem.title = title;
if (self.color)
{
CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.frame = self.view.bounds;
gradient.colors = @[(id)[self.color CGColor], (id)[self.color2 CGColor],(id)[self.color CGColor], (id)[self.color CGColor]];
[self.view.layer insertSublayer:gradient atIndex:0];
if ([[[UIDevice currentDevice] systemVersion] floatValue] < 7.0)
{
[navBar setTintColor:self.color];
}
else
{
[navBar setBarTintColor:self.color];
}
}
}
- (void)setupTextFields
{
int toppadding;
int leftpadding;
int width;
int height;
int padding;
CGFloat fontsize;
if (_iPad)
{
if (_fieldsAmount == 4)
{
leftpadding = 150;
}
else
{
leftpadding = 130;
}
width = 100;
height = 100;
toppadding = 250;
padding = 60;
fontsize = 64;
}
else
{
if (_fieldsAmount == 4)
{
leftpadding = 40;
}
else
{
leftpadding = 20;
}
width = 50;
height = 50;
toppadding = 125;
padding = 30;
fontsize = 32;
}
// Initialise the textField array
textFieldArray = [NSMutableArray array];
for (int i = 0; i < self.fieldsAmount; i++)
{
UITextField *textField;
textField = [[UITextField alloc]initWithFrame:CGRectMake(leftpadding + width*i + padding,toppadding,width,height)];
textField.backgroundColor = [UIColor whiteColor];
textField.borderStyle = UITextBorderStyleBezel;
textField.secureTextEntry = self.hideCode;
textField.font = [UIFont systemFontOfSize:fontsize];
textField.textAlignment = NSTextAlignmentCenter;
textField.tag = i;
textField.enabled = false;
[self.view addSubview:textField];
[textFieldArray addObject:textField];
}
hiddenField = [[UITextField alloc]initWithFrame:CGRectMake(0,0,500,500)];
hiddenField.text = @"";
hiddenField.keyboardType = UIKeyboardTypeNumberPad;
hiddenField.keyboardAppearance = UIKeyboardAppearanceAlert;
hiddenField.delegate = self;
hiddenField.hidden = true;
[hiddenField becomeFirstResponder];
[self.view setBackgroundColor:[UIColor whiteColor]];
[self.view addSubview:hiddenField];
}
-(BOOL)checkDecimal:(NSString *)string
{
NSNumberFormatter *numberFormat = [[NSNumberFormatter alloc] init];
BOOL isDecimal = [numberFormat numberFromString:string] != nil;
if (!isDecimal)
{
UIAlertView * decimalAlert = [[UIAlertView alloc] initWithTitle:NSLocalizedStringFromTable(@"Decimal title", @"LockController", @"Decimal title")
message:NSLocalizedStringFromTable(@"Decimal message", @"LockController", @"Decimal message")
delegate:self
cancelButtonTitle:@"OK"
otherButtonTitles:nil, nil];
[decimalAlert show];
}
return isDecimal;
}
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
@try
{
if ([string isEqualToString:@""] || [self checkDecimal:string])
{
UITextField *currentTextField;
// Check if the backSpace was pressed
if ([string isEqualToString:@""])
{
[self.tempString setString:[self.tempString substringToIndex:[self.tempString length]-1]];
currentTextField = textFieldArray[[self.tempString length]];
}
else
{
[self.tempString appendString:string];
currentTextField = textFieldArray[[self.tempString length] -1];
}
currentTextField.text = string;
// we have reached the maximum characters
if ([self.tempString length] == [textFieldArray count])
{
if (self.style == SET)
{
if (passcode == nil)
{
//empty tempstring to passcode string
passcode = [self.tempString copy];
self.tempString = [NSMutableString string];
//reset fields
[self resetFields];
textField.text = @"";
}
else
{
//check if confirm matches first
givenPasscode = [self.tempString copy];
if ([passcode isEqualToString:self.tempString])
{
subPromptLabel.textColor = [UIColor greenColor];
subPromptLabel.text = self.correct;
[delegate lockControllerDidFinish:givenPasscode tag:self.tag];
[self dissmissView];
}
else
{
[self passcodeDidNotMatch:givenPasscode];
}
}
}
else if(self.style == AUTHENTICATE)
{
givenPasscode = [self.tempString copy];
if ([passcode isEqualToString:self.tempString])
{
subPromptLabel.textColor = [UIColor greenColor];
subPromptLabel.text = self.correct;
[delegate lockControllerDidFinish:givenPasscode tag:self.tag];
[self dissmissView];
}
else
{
[self passcodeDidNotMatch:givenPasscode];
}
return false;
}
}
return true;
}
return false;
}
@catch (NSException *exception)
{
// Do nothing
}
}
- (void)passcodeDidNotMatch:(NSString*)incorrectPassword
{
if (self.waitingAlert)
{
[alert show];
}
self.tempString = [NSMutableString string];
subPromptLabel.textColor = [UIColor redColor];
subPromptLabel.text = self.subPrompt;
subPromptLabel.hidden = false;
[self resetFields];
[delegate lockControllerIncorrectPassword:incorrectPassword tag:self.tag];
}
- (void)resetFields
{
for (UITextField *textField in textFieldArray)
{
textField.text = @"";
}
hiddenField.text = @"";
}
- (void)incorrect
{
if (self.waitingAlert)
{
[alert dismissWithClickedButtonIndex:0 animated:true];
}
}
- (void)finished
{
if (self.waitingAlert)
{
[alert dismissWithClickedButtonIndex:0 animated:true];
}
subPromptLabel.textColor = [UIColor greenColor];
subPromptLabel.text = self.correct;
}
- (void)dissmissView
{
[self dismissViewControllerAnimated:TRUE completion:nil];
}
- (void)userDidCancel:(id)sender
{
[delegate lockControllerDidCancel:self.tag];
[self dissmissView];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
@end

BIN
EonaCatTools/Tools/Popup/.DS_Store vendored Normal file

Binary file not shown.

View File

@@ -0,0 +1,25 @@
//
// Popup.h
// Created by EonaCat
// Copyright 2013 EonaCat. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface Popup : NSObject
{
NSTimer *_notificationTimer;
UILabel *_target;
UIColor *_targetOldBackgroundColor;
UIColor *_targetOldTextColor;
NSString *_targetText;
UIAlertView *_alert;
}
-(void)showAlert:(NSString*)title message:(NSString*)message delegate:(id)delegate cancelButtonText:(NSString*)cancelButtonText otherButtonText:(NSString*)otherButtonText tag:(NSInteger)tag;
-(void)showDebugNotification:(NSString*)message textColor:(UIColor*)textColor backgroundColor:(UIColor*)backgroundColor target:(UILabel*)target;
-(void)dismiss;
+ (id)getInstance;
@end

View File

@@ -0,0 +1,83 @@
//
// Popup.m
// Created by EonaCat
// Copyright 2013 EonaCat. All rights reserved.
//
#import "Popup.h"
@implementation Popup
static Popup *_instance;
+ (id)getInstance
{
@synchronized(self)
{
if (_instance == nil)
{
_instance = [[self alloc] init];
}
}
return _instance;
}
-(void)showAlert:(NSString *)title message:(NSString *)message delegate:(id)delegate cancelButtonText:(NSString *)cancelButtonText otherButtonText:(NSString *)otherButtonText tag:(NSInteger)tag
{
_alert = [[UIAlertView alloc] initWithTitle:title
message:message
delegate:delegate
cancelButtonTitle:[cancelButtonText length] == 0 ? nil : cancelButtonText
otherButtonTitles:[otherButtonText length] == 0 ? nil : otherButtonText,nil];
_alert.tag = tag;
[_alert show];
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap:)];
[_alert addGestureRecognizer:singleTap];
}
-(void)handleSingleTap:(UITapGestureRecognizer *)sender
{
[_alert dismissWithClickedButtonIndex:0 animated:YES];
}
-(void)dismiss
{
[_alert dismissWithClickedButtonIndex:0 animated:true];
}
-(void)showDebugNotification:(NSString *)message textColor:(UIColor *)textColor backgroundColor:(UIColor *)backgroundColor target:(UILabel *)target
{
_target = target;
_targetOldBackgroundColor = target.backgroundColor;
_targetOldTextColor = target.textColor;
_targetText = target.text;
target.textColor = textColor;
target.backgroundColor = backgroundColor;
target.text = message;
_notificationTimer = [NSTimer scheduledTimerWithTimeInterval:10 target:self selector:@selector(debugNotificationTimeElapsed:) userInfo:nil repeats:NO];
}
- (void)debugNotificationTimeElapsed:(NSTimer*)timer
{
@try
{
UILabel *target = _target;
target.backgroundColor = _targetOldBackgroundColor;
target.textColor = _targetOldTextColor;
target.text = _targetText;
[_notificationTimer invalidate];
}
@catch (NSException *exception)
{
NSLog(@"DebugNotificationError: %@",exception.description);
}
}
@end

View File

@@ -0,0 +1,27 @@
//
// Toast.h
// Created by EonaCat
// Copyright 2013 EonaCat. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface UIView (Toast)
// each makeToast method creates a view and displays it as toast
- (void)makeToast:(NSString *)message;
- (void)makeToast:(NSString *)message duration:(CGFloat)interval position:(id)position;
- (void)makeToast:(NSString *)message duration:(CGFloat)interval position:(id)position title:(NSString *)title;
- (void)makeToast:(NSString *)message duration:(CGFloat)interval position:(id)position title:(NSString *)title image:(UIImage *)image;
- (void)makeToast:(NSString *)message duration:(CGFloat)interval position:(id)position image:(UIImage *)image;
// displays toast with an activity spinner
- (void)makeToastActivity;
- (void)makeToastActivity:(id)position;
- (void)hideToastActivity;
// the showToast methods display any view as toast
- (void)showToast:(UIView *)toast;
- (void)showToast:(UIView *)toast duration:(CGFloat)interval position:(id)point;
@end

View File

@@ -0,0 +1,375 @@
//
// Toast.m
// Created by EonaCat
// Copyright 2013 EonaCat. All rights reserved.
//
#import "Toast.h"
#import <QuartzCore/QuartzCore.h>
#import <AudioToolbox/AudioToolbox.h>
#import <objc/runtime.h>
#define kMaxWidth 0.8
#define kMaxHeight 0.8
#define kHorizontalPadding 10.0
#define kVerticalPadding 10.0
#define kCornerRadius 10.0
#define kOpacity 0.8
#define kFontSize 16.0
#define kMaxTitleLines 999
#define kMaxMessageLines 999
#define kFadeDuration 0.2
#define kDisplayShadow YES
#define kDefaultLength 3.0
#define kDefaultPosition @"bottom"
#define kImageWidth 80.0
#define kImageHeight 80.0
#define kActivityWidth 100.0
#define kActivityHeight 100.0
#define kActivityDefaultPosition @"center"
#define kActivityTag 91325
static NSString *kDurationKey = @"CSToastDurationKey";
@interface UIView (ToastPrivate)
- (CGPoint)getPositionFor:(id)position toast:(UIView *)toast;
- (UIView *)makeViewForMessage:(NSString *)message title:(NSString *)title image:(UIImage *)image;
@end
@implementation UIView (Toast)
#pragma mark - Toast Methods
- (void)makeToast:(NSString *)message {
[self makeToast:message duration:kDefaultLength position:kDefaultPosition];
}
- (void)makeToast:(NSString *)message duration:(CGFloat)interval position:(id)position {
UIView *toast = [self makeViewForMessage:message title:nil image:nil];
[self showToast:toast duration:interval position:position];
}
- (void)makeToast:(NSString *)message duration:(CGFloat)interval position:(id)position title:(NSString *)title {
UIView *toast = [self makeViewForMessage:message title:title image:nil];
[self showToast:toast duration:interval position:position];
}
- (void)makeToast:(NSString *)message duration:(CGFloat)interval position:(id)position image:(UIImage *)image {
UIView *toast = [self makeViewForMessage:message title:nil image:image];
[self showToast:toast duration:interval position:position];
}
- (void)makeToast:(NSString *)message duration:(CGFloat)interval position:(id)position title:(NSString *)title image:(UIImage *)image {
UIView *toast = [self makeViewForMessage:message title:title image:image];
[self showToast:toast duration:interval position:position];
}
- (void)showToast:(UIView *)toast {
[self showToast:toast duration:kDefaultLength position:kDefaultPosition];
}
- (void)showToast:(UIView *)toast duration:(CGFloat)interval position:(id)point {
// Display a view for a given duration & position.
CGPoint toastPoint = [self getPositionFor:point toast:toast];
// use an associative reference to associate the toast view with the display interval
objc_setAssociatedObject (toast, &kDurationKey, [NSNumber numberWithFloat:interval], OBJC_ASSOCIATION_RETAIN);
[toast setCenter:toastPoint];
[toast setAlpha:0.0];
[self addSubview:toast];
#if !__has_feature(objc_arc)
[UIView beginAnimations:@"fade_in" context:toast];
#else
[UIView beginAnimations:@"fade_in" context:(__bridge void*)toast];
#endif
[UIView setAnimationDuration:kFadeDuration];
SystemSoundID mySound = [self createSoundID: @"toast.wav"];
AudioServicesPlaySystemSound(mySound);
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:@selector(animationDidStop:finished:context:)];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
[toast setAlpha:1.0];
[UIView commitAnimations];
}
-(SystemSoundID) createSoundID: (NSString*)name
{
NSString *path = [NSString stringWithFormat: @"%@/%@",
[[NSBundle mainBundle] resourcePath], name];
NSURL* filePath = [NSURL fileURLWithPath: path isDirectory: NO];
SystemSoundID soundID;
AudioServicesCreateSystemSoundID((__bridge CFURLRef)filePath, &soundID);
NSLog(@"%@, %@", path, filePath);
return soundID;
}
#pragma mark - Toast Activity Methods
- (void)makeToastActivity {
[self makeToastActivity:kActivityDefaultPosition];
}
- (void)makeToastActivity:(id)position {
// prevent more than one activity view
UIView *existingToast = [self viewWithTag:kActivityTag];
if (existingToast != nil) {
[existingToast removeFromSuperview];
}
UIView *activityContainer = [[UIView alloc] initWithFrame:CGRectMake(0, 0, kActivityWidth, kActivityHeight)];
#if !__has_feature(objc_arc)
[activityContainer autorelease];
#endif
[activityContainer setCenter:[self getPositionFor:position toast:activityContainer]];
[activityContainer setBackgroundColor:[[UIColor blackColor] colorWithAlphaComponent:kOpacity]];
[activityContainer setAlpha:0.0];
[activityContainer setTag:kActivityTag];
[activityContainer setAutoresizingMask:(UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin)];
[activityContainer.layer setCornerRadius:kCornerRadius];
if (kDisplayShadow) {
[activityContainer.layer setShadowColor:[UIColor blackColor].CGColor];
[activityContainer.layer setShadowOpacity:0.8];
[activityContainer.layer setShadowRadius:6.0];
[activityContainer.layer setShadowOffset:CGSizeMake(4.0, 4.0)];
}
UIActivityIndicatorView *activityView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
#if !__has_feature(objc_arc)
[activityView autorelease];
#endif
[activityView setCenter:CGPointMake(activityContainer.bounds.size.width / 2, activityContainer.bounds.size.height / 2)];
[activityContainer addSubview:activityView];
[activityView startAnimating];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:kFadeDuration];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
[activityContainer setAlpha:1.0];
[UIView commitAnimations];
[self addSubview:activityContainer];
}
- (void)hideToastActivity {
UIView *existingToast = [self viewWithTag:kActivityTag];
if (existingToast != nil) {
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:kFadeDuration];
[UIView setAnimationDelegate:existingToast];
[UIView setAnimationDidStopSelector:@selector(removeFromSuperview)];
[UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
[existingToast setAlpha:0.0];
[UIView commitAnimations];
}
}
#pragma mark - Animation Delegate Method
- (void)animationDidStop:(NSString*)animationID finished:(BOOL)finished context:(void *)context {
#if !__has_feature(objc_arc)
UIView *toast = (UIView *)context;
#else
UIView *toast = (UIView *)(__bridge id)context;
#endif
// retrieve the display interval associated with the view
CGFloat interval = [(NSNumber *)objc_getAssociatedObject(toast, &kDurationKey) floatValue];
if([animationID isEqualToString:@"fade_in"]) {
#if !__has_feature(objc_arc)
[UIView beginAnimations:@"fade_out" context:toast];
#else
[UIView beginAnimations:@"fade_out" context:(__bridge void*)toast];
#endif
[UIView setAnimationDelay:interval];
[UIView setAnimationDuration:kFadeDuration];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:@selector(animationDidStop:finished:context:)];
[UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
[toast setAlpha:0.0];
[UIView commitAnimations];
} else if ([animationID isEqualToString:@"fade_out"]) {
[toast removeFromSuperview];
}
}
#pragma mark - Private Methods
- (CGPoint)getPositionFor:(id)point toast:(UIView *)toast {
// Convert string literals @"top", @"bottom", @"center", or any point wrapped in an
// NSValue object into a CGPoint
if([point isKindOfClass:[NSString class]]) {
if( [point caseInsensitiveCompare:@"top"] == NSOrderedSame ) {
return CGPointMake(self.bounds.size.width/2, (toast.frame.size.height / 2) + kVerticalPadding);
} else if( [point caseInsensitiveCompare:@"bottom"] == NSOrderedSame ) {
return CGPointMake(self.bounds.size.width/2, (self.bounds.size.height - (toast.frame.size.height / 2)) - kVerticalPadding);
} else if( [point caseInsensitiveCompare:@"center"] == NSOrderedSame ) {
return CGPointMake(self.bounds.size.width / 2, self.bounds.size.height / 2);
}
} else if ([point isKindOfClass:[NSValue class]]) {
return [point CGPointValue];
}
NSLog(@"Error: Invalid position for toast.");
return [self getPositionFor:kDefaultPosition toast:toast];
}
- (UIView *)makeViewForMessage:(NSString *)message title:(NSString *)title image:(UIImage *)image {
// sanity
if((message == nil) && (title == nil) && (image == nil)) return nil;
// Dynamically build a toast view with any combination of message, title, & image.
UILabel *messageLabel = nil;
UILabel *titleLabel = nil;
UIImageView *imageView = nil;
// create the parent view
UIView *wrapperView = [[UIView alloc] init];
#if !__has_feature(objc_arc)
[wrapperView autorelease];
#endif
[wrapperView setAutoresizingMask:(UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin)];
[wrapperView.layer setCornerRadius:kCornerRadius];
if (kDisplayShadow) {
[wrapperView.layer setShadowColor:[UIColor blackColor].CGColor];
[wrapperView.layer setShadowOpacity:0.8];
[wrapperView.layer setShadowRadius:6.0];
[wrapperView.layer setShadowOffset:CGSizeMake(4.0, 4.0)];
}
[wrapperView setBackgroundColor:[[UIColor blackColor] colorWithAlphaComponent:kOpacity]];
if(image != nil) {
imageView = [[UIImageView alloc] initWithImage:image];
#if !__has_feature(objc_arc)
[imageView autorelease];
#endif
[imageView setContentMode:UIViewContentModeScaleAspectFit];
[imageView setFrame:CGRectMake(kHorizontalPadding, kVerticalPadding, kImageWidth, kImageHeight)];
}
CGFloat imageWidth, imageHeight, imageLeft;
// the imageView frame values will be used to size & position the other views
if(imageView != nil) {
imageWidth = imageView.bounds.size.width;
imageHeight = imageView.bounds.size.height;
imageLeft = kHorizontalPadding;
} else {
imageWidth = imageHeight = imageLeft = 0.0;
}
if (title != nil) {
titleLabel = [[UILabel alloc] init];
#if !__has_feature(objc_arc)
[titleLabel autorelease];
#endif
[titleLabel setNumberOfLines:kMaxTitleLines];
[titleLabel setFont:[UIFont boldSystemFontOfSize:kFontSize]];
[titleLabel setTextAlignment:NSTextAlignmentLeft];
[titleLabel setLineBreakMode:NSLineBreakByWordWrapping];
[titleLabel setTextColor:[UIColor whiteColor]];
[titleLabel setBackgroundColor:[UIColor clearColor]];
[titleLabel setAlpha:1.0];
[titleLabel setText:title];
// size the title label according to the length of the text
CGSize maxSizeTitle = CGSizeMake((self.bounds.size.width * kMaxWidth) - imageWidth, self.bounds.size.height * kMaxHeight);
CGSize expectedSizeTitle = [title sizeWithFont:titleLabel.font constrainedToSize:maxSizeTitle lineBreakMode:titleLabel.lineBreakMode];
[titleLabel setFrame:CGRectMake(0.0, 0.0, expectedSizeTitle.width, expectedSizeTitle.height)];
}
if (message != nil) {
messageLabel = [[UILabel alloc] init];
#if !__has_feature(objc_arc)
[messageLabel autorelease];
#endif
[messageLabel setNumberOfLines:kMaxMessageLines];
[messageLabel setFont:[UIFont systemFontOfSize:kFontSize]];
[messageLabel setLineBreakMode:NSLineBreakByWordWrapping];
[messageLabel setTextColor:[UIColor whiteColor]];
[messageLabel setBackgroundColor:[UIColor clearColor]];
[messageLabel setAlpha:1.0];
[messageLabel setText:message];
// size the message label according to the length of the text
CGSize maxSizeMessage = CGSizeMake((self.bounds.size.width * kMaxWidth) - imageWidth, self.bounds.size.height * kMaxHeight);
CGSize expectedSizeMessage = [message sizeWithFont:messageLabel.font constrainedToSize:maxSizeMessage lineBreakMode:messageLabel.lineBreakMode];
[messageLabel setFrame:CGRectMake(0.0, 0.0, expectedSizeMessage.width, expectedSizeMessage.height)];
}
// titleLabel frame values
CGFloat titleWidth, titleHeight, titleTop, titleLeft;
if(titleLabel != nil) {
titleWidth = titleLabel.bounds.size.width;
titleHeight = titleLabel.bounds.size.height;
titleTop = kVerticalPadding;
titleLeft = imageLeft + imageWidth + kHorizontalPadding;
} else {
titleWidth = titleHeight = titleTop = titleLeft = 0.0;
}
// messageLabel frame values
CGFloat messageWidth, messageHeight, messageLeft, messageTop;
if(messageLabel != nil) {
messageWidth = messageLabel.bounds.size.width;
messageHeight = messageLabel.bounds.size.height;
messageLeft = imageLeft + imageWidth + kHorizontalPadding;
messageTop = titleTop + titleHeight + kVerticalPadding;
} else {
messageWidth = messageHeight = messageLeft = messageTop = 0.0;
}
CGFloat longerWidth = MAX(titleWidth, messageWidth);
CGFloat longerLeft = MAX(titleLeft, messageLeft);
// wrapper width uses the longerWidth or the image width, whatever is larger. same logic applies to the wrapper height
CGFloat wrapperWidth = MAX((imageWidth + (kHorizontalPadding * 2)), (longerLeft + longerWidth + kHorizontalPadding));
CGFloat wrapperHeight = MAX((messageTop + messageHeight + kVerticalPadding), (imageHeight + (kVerticalPadding * 2)));
[wrapperView setFrame:CGRectMake(0.0, 0.0, wrapperWidth, wrapperHeight)];
if(titleLabel != nil) {
[titleLabel setFrame:CGRectMake(titleLeft, titleTop, titleWidth, titleHeight)];
[wrapperView addSubview:titleLabel];
}
if(messageLabel != nil) {
[messageLabel setFrame:CGRectMake(messageLeft, messageTop, messageWidth, messageHeight)];
[wrapperView addSubview:messageLabel];
}
if(imageView != nil) {
[wrapperView addSubview:imageView];
}
return wrapperView;
}
@end

Binary file not shown.

View File

@@ -0,0 +1,21 @@
//
// DeviceIdentifier.h
// Created by EonaCat
// Copyright 2013 EonaCat. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface UIDevice (IdentifierAddition)
// Generate a sha1 hash of your MAC address with your bundle app identifier
- (NSString*) appIdentifier;
// Generate a sha1 hash of your MAC address
- (NSString*) deviceIdentifier;
// Get the MAC address
- (NSString*) macAddress;
@end

View File

@@ -0,0 +1,101 @@
//
// DeviceIdentifier.m
// Created by EonaCat
// Copyright 2013 EonaCat. All rights reserved.
//
#import "DeviceIdentifier.h"
#import "SHA1.h"
#include <sys/socket.h>
#include <sys/sysctl.h>
#include <net/if.h>
#include <net/if_dl.h>
@interface UIDevice(Private)
- (NSString*) macaddress;
@end
@implementation UIDevice (IdentifierAddition)
// Get the local macaddress
- (NSString*) macaddress
{
int mib[6];
size_t len;
char *buf;
unsigned char *ptr;
struct if_msghdr *ifm;
struct sockaddr_dl *sdl;
mib[0] = CTL_NET;
mib[1] = AF_ROUTE;
mib[2] = 0;
mib[3] = AF_LINK;
mib[4] = NET_RT_IFLIST;
if ((mib[5] = if_nametoindex("en0")) == 0)
{
printf("Error: if_nametoindex error\n");
return NULL;
}
if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0)
{
printf("Error: sysctl, take 1\n");
return NULL;
}
if ((buf = malloc(len)) == NULL)
{
printf("Could not allocate memory. error!\n");
return NULL;
}
if (sysctl(mib, 6, buf, &len, NULL, 0) < 0)
{
printf("Error: sysctl, take 2");
free(buf);
return NULL;
}
ifm = (struct if_msghdr *)buf;
sdl = (struct sockaddr_dl *)(ifm + 1);
ptr = (unsigned char *)LLADDR(sdl);
NSString *outstring = [NSString stringWithFormat:@"%02X:%02X:%02X:%02X:%02X:%02X",
*ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4), *(ptr+5)];
free(buf);
return outstring;
}
// Get the appIdentifier
- (NSString*) appIdentifier
{
NSString *macaddress = [[UIDevice currentDevice] macaddress];
NSString *bundleIdentifier = [[NSBundle mainBundle] bundleIdentifier];
NSString *stringToHash = [NSString stringWithFormat:@"%@%@",macaddress,bundleIdentifier];
NSString *uniqueIdentifier = [stringToHash stringFromSHA1:stringToHash];
return uniqueIdentifier;
}
// Get the deviceIdentifier
- (NSString*) deviceIdentifier
{
NSString *macaddress = [[UIDevice currentDevice] macaddress];
NSString *uniqueIdentifier = [macaddress stringFromSHA1:macaddress];
return uniqueIdentifier;
}
// Get the macAddress
- (NSString*) macAddress
{
return [[UIDevice currentDevice] macaddress];
}
@end

View File

@@ -0,0 +1,13 @@
//
// SHA1.h
// Created by EonaCat
// Copyright 2013 EonaCat. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface NSString(SHA1)
-(NSString*) stringFromSHA1:(NSString*)input;
@end

View File

@@ -0,0 +1,29 @@
//
// SHA1.m
// Created by EonaCat
// Copyright 2013 EonaCat. All rights reserved.
//
#import "SHA1.h"
#import <CommonCrypto/CommonDigest.h>
@implementation NSString(SHA1)
-(NSString*) stringFromSHA1:(NSString*)input
{
const char *charString = [input cStringUsingEncoding:NSUTF8StringEncoding];
NSData *data = [NSData dataWithBytes:charString length:input.length];
uint8_t digest[CC_SHA1_DIGEST_LENGTH];
CC_SHA1(data.bytes, data.length, digest);
NSMutableString *output = [NSMutableString stringWithCapacity:CC_SHA1_DIGEST_LENGTH * 2];
for (int i = 0; i < CC_SHA1_DIGEST_LENGTH; i++)
{
[output appendFormat:@"%02x", digest[i]];
}
return output;
}
@end