Initial commit
This commit is contained in:
BIN
EonaCatTools/Tools/.DS_Store
vendored
Normal file
BIN
EonaCatTools/Tools/.DS_Store
vendored
Normal file
Binary file not shown.
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>
|
BIN
EonaCatTools/Tools/Lockscreen/.DS_Store
vendored
Normal file
BIN
EonaCatTools/Tools/Lockscreen/.DS_Store
vendored
Normal file
Binary file not shown.
@@ -0,0 +1,6 @@
|
||||
// Dutch language file
|
||||
|
||||
"Please wait" = "Een ogenblik geduld";
|
||||
"Decimal title" = "Alleen nummers";
|
||||
"Decimal message" = "Alleen nummers zijn toegestaan";
|
||||
"OK" = "OK";
|
@@ -0,0 +1,6 @@
|
||||
// English language file
|
||||
|
||||
"Please wait" = "Please wait";
|
||||
"Decimal title" = "Decimals only";
|
||||
"Decimal message" = "You can only insert decimals";
|
||||
"OK" = "OK";
|
73
EonaCatTools/Tools/Lockscreen/LockController.h
Normal file
73
EonaCatTools/Tools/Lockscreen/LockController.h
Normal 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
|
444
EonaCatTools/Tools/Lockscreen/LockController.m
Normal file
444
EonaCatTools/Tools/Lockscreen/LockController.m
Normal 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
BIN
EonaCatTools/Tools/Popup/.DS_Store
vendored
Normal file
Binary file not shown.
25
EonaCatTools/Tools/Popup/Popup.h
Normal file
25
EonaCatTools/Tools/Popup/Popup.h
Normal 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
|
83
EonaCatTools/Tools/Popup/Popup.m
Normal file
83
EonaCatTools/Tools/Popup/Popup.m
Normal 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
|
27
EonaCatTools/Tools/Toast/Toast.h
Normal file
27
EonaCatTools/Tools/Toast/Toast.h
Normal 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
|
375
EonaCatTools/Tools/Toast/Toast.m
Normal file
375
EonaCatTools/Tools/Toast/Toast.m
Normal 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
|
BIN
EonaCatTools/Tools/Toast/toast.wav
Normal file
BIN
EonaCatTools/Tools/Toast/toast.wav
Normal file
Binary file not shown.
21
EonaCatTools/Tools/uniqueIdentifier/DeviceIdentifier.h
Normal file
21
EonaCatTools/Tools/uniqueIdentifier/DeviceIdentifier.h
Normal 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
|
101
EonaCatTools/Tools/uniqueIdentifier/DeviceIdentifier.m
Normal file
101
EonaCatTools/Tools/uniqueIdentifier/DeviceIdentifier.m
Normal 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
|
13
EonaCatTools/Tools/uniqueIdentifier/SHA1.h
Normal file
13
EonaCatTools/Tools/uniqueIdentifier/SHA1.h
Normal 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
|
29
EonaCatTools/Tools/uniqueIdentifier/SHA1.m
Normal file
29
EonaCatTools/Tools/uniqueIdentifier/SHA1.m
Normal 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
|
Reference in New Issue
Block a user