├── .gitignore ├── GetexceptionalAPI ├── GetexceptionalAPI.xcodeproj │ ├── colins.mode1v3 │ ├── colins.pbxuser │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcuserdata │ │ │ └── colins.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── xcuserdata │ │ └── colins.xcuserdatad │ │ └── xcschemes │ │ ├── GetexceptionalAPI.xcscheme │ │ └── xcschememanagement.plist ├── GetexceptionalAPI │ ├── GetexceptionalAPI-Info.plist │ ├── GetexceptionalAPI-Prefix.pch │ ├── GetexceptionalAPI │ │ ├── GTExceptionalAPI.h │ │ ├── GTExceptionalAPI.m │ │ ├── GTExceptionalDeviceInfo.h │ │ ├── GTExceptionalDeviceInfo.m │ │ ├── GTExceptionalMessage.h │ │ ├── GTExceptionalMessage.m │ │ └── exceptional.plist │ ├── GetexceptionalAPIAppDelegate.h │ ├── GetexceptionalAPIAppDelegate.m │ ├── en.lproj │ │ ├── InfoPlist.strings │ │ └── MainWindow.xib │ ├── external │ │ ├── ISO-8601-parser-0.5 │ │ │ ├── ISO8601DateFormatter.h │ │ │ ├── ISO8601DateFormatter.m │ │ │ ├── LICENSE.txt │ │ │ └── README.txt │ │ ├── Reachability.h │ │ ├── Reachability.m │ │ ├── asi-http-request │ │ │ ├── ASIAuthenticationDialog.h │ │ │ ├── ASIAuthenticationDialog.m │ │ │ ├── ASICacheDelegate.h │ │ │ ├── ASIDataCompressor.h │ │ │ ├── ASIDataCompressor.m │ │ │ ├── ASIDataDecompressor.h │ │ │ ├── ASIDataDecompressor.m │ │ │ ├── ASIDownloadCache.h │ │ │ ├── ASIDownloadCache.m │ │ │ ├── ASIFormDataRequest.h │ │ │ ├── ASIFormDataRequest.m │ │ │ ├── ASIHTTPRequest.h │ │ │ ├── ASIHTTPRequest.m │ │ │ ├── ASIHTTPRequestConfig.h │ │ │ ├── ASIHTTPRequestDelegate.h │ │ │ ├── ASIInputStream.h │ │ │ ├── ASIInputStream.m │ │ │ ├── ASINetworkQueue.h │ │ │ ├── ASINetworkQueue.m │ │ │ └── ASIProgressDelegate.h │ │ └── json_framework_2.3 │ │ │ ├── JSON.h │ │ │ ├── NSObject+SBJSON.h │ │ │ ├── NSObject+SBJSON.m │ │ │ ├── NSString+SBJSON.h │ │ │ ├── NSString+SBJSON.m │ │ │ ├── SBJsonBase.h │ │ │ ├── SBJsonBase.m │ │ │ ├── SBJsonParser.h │ │ │ ├── SBJsonParser.m │ │ │ ├── SBJsonWriter.h │ │ │ └── SBJsonWriter.m │ └── main.m └── GetexceptionalAPITests │ ├── GetexceptionalAPITests-Info.plist │ ├── GetexceptionalAPITests-Prefix.pch │ ├── GetexceptionalAPITests.h │ ├── GetexceptionalAPITests.m │ └── en.lproj │ └── InfoPlist.strings ├── README.md └── TestApps └── iPhoneTestApp ├── iPhoneTestApp.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcuserdata │ │ └── colins.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ └── colins.xcuserdatad │ └── xcschemes │ ├── iPhoneTestApp.xcscheme │ └── xcschememanagement.plist ├── iPhoneTestApp ├── en.lproj │ ├── InfoPlist.strings │ └── MainWindow.xib ├── iPhoneTestApp-Info.plist ├── iPhoneTestApp-Prefix.pch ├── iPhoneTestAppAppDelegate.h ├── iPhoneTestAppAppDelegate.m └── main.m └── iPhoneTestAppTests ├── en.lproj └── InfoPlist.strings ├── iPhoneTestAppTests-Info.plist ├── iPhoneTestAppTests-Prefix.pch ├── iPhoneTestAppTests.h └── iPhoneTestAppTests.m /.gitignore: -------------------------------------------------------------------------------- 1 | # xcode noise 2 | build/* 3 | *.pbxuser 4 | *.mode1v3 5 | 6 | # old skool 7 | .svn 8 | 9 | # osx noise 10 | .DS_Store 11 | profile -------------------------------------------------------------------------------- /GetexceptionalAPI/GetexceptionalAPI.xcodeproj/colins.pbxuser: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | 1F1EC0F61339FA65007B5A96 /* Project object */ = { 4 | activeBuildConfigurationName = Debug; 5 | activeExecutable = 1FB02F6A133A04A5008C0462 /* GetexceptionalAPI */; 6 | activeTarget = 1F1EC0FE1339FA65007B5A96 /* GetexceptionalAPI */; 7 | codeSenseManager = 1FB02F8C133A04AB008C0462 /* Code sense */; 8 | executables = ( 9 | 1FB02F6A133A04A5008C0462 /* GetexceptionalAPI */, 10 | ); 11 | perUserDictionary = { 12 | PBXConfiguration.PBXFileTableDataSource3.PBXFileTableDataSource = { 13 | PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; 14 | PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID; 15 | PBXFileTableDataSourceColumnWidthsKey = ( 16 | 20, 17 | 757, 18 | 20, 19 | 48.16259765625, 20 | 43, 21 | 43, 22 | 20, 23 | ); 24 | PBXFileTableDataSourceColumnsKey = ( 25 | PBXFileDataSource_FiletypeID, 26 | PBXFileDataSource_Filename_ColumnID, 27 | PBXFileDataSource_Built_ColumnID, 28 | PBXFileDataSource_ObjectSize_ColumnID, 29 | PBXFileDataSource_Errors_ColumnID, 30 | PBXFileDataSource_Warnings_ColumnID, 31 | PBXFileDataSource_Target_ColumnID, 32 | ); 33 | }; 34 | PBXPerProjectTemplateStateSaveDate = 322569381; 35 | PBXWorkspaceStateSaveDate = 322569381; 36 | }; 37 | sourceControlManager = 1FB02F8B133A04AB008C0462 /* Source Control */; 38 | userBuildSettings = { 39 | }; 40 | }; 41 | 1F1EC0FE1339FA65007B5A96 /* GetexceptionalAPI */ = { 42 | activeExec = 0; 43 | executables = ( 44 | 1FB02F6A133A04A5008C0462 /* GetexceptionalAPI */, 45 | ); 46 | }; 47 | 1F1EC11C1339FA65007B5A96 /* GetexceptionalAPITests */ = { 48 | activeExec = 0; 49 | }; 50 | 1FB02F6A133A04A5008C0462 /* GetexceptionalAPI */ = { 51 | isa = PBXExecutable; 52 | activeArgIndices = ( 53 | ); 54 | argumentStrings = ( 55 | ); 56 | autoAttachOnCrash = 1; 57 | breakpointsEnabled = 0; 58 | configStateDict = { 59 | }; 60 | customDataFormattersEnabled = 1; 61 | dataTipCustomDataFormattersEnabled = 1; 62 | dataTipShowTypeColumn = 1; 63 | dataTipSortType = 0; 64 | debuggerPlugin = GDBDebugging; 65 | disassemblyDisplayState = 0; 66 | enableDebugStr = 1; 67 | environmentEntries = ( 68 | ); 69 | executableSystemSymbolLevel = 0; 70 | executableUserSymbolLevel = 0; 71 | libgmallocEnabled = 0; 72 | name = GetexceptionalAPI; 73 | showTypeColumn = 0; 74 | sourceDirectories = ( 75 | ); 76 | }; 77 | 1FB02F8B133A04AB008C0462 /* Source Control */ = { 78 | isa = PBXSourceControlManager; 79 | fallbackIsa = XCSourceControlManager; 80 | isSCMEnabled = 0; 81 | scmConfiguration = { 82 | repositoryNamesForRoots = { 83 | "" = ""; 84 | }; 85 | }; 86 | }; 87 | 1FB02F8C133A04AB008C0462 /* Code sense */ = { 88 | isa = PBXCodeSenseManager; 89 | indexTemplatePath = ""; 90 | }; 91 | } 92 | -------------------------------------------------------------------------------- /GetexceptionalAPI/GetexceptionalAPI.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /GetexceptionalAPI/GetexceptionalAPI.xcodeproj/xcuserdata/colins.xcuserdatad/xcschemes/GetexceptionalAPI.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | 14 | 20 | 21 | 22 | 23 | 24 | 29 | 30 | 32 | 38 | 39 | 40 | 41 | 42 | 50 | 51 | 57 | 58 | 59 | 60 | 61 | 62 | 69 | 70 | 76 | 77 | 78 | 79 | 81 | 82 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /GetexceptionalAPI/GetexceptionalAPI.xcodeproj/xcuserdata/colins.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | GetexceptionalAPI.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 1F1EC0FE1339FA65007B5A96 16 | 17 | primary 18 | 19 | 20 | 1F1EC11C1339FA65007B5A96 21 | 22 | primary 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /GetexceptionalAPI/GetexceptionalAPI/GetexceptionalAPI-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIconFile 12 | 13 | CFBundleIdentifier 14 | mobilemelting.${PRODUCT_NAME:rfc1034identifier} 15 | CFBundleInfoDictionaryVersion 16 | 6.0 17 | CFBundleName 18 | ${PRODUCT_NAME} 19 | CFBundlePackageType 20 | APPL 21 | CFBundleShortVersionString 22 | 1.0 23 | CFBundleSignature 24 | ???? 25 | CFBundleVersion 26 | 1.0 27 | LSRequiresIPhoneOS 28 | 29 | NSMainNibFile 30 | MainWindow 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /GetexceptionalAPI/GetexceptionalAPI/GetexceptionalAPI-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'GetexceptionalAPI' target in the 'GetexceptionalAPI' project 3 | // 4 | 5 | #import 6 | 7 | #ifndef __IPHONE_3_0 8 | #warning "This project uses features only available in iPhone SDK 3.0 and later." 9 | #endif 10 | 11 | #ifdef __OBJC__ 12 | #import 13 | #import 14 | #endif 15 | -------------------------------------------------------------------------------- /GetexceptionalAPI/GetexceptionalAPI/GetexceptionalAPI/GTExceptionalAPI.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Author: Jörg Polakowski 3 | * 4 | * Copyright (c) 2011 mobile melting GmbH 5 | * All rights reserved. 6 | * 7 | * Permission is hereby granted, free of charge, to any person 8 | * obtaining a copy of this software and associated documentation 9 | * files (the "Software"), to deal in the Software without 10 | * restriction, including without limitation the rights to use, 11 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the 13 | * Software is furnished to do so, subject to the following 14 | * conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be 17 | * included in all copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 20 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 21 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 22 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 23 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 24 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 26 | * OTHER DEALINGS IN THE SOFTWARE. 27 | */ 28 | 29 | #import 30 | #import "GTExceptionalMessage.h" 31 | 32 | 33 | @interface GTExceptionalAPI : NSObject { 34 | 35 | @private 36 | // Application identifier, e.g. product name 37 | NSString *applicationIdentifier; 38 | // Application version 39 | NSString *applicationVersion; 40 | // The device name on which the error occurred, e.g. "iPhone 4" 41 | NSString *deviceName; 42 | // The device's iOS version identifier, e.g. "4.3.3" 43 | NSString *systemVersion; 44 | // Path to the crash reporter internal data directory 45 | NSString *crashReportDirectory; 46 | } 47 | 48 | @property (nonatomic, retain) NSString *applicationIdentifier; 49 | @property (nonatomic, retain) NSString *applicationVersion; 50 | @property (nonatomic, retain) NSString *deviceName; 51 | @property (nonatomic, retain) NSString *systemVersion; 52 | @property (nonatomic, retain) NSString *crashReportDirectory; 53 | 54 | /** 55 | * Use this to retrieve the singleton instance of the API handler. 56 | * 57 | * Usage: ExceptionalAPI *api = [ExceptionalAPI sharedAPI]; 58 | */ 59 | + (GTExceptionalAPI *)sharedAPI; 60 | 61 | /** 62 | * Call this once for your app to setup the exception handler. 63 | * 64 | * In an iOS environment this would fit in very well in the applicationDidFinishLaunching callback. 65 | */ 66 | - (void)setupExceptionHandling; 67 | 68 | /** 69 | * Reports the exception to getexceptional API. 70 | * 71 | * exception - the exception, which should be reported. Must not be nil. 72 | * wait - YES, block the calling thread while sending the exception. NO, perform sending asynchronously. 73 | */ 74 | - (void)reportNSException:(NSException *)exception wait:(BOOL)wait; 75 | 76 | /** 77 | * Reports the exception to getexceptional API. 78 | * 79 | * message - the wrapped exception, which should be reported. Must not be nil. 80 | * wait - YES, block the calling thread while sending the exception. NO, perform sending asynchronously. 81 | */ 82 | - (void)reportExceptionalMessage:(GTExceptionalMessage *)message wait:(BOOL)wait; 83 | 84 | /** 85 | * Utility method, which returns the getexceptional.com reporting URL. 86 | * The URL is already setup with the API key from the exceptional.plist file 87 | * 88 | * e.g. http://api.getexceptional.com/api/errors?api_key=YOUR_API_KEY&protocol_version=6 89 | */ 90 | + (NSURL *) exceptionalURL; 91 | 92 | @end 93 | -------------------------------------------------------------------------------- /GetexceptionalAPI/GetexceptionalAPI/GetexceptionalAPI/GTExceptionalAPI.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Author: Jörg Polakowski 3 | * 4 | * Copyright (c) 2011 mobile melting GmbH 5 | * All rights reserved. 6 | * 7 | * Permission is hereby granted, free of charge, to any person 8 | * obtaining a copy of this software and associated documentation 9 | * files (the "Software"), to deal in the Software without 10 | * restriction, including without limitation the rights to use, 11 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the 13 | * Software is furnished to do so, subject to the following 14 | * conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be 17 | * included in all copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 20 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 21 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 22 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 23 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 24 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 26 | * OTHER DEALINGS IN THE SOFTWARE. 27 | */ 28 | 29 | #import "GTExceptionalAPI.h" 30 | #import "ASIHTTPRequest.h" 31 | #import "JSON.h" 32 | #import "GTExceptionalDeviceInfo.h" 33 | 34 | #define NSDEBUG(msg, args...) {\ 35 | NSLog(@"[ExceptionalAPI] " msg, ## args); \ 36 | } 37 | 38 | /** 39 | * @internal 40 | * CrashReporter cache directory name. 41 | */ 42 | static NSString *GTCRASH_CACHE_DIR = @"com.mobilemelting.exceptional.data"; 43 | 44 | // private category 45 | @interface GTExceptionalAPI (Private) 46 | 47 | - (id) initWithBundle:(NSBundle *)bundle; 48 | - (id) initWithApplicationIdentifier:(NSString *)identifier appVersion:(NSString *)version; 49 | 50 | - (void)exceptionReportingRequestFinished:(ASIHTTPRequest *)request; 51 | - (void)exceptionReportingRequestFailed:(ASIHTTPRequest *)request; 52 | @end 53 | 54 | 55 | @implementation GTExceptionalAPI 56 | 57 | static GTExceptionalAPI *sharedSingleton = nil; 58 | 59 | @synthesize applicationIdentifier, applicationVersion, deviceName, systemVersion, 60 | crashReportDirectory; 61 | 62 | /** 63 | * Return the application's crash reporter instance. 64 | */ 65 | + (GTExceptionalAPI *)sharedAPI { 66 | if (sharedSingleton == nil) { 67 | sharedSingleton = [[GTExceptionalAPI alloc] initWithBundle:[NSBundle mainBundle]]; 68 | } 69 | return sharedSingleton; 70 | } 71 | 72 | void exceptionHandler(NSException *exception) { 73 | [[GTExceptionalAPI sharedAPI] reportNSException:exception wait:YES]; 74 | } 75 | 76 | - (void)setupExceptionHandling { 77 | // Change top-level exception handler to report exceptions to 'getexceptional' 78 | NSSetUncaughtExceptionHandler(&exceptionHandler); 79 | } 80 | 81 | - (void)reportNSException:(NSException *)exception wait:(BOOL)wait { 82 | GTExceptionalMessage *message = [[GTExceptionalMessage alloc] initWithException:exception]; 83 | [self reportExceptionalMessage:message wait:wait]; 84 | [message release]; 85 | } 86 | 87 | - (void)reportExceptionalMessage:(GTExceptionalMessage *)message wait:(BOOL)wait { 88 | 89 | NSDictionary *exDict = [NSDictionary dictionaryWithObjectsAndKeys: 90 | [message message], @"message", 91 | [message exceptionClassName], @"exception_class", 92 | [message backtrace], @"backtrace", 93 | [message occuredAt], @"occurred_at", nil]; 94 | 95 | // "env" 96 | NSDictionary *envDict = [NSDictionary dictionaryWithObjectsAndKeys: 97 | self.applicationIdentifier, @"application_identifier", 98 | self.applicationVersion, @"application_version", 99 | self.deviceName, @"device_name", 100 | self.systemVersion, @"device_version", nil]; 101 | 102 | // "application_environment" 103 | NSDictionary *appDict = [NSDictionary dictionaryWithObjectsAndKeys: 104 | @"objective-c", @"language", 105 | @"Apple iOS", @"framework", 106 | envDict, @"env", 107 | @"", @"application_root_directory", nil]; 108 | 109 | // "client" 110 | NSDictionary *clientDict = [NSDictionary dictionaryWithObjectsAndKeys: 111 | @"getexceptional-ios-api-wrapper", @"name", 112 | @"1.0", @"version", 113 | @"6", @"protocol_version", nil]; 114 | 115 | NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys: 116 | exDict, @"exception", 117 | appDict, @"application_environment", 118 | clientDict, @"client", nil]; 119 | 120 | SBJsonWriter *parser = [[SBJsonWriter alloc] init]; 121 | NSString *exceptionData = [parser stringWithObject:dict]; 122 | [parser release]; 123 | 124 | ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[GTExceptionalAPI exceptionalURL]]; 125 | [request addRequestHeader:@"Accept" value:@"application/json"]; 126 | [request addRequestHeader:@"Content-Type" value:@"application/json"]; 127 | [request appendPostData:[exceptionData dataUsingEncoding:NSUTF8StringEncoding]]; 128 | [request setShouldCompressRequestBody:YES]; // gzip the POST data 129 | [request setAllowCompressedResponse:YES]; 130 | [request setShouldRedirect:NO]; 131 | [request setDelegate:self]; 132 | if (wait) { 133 | [request startSynchronous]; 134 | } 135 | else { 136 | [request setDidFinishSelector:@selector(exceptionReportingRequestFinished:)]; 137 | [request setDidFailSelector:@selector(exceptionReportingRequestFailed:)]; 138 | [request startAsynchronous]; 139 | } 140 | } 141 | 142 | + (NSURL *) exceptionalURL { 143 | NSString *path = [[NSBundle mainBundle] pathForResource:@"exceptional" ofType:@"plist"]; 144 | NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:path]; 145 | 146 | NSString *apiKey = [dict valueForKey:@"API_KEY"]; 147 | NSString *apiBaseUrl = [dict valueForKey:@"API_BASE_URL"]; 148 | NSString *apiUrlPath = [NSString stringWithFormat:@"%@?api_key=%@&protocol_version=6", 149 | apiBaseUrl, apiKey]; 150 | 151 | return [NSURL URLWithString:apiUrlPath]; 152 | } 153 | 154 | @end 155 | 156 | 157 | /** 158 | * @internal 159 | * 160 | * Private Methods 161 | */ 162 | @implementation GTExceptionalAPI (Private) 163 | 164 | /** 165 | * @internal 166 | * 167 | * Initialize with the provided bundle's ID and version. 168 | */ 169 | - (id) initWithBundle: (NSBundle *) bundle { 170 | NSString *bundleIdentifier = [bundle bundleIdentifier]; 171 | NSString *bundleVersion = [[bundle infoDictionary] objectForKey: (NSString *) kCFBundleVersionKey]; 172 | 173 | /* Verify that the identifier is available */ 174 | if (bundleIdentifier == nil) { 175 | const char *progname = getprogname(); 176 | if (progname == NULL) { 177 | [NSException raise:@"ExceptionalAPI" format:@"Can not determine process identifier or process name"]; 178 | [self release]; 179 | return nil; 180 | } 181 | NSDEBUG(@"Warning -- bundle identifier, using process name %s", progname); 182 | bundleIdentifier = [NSString stringWithUTF8String:progname]; 183 | } 184 | /* Verify that the version is available */ 185 | if (bundleVersion == nil) { 186 | NSDEBUG(@"Warning -- bundle version unavailable"); 187 | bundleVersion = @""; 188 | } 189 | return [self initWithApplicationIdentifier:bundleIdentifier appVersion:bundleVersion]; 190 | } 191 | 192 | /** 193 | * @internal 194 | * 195 | * This is the designated initializer, but it is not intended to be called externally. 196 | */ 197 | - (id) initWithApplicationIdentifier:(NSString *)identifier appVersion:(NSString *)version { 198 | /* Only allow one instance to be created, no matter what */ 199 | if (sharedSingleton != NULL) { 200 | [self release]; 201 | return sharedSingleton; 202 | } 203 | /* Initialize our superclass */ 204 | if ((self = [super init]) == nil) { 205 | return nil; 206 | } 207 | // Save application ID, version and device name 208 | self.applicationIdentifier = identifier; 209 | self.applicationVersion = version; 210 | self.deviceName = [GTExceptionalDeviceInfo platformString]; 211 | self.systemVersion = [[UIDevice currentDevice] systemVersion]; 212 | 213 | /* No occurances of '/' should ever be in a bundle ID, but just to be safe, we escape them */ 214 | NSString *appIdPath = [applicationIdentifier stringByReplacingOccurrencesOfString:@"/" withString:@"_"]; 215 | 216 | NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); 217 | NSString *cacheDir = [paths objectAtIndex:0]; 218 | self.crashReportDirectory = [[cacheDir stringByAppendingPathComponent:GTCRASH_CACHE_DIR] 219 | stringByAppendingPathComponent:appIdPath]; 220 | return self; 221 | } 222 | 223 | #pragma ASIHTTPRequest delegate methods 224 | 225 | - (void)exceptionReportingRequestFinished:(ASIHTTPRequest *)request { 226 | NSLog(@"Exception has been reported .."); 227 | 228 | NSLog(@"Status Code: %d", [request responseStatusCode]); 229 | NSLog(@"Request Message: %@", [request responseStatusMessage]); 230 | } 231 | 232 | - (void)exceptionReportingRequestFailed:(ASIHTTPRequest *)request { 233 | // TODO: handle request failure 234 | NSLog(@"Exception Reporting failed ..."); 235 | } 236 | 237 | @end 238 | -------------------------------------------------------------------------------- /GetexceptionalAPI/GetexceptionalAPI/GetexceptionalAPI/GTExceptionalDeviceInfo.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Author: Jörg Polakowski 3 | * 4 | * Copyright (c) 2011 mobile melting GmbH 5 | * All rights reserved. 6 | * 7 | * Permission is hereby granted, free of charge, to any person 8 | * obtaining a copy of this software and associated documentation 9 | * files (the "Software"), to deal in the Software without 10 | * restriction, including without limitation the rights to use, 11 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the 13 | * Software is furnished to do so, subject to the following 14 | * conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be 17 | * included in all copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 20 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 21 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 22 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 23 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 24 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 26 | * OTHER DEALINGS IN THE SOFTWARE. 27 | */ 28 | 29 | // 30 | // Used to determine EXACT version of device software is running on. 31 | // Taken from: http://stackoverflow.com/questions/448162/determine-device-iphone-ipod-touch-with-iphone-sdk/1561920#1561920 32 | // 33 | 34 | #import 35 | 36 | @interface GTExceptionalDeviceInfo : NSObject 37 | 38 | + (NSString *) platform; 39 | + (NSString *) platformString; 40 | 41 | @end 42 | -------------------------------------------------------------------------------- /GetexceptionalAPI/GetexceptionalAPI/GetexceptionalAPI/GTExceptionalDeviceInfo.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Author: Jörg Polakowski 3 | * 4 | * Copyright (c) 2011 mobile melting GmbH 5 | * All rights reserved. 6 | * 7 | * Permission is hereby granted, free of charge, to any person 8 | * obtaining a copy of this software and associated documentation 9 | * files (the "Software"), to deal in the Software without 10 | * restriction, including without limitation the rights to use, 11 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the 13 | * Software is furnished to do so, subject to the following 14 | * conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be 17 | * included in all copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 20 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 21 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 22 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 23 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 24 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 26 | * OTHER DEALINGS IN THE SOFTWARE. 27 | */ 28 | 29 | // 30 | // Used to determine EXACT version of device software is running on. 31 | // Taken from: http://stackoverflow.com/questions/448162/determine-device-iphone-ipod-touch-with-iphone-sdk/1561920#1561920 32 | // 33 | 34 | #import "GTExceptionalDeviceInfo.h" 35 | #include 36 | #include 37 | 38 | @implementation GTExceptionalDeviceInfo 39 | 40 | + (NSString *) platform{ 41 | size_t size; 42 | sysctlbyname("hw.machine", NULL, &size, NULL, 0); 43 | char *machine = malloc(size); 44 | sysctlbyname("hw.machine", machine, &size, NULL, 0); 45 | NSString *platform = [NSString stringWithCString:(char *)machine encoding:NSUTF8StringEncoding]; 46 | free(machine); 47 | return platform; 48 | } 49 | 50 | + (NSString *) platformString{ 51 | NSString *platform = [self platform]; 52 | if ([platform isEqualToString:@"iPhone1,1"]) return @"iPhone 1G"; 53 | if ([platform isEqualToString:@"iPhone1,2"]) return @"iPhone 3G"; 54 | if ([platform isEqualToString:@"iPhone2,1"]) return @"iPhone 3GS"; 55 | if ([platform isEqualToString:@"iPhone3,1"]) return @"iPhone 4"; 56 | if ([platform isEqualToString:@"iPhone3,2"]) return @"Verizon iPhone 4"; 57 | if ([platform isEqualToString:@"iPod1,1"]) return @"iPod Touch 1G"; 58 | if ([platform isEqualToString:@"iPod2,1"]) return @"iPod Touch 2G"; 59 | if ([platform isEqualToString:@"iPod3,1"]) return @"iPod Touch 3G"; 60 | if ([platform isEqualToString:@"iPod4,1"]) return @"iPod Touch 4G"; 61 | if ([platform isEqualToString:@"iPad1,1"]) return @"iPad"; 62 | if ([platform isEqualToString:@"iPad2,1"]) return @"iPad 2 (WiFi)"; 63 | if ([platform isEqualToString:@"iPad2,2"]) return @"iPad 2 (GSM)"; 64 | if ([platform isEqualToString:@"iPad2,3"]) return @"iPad 2 (CDMA)"; 65 | if ([platform isEqualToString:@"i386"]) return @"Simulator"; 66 | return platform; 67 | } 68 | 69 | @end 70 | -------------------------------------------------------------------------------- /GetexceptionalAPI/GetexceptionalAPI/GetexceptionalAPI/GTExceptionalMessage.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Author: Jörg Polakowski 3 | * 4 | * Copyright (c) 2011 mobile melting GmbH 5 | * All rights reserved. 6 | * 7 | * Permission is hereby granted, free of charge, to any person 8 | * obtaining a copy of this software and associated documentation 9 | * files (the "Software"), to deal in the Software without 10 | * restriction, including without limitation the rights to use, 11 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the 13 | * Software is furnished to do so, subject to the following 14 | * conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be 17 | * included in all copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 20 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 21 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 22 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 23 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 24 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 26 | * OTHER DEALINGS IN THE SOFTWARE. 27 | */ 28 | 29 | #import 30 | #import "ISO8601DateFormatter.h" 31 | 32 | @interface GTExceptionalMessage : NSObject { 33 | NSString *message; 34 | NSString *exceptionClassName; 35 | NSArray *backtrace; 36 | NSString *occurredAt; 37 | } 38 | 39 | @property (nonatomic, retain) NSString *message; 40 | @property (nonatomic, retain) NSString *exceptionClassName; 41 | @property (nonatomic, retain) NSArray *backtrace; 42 | @property (nonatomic, retain) NSString *occuredAt; 43 | 44 | /** 45 | * 46 | * exMessage - The error details string for the error. 47 | * exClass - This string represents the name of the class within which the error occurred. 48 | * exBacktrace - Array of strings representing the backtrace where the error occurred. 49 | * 50 | */ 51 | - (id)initWithMessage:(NSString *)exMessage 52 | exceptionClass:(NSString *)exClass 53 | backtrace:(NSArray *)exBacktrace; 54 | 55 | - (id)initWithException:(NSException *)exception; 56 | 57 | @end 58 | -------------------------------------------------------------------------------- /GetexceptionalAPI/GetexceptionalAPI/GetexceptionalAPI/GTExceptionalMessage.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Author: Jörg Polakowski 3 | * 4 | * Copyright (c) 2011 mobile melting GmbH 5 | * All rights reserved. 6 | * 7 | * Permission is hereby granted, free of charge, to any person 8 | * obtaining a copy of this software and associated documentation 9 | * files (the "Software"), to deal in the Software without 10 | * restriction, including without limitation the rights to use, 11 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the 13 | * Software is furnished to do so, subject to the following 14 | * conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be 17 | * included in all copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 20 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 21 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 22 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 23 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 24 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 26 | * OTHER DEALINGS IN THE SOFTWARE. 27 | */ 28 | 29 | #import "GTExceptionalMessage.h" 30 | #import "GTExceptionalAPI.h" 31 | 32 | @implementation GTExceptionalMessage 33 | 34 | @synthesize message, exceptionClassName, backtrace, occuredAt; 35 | 36 | - (void)dealloc { 37 | [message release]; 38 | [exceptionClassName release]; 39 | [backtrace release]; 40 | [occuredAt release]; 41 | [super dealloc]; 42 | } 43 | 44 | - (id)init { 45 | self = [super init]; 46 | if (self != nil) { 47 | // additional init stuff here 48 | ISO8601DateFormatter *isoFormatter = [[ISO8601DateFormatter alloc] init]; 49 | [isoFormatter setIncludeTime:YES]; 50 | NSTimeZone *timeZone = [NSTimeZone localTimeZone]; 51 | self.occuredAt = [isoFormatter stringFromDate:[NSDate date] timeZone:timeZone]; 52 | [isoFormatter release]; 53 | } 54 | return self; 55 | } 56 | 57 | - (id)initWithMessage:(NSString *)exMessage 58 | exceptionClass:(NSString *)exClass 59 | backtrace:(NSArray *)exBacktrace { 60 | 61 | GTExceptionalMessage *exceptionalMessage = (GTExceptionalMessage *) [self init]; 62 | 63 | self.message = exMessage; 64 | self.exceptionClassName = exClass; 65 | if (exBacktrace == nil) { 66 | self.backtrace = [NSThread callStackSymbols]; 67 | } 68 | else { 69 | self.backtrace = exBacktrace; 70 | } 71 | 72 | return exceptionalMessage; 73 | } 74 | 75 | - (id)initWithException:(NSException *)exception { 76 | return [self initWithMessage:[exception reason] exceptionClass:[exception name] backtrace:[exception callStackSymbols]]; 77 | } 78 | 79 | @end 80 | -------------------------------------------------------------------------------- /GetexceptionalAPI/GetexceptionalAPI/GetexceptionalAPI/exceptional.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | API_BASE_URL 6 | http://api.getexceptional.com/api/errors 7 | API_KEY 8 | to be defined 9 | 10 | 11 | -------------------------------------------------------------------------------- /GetexceptionalAPI/GetexceptionalAPI/GetexceptionalAPIAppDelegate.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Author: Jörg Polakowski 3 | * 4 | * Copyright (c) 2011 mobile melting GmbH 5 | * All rights reserved. 6 | * 7 | * Permission is hereby granted, free of charge, to any person 8 | * obtaining a copy of this software and associated documentation 9 | * files (the "Software"), to deal in the Software without 10 | * restriction, including without limitation the rights to use, 11 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the 13 | * Software is furnished to do so, subject to the following 14 | * conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be 17 | * included in all copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 20 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 21 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 22 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 23 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 24 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 26 | * OTHER DEALINGS IN THE SOFTWARE. 27 | */ 28 | 29 | #import 30 | 31 | @interface GetexceptionalAPIAppDelegate : NSObject { 32 | IBOutlet UIButton *reportDirectlyButton; 33 | IBOutlet UIButton *triggerExceptionButton; 34 | } 35 | 36 | @property (nonatomic, retain) IBOutlet UIWindow *window; 37 | @property (nonatomic, retain) IBOutlet UIButton *reportDirectlyButton; 38 | @property (nonatomic, retain) IBOutlet UIButton *triggerExceptionButton; 39 | 40 | -(IBAction) reportDirectlyButtonPressed:(id)sender; 41 | 42 | -(IBAction) triggerExceptionButtonPressed:(id)sender; 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /GetexceptionalAPI/GetexceptionalAPI/GetexceptionalAPIAppDelegate.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Author: Jörg Polakowski 3 | * 4 | * Copyright (c) 2011 mobile melting GmbH 5 | * All rights reserved. 6 | * 7 | * Permission is hereby granted, free of charge, to any person 8 | * obtaining a copy of this software and associated documentation 9 | * files (the "Software"), to deal in the Software without 10 | * restriction, including without limitation the rights to use, 11 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the 13 | * Software is furnished to do so, subject to the following 14 | * conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be 17 | * included in all copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 20 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 21 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 22 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 23 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 24 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 26 | * OTHER DEALINGS IN THE SOFTWARE. 27 | */ 28 | 29 | #import "GetexceptionalAPIAppDelegate.h" 30 | #import "GTExceptionalAPI.h" 31 | 32 | @implementation GetexceptionalAPIAppDelegate 33 | 34 | @synthesize window=_window; 35 | @synthesize reportDirectlyButton, triggerExceptionButton; 36 | 37 | - (void)dealloc { 38 | [reportDirectlyButton release]; 39 | [triggerExceptionButton release]; 40 | [_window release]; 41 | [super dealloc]; 42 | } 43 | 44 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 45 | { 46 | [[GTExceptionalAPI sharedAPI] setupExceptionHandling]; 47 | 48 | // Override point for customization after application launch. 49 | [self.window makeKeyAndVisible]; 50 | return YES; 51 | } 52 | 53 | - (void)applicationWillResignActive:(UIApplication *)application 54 | { 55 | /* 56 | Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 57 | Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 58 | */ 59 | } 60 | 61 | - (void)applicationDidEnterBackground:(UIApplication *)application 62 | { 63 | /* 64 | Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 65 | If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 66 | */ 67 | } 68 | 69 | - (void)applicationWillEnterForeground:(UIApplication *)application 70 | { 71 | /* 72 | Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 73 | */ 74 | } 75 | 76 | - (void)applicationDidBecomeActive:(UIApplication *)application 77 | { 78 | /* 79 | Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 80 | */ 81 | } 82 | 83 | - (void)applicationWillTerminate:(UIApplication *)application 84 | { 85 | /* 86 | Called when the application is about to terminate. 87 | Save data if appropriate. 88 | See also applicationDidEnterBackground:. 89 | */ 90 | } 91 | 92 | #pragma Button delegates 93 | 94 | -(IBAction) reportDirectlyButtonPressed:(id)sender { 95 | @try { 96 | NSArray *array = [NSArray arrayWithObjects:@"one", @"two", @"three", nil]; 97 | [array objectAtIndex:0]; 98 | [array objectAtIndex:5]; 99 | } 100 | @catch (NSException *exception) { 101 | [[GTExceptionalAPI sharedAPI] reportNSException:exception wait:NO]; 102 | } 103 | } 104 | 105 | -(IBAction) triggerExceptionButtonPressed:(id)sender { 106 | NSArray *array = [NSArray arrayWithObjects:@"one", @"two", @"three", nil]; 107 | [array objectAtIndex:0]; 108 | [array objectAtIndex:7]; 109 | 110 | } 111 | 112 | @end 113 | -------------------------------------------------------------------------------- /GetexceptionalAPI/GetexceptionalAPI/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /GetexceptionalAPI/GetexceptionalAPI/en.lproj/MainWindow.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1056 5 | 10J869 6 | 1306 7 | 1038.35 8 | 461.00 9 | 10 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 11 | 301 12 | 13 | 14 | IBUIWindow 15 | IBUICustomObject 16 | IBUIButton 17 | IBUITextView 18 | IBProxyObject 19 | 20 | 21 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 22 | 23 | 24 | 25 | 26 | IBFilesOwner 27 | IBCocoaTouchFramework 28 | 29 | 30 | IBFirstResponder 31 | IBCocoaTouchFramework 32 | 33 | 34 | IBCocoaTouchFramework 35 | 36 | 37 | 38 | 1316 39 | 40 | 41 | 42 | 1316 43 | {{56, 134}, {209, 37}} 44 | 45 | 46 | 47 | NO 48 | IBCocoaTouchFramework 49 | 0 50 | 0 51 | 52 | Helvetica-Bold 53 | 15 54 | 16 55 | 56 | 1 57 | Report Exception Directly 58 | 59 | 3 60 | MQA 61 | 62 | 63 | 1 64 | MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA 65 | 66 | 67 | 3 68 | MC41AA 69 | 70 | 71 | 72 | 73 | 1316 74 | {{84, 305}, {152, 37}} 75 | 76 | 77 | 78 | NO 79 | IBCocoaTouchFramework 80 | 0 81 | 0 82 | 83 | 1 84 | Trigger Exception 85 | 86 | 87 | 1 88 | MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA 89 | 90 | 91 | 92 | 93 | 94 | 1316 95 | {{20, 179}, {280, 82}} 96 | 97 | 98 | 99 | 100 | 1 101 | MSAxIDEAA 102 | 103 | YES 104 | YES 105 | 106 | 107 | 108 | 109 | IBCocoaTouchFramework 110 | Exception will be handled in a try-catch block and reported to exceptional. 111 | 112 | Helvetica 113 | 17 114 | 16 115 | 116 | 117 | 2 118 | IBCocoaTouchFramework 119 | 120 | 121 | 122 | 123 | 1316 124 | {{20, 350}, {280, 82}} 125 | 126 | 127 | 128 | 129 | YES 130 | YES 131 | 132 | 133 | 134 | 135 | IBCocoaTouchFramework 136 | Exception will be handled in a try-catch block and reported to exceptional. 137 | 138 | 139 | 2 140 | IBCocoaTouchFramework 141 | 142 | 143 | 144 | 145 | {320, 480} 146 | 147 | 148 | 149 | 150 | NO 151 | NO 152 | 153 | IBCocoaTouchFramework 154 | YES 155 | 156 | 157 | 158 | 159 | 160 | 161 | delegate 162 | 163 | 164 | 165 | 4 166 | 167 | 168 | 169 | window 170 | 171 | 172 | 173 | 5 174 | 175 | 176 | 177 | reportDirectlyButton 178 | 179 | 180 | 181 | 11 182 | 183 | 184 | 185 | reportDirectlyButtonPressed: 186 | 187 | 188 | 7 189 | 190 | 12 191 | 192 | 193 | 194 | triggerExceptionButton 195 | 196 | 197 | 198 | 17 199 | 200 | 201 | 202 | triggerExceptionButtonPressed: 203 | 204 | 205 | 7 206 | 207 | 18 208 | 209 | 210 | 211 | 212 | 213 | 0 214 | 215 | 216 | 217 | 218 | 219 | 2 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | -1 231 | 232 | 233 | File's Owner 234 | 235 | 236 | 3 237 | 238 | 239 | 240 | 241 | -2 242 | 243 | 244 | 245 | 246 | 10 247 | 248 | 249 | 250 | 251 | 13 252 | 253 | 254 | 255 | 256 | 15 257 | 258 | 259 | 260 | 261 | 16 262 | 263 | 264 | 265 | 266 | 267 | 268 | UIApplication 269 | UIResponder 270 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 271 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 272 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 273 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 274 | 275 | {{198, 376}, {320, 480}} 276 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 277 | GetexceptionalAPIAppDelegate 278 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 279 | 280 | 281 | 282 | 283 | 284 | 18 285 | 286 | 287 | 288 | 289 | GetexceptionalAPIAppDelegate 290 | NSObject 291 | 292 | id 293 | id 294 | 295 | 296 | 297 | reportDirectlyButtonPressed: 298 | id 299 | 300 | 301 | triggerExceptionButtonPressed: 302 | id 303 | 304 | 305 | 306 | UIButton 307 | UIButton 308 | UIWindow 309 | 310 | 311 | 312 | reportDirectlyButton 313 | UIButton 314 | 315 | 316 | triggerExceptionButton 317 | UIButton 318 | 319 | 320 | window 321 | UIWindow 322 | 323 | 324 | 325 | IBProjectSource 326 | ./Classes/GetexceptionalAPIAppDelegate.h 327 | 328 | 329 | 330 | 331 | 0 332 | IBCocoaTouchFramework 333 | YES 334 | 3 335 | 301 336 | 337 | 338 | -------------------------------------------------------------------------------- /GetexceptionalAPI/GetexceptionalAPI/external/ISO-8601-parser-0.5/ISO8601DateFormatter.h: -------------------------------------------------------------------------------- 1 | /*ISO8601DateFormatter.h 2 | * 3 | *Created by Peter Hosey on 2009-04-11. 4 | *Copyright 2009 Peter Hosey. All rights reserved. 5 | */ 6 | 7 | #import 8 | 9 | /*This class converts dates to and from ISO 8601 strings. A good introduction to ISO 8601: 10 | * 11 | *Parsing can be done strictly, or not. When you parse loosely, leading whitespace is ignored, as is anything after the date. 12 | *The loose parser will return an NSDate for this string: @" \t\r\n\f\t 2006-03-02!!!" 13 | *Leading non-whitespace will not be ignored; the string will be rejected, and nil returned. See the README that came with this addition. 14 | * 15 | *The strict parser will only accept a string if the date is the entire string. The above string would be rejected immediately, solely on these grounds. 16 | *Also, the loose parser provides some extensions that the strict parser doesn't. 17 | *For example, the standard says for "-DDD" (an ordinal date in the implied year) that the logical representation (meaning, hierarchically) would be "--DDD", but because that extra hyphen is "superfluous", it was omitted. 18 | *The loose parser will accept the extra hyphen; the strict parser will not. 19 | *A full list of these extensions is in the README file. 20 | */ 21 | 22 | /*The format to either expect or produce. 23 | *Calendar format is YYYY-MM-DD. 24 | *Ordinal format is YYYY-DDD, where DDD ranges from 1 to 366; for example, 2009-32 is 2009-02-01. 25 | *Week format is YYYY-Www-D, where ww ranges from 1 to 53 (the 'W' is literal) and D ranges from 1 to 7; for example, 2009-W05-07. 26 | */ 27 | enum { 28 | ISO8601DateFormatCalendar, 29 | ISO8601DateFormatOrdinal, 30 | ISO8601DateFormatWeek, 31 | }; 32 | typedef NSUInteger ISO8601DateFormat; 33 | 34 | //The default separator for time values. Currently, this is ':'. 35 | extern unichar ISO8601DefaultTimeSeparatorCharacter; 36 | 37 | @interface ISO8601DateFormatter: NSFormatter 38 | { 39 | NSTimeZone *defaultTimeZone; 40 | ISO8601DateFormat format; 41 | unichar timeSeparator; 42 | BOOL includeTime; 43 | BOOL parsesStrictly; 44 | } 45 | 46 | @property(retain) NSTimeZone *defaultTimeZone; 47 | 48 | #pragma mark Parsing 49 | 50 | //As a formatter, this object converts strings to dates. 51 | 52 | @property BOOL parsesStrictly; 53 | 54 | - (NSDateComponents *) dateComponentsFromString:(NSString *)string; 55 | - (NSDateComponents *) dateComponentsFromString:(NSString *)string timeZone:(out NSTimeZone **)outTimeZone; 56 | - (NSDateComponents *) dateComponentsFromString:(NSString *)string timeZone:(out NSTimeZone **)outTimeZone range:(out NSRange *)outRange; 57 | 58 | - (NSDate *) dateFromString:(NSString *)string; 59 | - (NSDate *) dateFromString:(NSString *)string timeZone:(out NSTimeZone **)outTimeZone; 60 | - (NSDate *) dateFromString:(NSString *)string timeZone:(out NSTimeZone **)outTimeZone range:(out NSRange *)outRange; 61 | 62 | #pragma mark Unparsing 63 | 64 | @property ISO8601DateFormat format; 65 | @property BOOL includeTime; 66 | @property unichar timeSeparator; 67 | 68 | - (NSString *) stringFromDate:(NSDate *)date; 69 | - (NSString *) stringFromDate:(NSDate *)date timeZone:(NSTimeZone *)timeZone; 70 | 71 | @end 72 | -------------------------------------------------------------------------------- /GetexceptionalAPI/GetexceptionalAPI/external/ISO-8601-parser-0.5/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright © 2006 Peter Hosey 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 5 | Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 6 | Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 7 | Neither the name of Peter Hosey nor the names of his contributors may be used to endorse or promote products derived from this software without specific prior written permission. 8 | 9 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 10 | -------------------------------------------------------------------------------- /GetexceptionalAPI/GetexceptionalAPI/external/ISO-8601-parser-0.5/README.txt: -------------------------------------------------------------------------------- 1 | How to use in your program 2 | ========================== 3 | 4 | Add the source files to your project. 5 | 6 | Parsing 7 | ------- 8 | 9 | Create an ISO 8601 date formatter, then call [formatter dateFromString:myString]. The method will return either an NSDate or nil. 10 | 11 | There are a total of six parser methods. The one that contains the actual parser is -[ISO8601DateFormatter dateComponentsFromString:timeZone:range:]. The other five are based on this one. 12 | 13 | The "outTimeZone" parameter, when not set to NULL, is a pointer to an NSTimeZone *variable. If the string specified a time zone, you'll receive the time zone object in that variable. If the string didn't specify a time zone, you'll receive nil. 14 | 15 | The "outRange" parameter, when not set to NULL, is a pointer to NSRange storage. You will receive the range of the parsed substring in that storage. 16 | 17 | Unparsing 18 | --------- 19 | 20 | Create an ISO 8601 date formatter, then call [formatter stringFromDate:myDate]. The method will return a string. 21 | 22 | The formatter has several properties that control its behavior: 23 | 24 | * You can set the format of the resulting strings. By default, the formatter will generate calendar-date strings; your other options are week dates and ordinal dates. 25 | * You can set a default time zone; by default, it will use [NSTimeZone defaultTimeZone]. 26 | * You can enable a strict mode, wherein the formatter enforces sanity checks on the string. By default, the parser will afford you quite a bit of leeway. 27 | * You can set whether to include the time in the string, and if so, what hour-minute separator to use (default ':'). 28 | 29 | How to test that this code works 30 | ================================ 31 | 32 | 'make test' will perform all tests. If you want to perform only *some* tests: 33 | 34 | Parsing 35 | ------- 36 | 37 | Type 'make parser-test'. make will build the test program (testparser), then invoke testparser.sh.py to generate testparser.sh. Then make will invoke testparser.sh, which will invoke the test program with various dates. 38 | 39 | If you don't want to use my tests, 'make testparser' will create the test program without running it. You can then invoke testparser yourself with any date you want to. If it doesn't give you the result you expected, contact me, making sure to provide me with both the input and the output. 40 | 41 | Unparsing 42 | --------- 43 | 44 | Type 'make unparser-test'. make will build the test programs, then invoke testunparser.sh. This shell script invokes each test program for -01-01 of every year from 1991 to 2010, writing the output to a file, and then runs diff -qs between that file (testunparser.out) and a file (testunparser-expected.out) containing known correct output. diff should report that the files are identical. 45 | 46 | Three test programs are included: unparse-date, unparse-weekdate, and unparse-ordinal date. If you don't want to use my tests, you can make these test programs separately. Each takes a date specified by ISO 8601 (parsed with my own ISO 8601 parser), and outputs a string that should represent the same date. 47 | 48 | Notes 49 | ===== 50 | 51 | Version history 52 | --------------- 53 | 54 | This version is 0.5. Changes from 0.4: 55 | * Rewrote as an NSFormatter subclass using NSCalendar. 56 | * Making it a formatter makes it much easier to use with Bindings. 57 | * Using NSCalendar means we're no longer using NSCalendarDate, which Apple has said they will deprecate at some point. 58 | * Fixed a bug in week date generation: One subtraction could give a negative result, which was a problem because my implementation of the algorithm used unsigned integers. I've changed it to use signed integers, so the result truly is negative now. I also added a test case for this. 59 | 60 | Changes in 0.4 from 0.3: 61 | * Added the ability to use a time separator other than ':'. 62 | 63 | Changes in 0.3 from 0.2: 64 | * Colin Barrett noticed that I used %m instead of %M when creating the time strings. Oops. 65 | * Colin also noticed that I had the ?: in -ISO8601DateStringWithTime: the wrong way around. Oops again. 66 | 67 | Changes in 0.2 from 0.1: 68 | * The unparser is new. The has been munged to allow both components together, 69 | * The parser has not changed. 70 | 71 | Parsing 72 | ------- 73 | 74 | Whitespace before a date, and anything after a date, is ignored. Thus, " T23 and all's well" is a valid date for the purpose of this method. (Yes, T23 is a valid ISO 8601 date. It means 23:00:00, or 11 PM.) 75 | 76 | All of the frills of ISO 8601 are supported, except for extended dates (years longer than 4 digits). Specifically, you can use week-based dates (2006-W2 for the second week of 2006), ordinal dates (2006-365 for December 31), decimal minutes (11:30.5 == 11:30:30), and decimal seconds (11:30:10.5). All methods of specifying a time zone are supported. 77 | 78 | ISO 8601 leaves quite a bit up to the parties exchanging dates. I hope I've chosen reasonable defaults. For example (note that I'm writing this on 2006-02-24): 79 | 80 | • If the month or month and date are missing, 1 is assumed. "2006" == "2006-01-01". 81 | • If the year or year and month are missing, the current ones are assumed. "--02-01" == "2006-02-01". "---28" == "2006-02-28". 82 | • In the case of week-based dates, with the day missing, this implementation returns the first day of that week: 2006-W1 is 2006-01-01, 2006-W2 is 2006-01-08, etc. 83 | • For any date without a time, midnight on that date is used. 84 | • ISO 8601 permits the choice of either T0 or T24 for midnight. This implementation uses T0. T24 will get you T0 on the following day. 85 | • If no time-zone is specified, local time (as returned by [NSTimeZone localTimeZone]) is used. 86 | 87 | When a date is parsed that has a year but no century, this implementation adds the current century. 88 | 89 | The implementation is tolerant of out-of-range numbers. For example, "2005-13-40T24:62:89" == 1:02 AM on 2006-02-10. Notice that the month (13 > 12), date (40 > 31), hour (24 > 23), minute (62 > 59), and second (89 > 59) are all out-of-range. 90 | 91 | As mentioned above, there is a "strict" mode that enforces sanity checks. In particular, the date must be the entire contents of the string, and numbers are range-checked. If you have any suggestions on how to make this mode more strict, contact me. 92 | 93 | Unparsing 94 | --------- 95 | 96 | I use Rick McCarty's algorithm for converting calendar dates to week dates (http://personal.ecu.edu/mccartyr/ISOwdAlg.txt), slightly tweaked. 97 | 98 | Bugs 99 | ==== 100 | 101 | Parsing 102 | ------- 103 | 104 | * This method won't extract a date from just anywhere in a string, only immediately after the start of the string (or any leading whitespace). There are two solutions: either require you to invoke the parser on a string that is only an ISO 8601 date, with nothing before or after (bad for parsing purposes), or make the parser able to find an ISO 8601 date as a substring. I won't do the first one, and barring a patch, I probably won't do the second one either. 105 | 106 | * Date ranges (also specified by ISO 8601) are not supported; this method will only return one date. To handle ranges would require at least one more method. 107 | 108 | * There is no method to analyze a date string and tell you what was found in it (year, month, week, day, ordinal day, etc.). Feel free to submit a patch. 109 | 110 | Copyright 111 | ========= 112 | 113 | This code is copyright 2006 Peter Hosey. It is under the BSD license; see LICENSE.txt for the full text of the license. 114 | -------------------------------------------------------------------------------- /GetexceptionalAPI/GetexceptionalAPI/external/Reachability.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | File: Reachability.h 4 | Abstract: Basic demonstration of how to use the SystemConfiguration Reachablity APIs. 5 | 6 | Version: 2.0.4ddg 7 | */ 8 | 9 | /* 10 | Significant additions made by Andrew W. Donoho, August 11, 2009. 11 | This is a derived work of Apple's Reachability v2.0 class. 12 | 13 | The below license is the new BSD license with the OSI recommended personalizations. 14 | 15 | 16 | Extensions Copyright (C) 2009 Donoho Design Group, LLC. All Rights Reserved. 17 | 18 | Redistribution and use in source and binary forms, with or without 19 | modification, are permitted provided that the following conditions are 20 | met: 21 | 22 | * Redistributions of source code must retain the above copyright notice, 23 | this list of conditions and the following disclaimer. 24 | 25 | * Redistributions in binary form must reproduce the above copyright 26 | notice, this list of conditions and the following disclaimer in the 27 | documentation and/or other materials provided with the distribution. 28 | 29 | * Neither the name of Andrew W. Donoho nor Donoho Design Group, L.L.C. 30 | may be used to endorse or promote products derived from this software 31 | without specific prior written permission. 32 | 33 | THIS SOFTWARE IS PROVIDED BY DONOHO DESIGN GROUP, L.L.C. "AS IS" AND ANY 34 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 35 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 36 | PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 37 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 38 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 39 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 40 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 41 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 42 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 43 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 44 | 45 | */ 46 | 47 | 48 | /* 49 | 50 | Apple's Original License on Reachability v2.0 51 | 52 | Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. 53 | ("Apple") in consideration of your agreement to the following terms, and your 54 | use, installation, modification or redistribution of this Apple software 55 | constitutes acceptance of these terms. If you do not agree with these terms, 56 | please do not use, install, modify or redistribute this Apple software. 57 | 58 | In consideration of your agreement to abide by the following terms, and subject 59 | to these terms, Apple grants you a personal, non-exclusive license, under 60 | Apple's copyrights in this original Apple software (the "Apple Software"), to 61 | use, reproduce, modify and redistribute the Apple Software, with or without 62 | modifications, in source and/or binary forms; provided that if you redistribute 63 | the Apple Software in its entirety and without modifications, you must retain 64 | this notice and the following text and disclaimers in all such redistributions 65 | of the Apple Software. 66 | 67 | Neither the name, trademarks, service marks or logos of Apple Inc. may be used 68 | to endorse or promote products derived from the Apple Software without specific 69 | prior written permission from Apple. Except as expressly stated in this notice, 70 | no other rights or licenses, express or implied, are granted by Apple herein, 71 | including but not limited to any patent rights that may be infringed by your 72 | derivative works or by other works in which the Apple Software may be 73 | incorporated. 74 | 75 | The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO 76 | WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED 77 | WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR 78 | PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN 79 | COMBINATION WITH YOUR PRODUCTS. 80 | 81 | IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR 82 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 83 | GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 84 | ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR 85 | DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF 86 | CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF 87 | APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 88 | 89 | Copyright (C) 2009 Apple Inc. All Rights Reserved. 90 | 91 | */ 92 | 93 | 94 | /* 95 | DDG extensions include: 96 | Each reachability object now has a copy of the key used to store it in a 97 | dictionary. This allows each observer to quickly determine if the event is 98 | important to them. 99 | 100 | -currentReachabilityStatus also has a significantly different decision criteria than 101 | Apple's code. 102 | 103 | A multiple convenience test methods have been added. 104 | */ 105 | 106 | #import 107 | #import 108 | 109 | #define USE_DDG_EXTENSIONS 1 // Use DDG's Extensions to test network criteria. 110 | // Since NSAssert and NSCAssert are used in this code, 111 | // I recommend you set NS_BLOCK_ASSERTIONS=1 in the release versions of your projects. 112 | 113 | enum { 114 | 115 | // DDG NetworkStatus Constant Names. 116 | kNotReachable = 0, // Apple's code depends upon 'NotReachable' being the same value as 'NO'. 117 | kReachableViaWWAN, // Switched order from Apple's enum. WWAN is active before WiFi. 118 | kReachableViaWiFi 119 | 120 | }; 121 | typedef uint32_t NetworkStatus; 122 | 123 | enum { 124 | 125 | // Apple NetworkStatus Constant Names. 126 | NotReachable = kNotReachable, 127 | ReachableViaWiFi = kReachableViaWiFi, 128 | ReachableViaWWAN = kReachableViaWWAN 129 | 130 | }; 131 | 132 | 133 | extern NSString *const kInternetConnection; 134 | extern NSString *const kLocalWiFiConnection; 135 | extern NSString *const kReachabilityChangedNotification; 136 | 137 | @interface Reachability: NSObject { 138 | 139 | @private 140 | NSString *key_; 141 | SCNetworkReachabilityRef reachabilityRef; 142 | 143 | } 144 | 145 | @property (copy) NSString *key; // Atomic because network operations are asynchronous. 146 | 147 | // Designated Initializer. 148 | - (Reachability *) initWithReachabilityRef: (SCNetworkReachabilityRef) ref; 149 | 150 | // Use to check the reachability of a particular host name. 151 | + (Reachability *) reachabilityWithHostName: (NSString*) hostName; 152 | 153 | // Use to check the reachability of a particular IP address. 154 | + (Reachability *) reachabilityWithAddress: (const struct sockaddr_in*) hostAddress; 155 | 156 | // Use to check whether the default route is available. 157 | // Should be used to, at minimum, establish network connectivity. 158 | + (Reachability *) reachabilityForInternetConnection; 159 | 160 | // Use to check whether a local wifi connection is available. 161 | + (Reachability *) reachabilityForLocalWiFi; 162 | 163 | //Start listening for reachability notifications on the current run loop. 164 | - (BOOL) startNotifier; 165 | - (void) stopNotifier; 166 | 167 | // Comparison routines to enable choosing actions in a notification. 168 | - (BOOL) isEqual: (Reachability *) r; 169 | 170 | // These are the status tests. 171 | - (NetworkStatus) currentReachabilityStatus; 172 | 173 | // The main direct test of reachability. 174 | - (BOOL) isReachable; 175 | 176 | // WWAN may be available, but not active until a connection has been established. 177 | // WiFi may require a connection for VPN on Demand. 178 | - (BOOL) isConnectionRequired; // Identical DDG variant. 179 | - (BOOL) connectionRequired; // Apple's routine. 180 | 181 | // Dynamic, on demand connection? 182 | - (BOOL) isConnectionOnDemand; 183 | 184 | // Is user intervention required? 185 | - (BOOL) isInterventionRequired; 186 | 187 | // Routines for specific connection testing by your app. 188 | - (BOOL) isReachableViaWWAN; 189 | - (BOOL) isReachableViaWiFi; 190 | 191 | - (SCNetworkReachabilityFlags) reachabilityFlags; 192 | 193 | @end 194 | -------------------------------------------------------------------------------- /GetexceptionalAPI/GetexceptionalAPI/external/asi-http-request/ASIAuthenticationDialog.h: -------------------------------------------------------------------------------- 1 | // 2 | // ASIAuthenticationDialog.h 3 | // Part of ASIHTTPRequest -> http://allseeing-i.com/ASIHTTPRequest 4 | // 5 | // Created by Ben Copsey on 21/08/2009. 6 | // Copyright 2009 All-Seeing Interactive. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | @class ASIHTTPRequest; 12 | 13 | typedef enum _ASIAuthenticationType { 14 | ASIStandardAuthenticationType = 0, 15 | ASIProxyAuthenticationType = 1 16 | } ASIAuthenticationType; 17 | 18 | @interface ASIAutorotatingViewController : UIViewController 19 | @end 20 | 21 | @interface ASIAuthenticationDialog : ASIAutorotatingViewController { 22 | ASIHTTPRequest *request; 23 | ASIAuthenticationType type; 24 | UITableView *tableView; 25 | UIViewController *presentingController; 26 | BOOL didEnableRotationNotifications; 27 | } 28 | + (void)presentAuthenticationDialogForRequest:(ASIHTTPRequest *)request; 29 | + (void)dismiss; 30 | 31 | @property (retain) ASIHTTPRequest *request; 32 | @property (assign) ASIAuthenticationType type; 33 | @property (assign) BOOL didEnableRotationNotifications; 34 | @property (retain, nonatomic) UIViewController *presentingController; 35 | @end 36 | -------------------------------------------------------------------------------- /GetexceptionalAPI/GetexceptionalAPI/external/asi-http-request/ASICacheDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // ASICacheDelegate.h 3 | // Part of ASIHTTPRequest -> http://allseeing-i.com/ASIHTTPRequest 4 | // 5 | // Created by Ben Copsey on 01/05/2010. 6 | // Copyright 2010 All-Seeing Interactive. All rights reserved. 7 | // 8 | 9 | #import 10 | @class ASIHTTPRequest; 11 | 12 | // Cache policies control the behaviour of a cache and how requests use the cache 13 | // When setting a cache policy, you can use a combination of these values as a bitmask 14 | // For example: [request setCachePolicy:ASIAskServerIfModifiedCachePolicy|ASIFallbackToCacheIfLoadFailsCachePolicy|ASIDoNotWriteToCacheCachePolicy]; 15 | // Note that some of the behaviours below are mutally exclusive - you cannot combine ASIAskServerIfModifiedWhenStaleCachePolicy and ASIAskServerIfModifiedCachePolicy, for example. 16 | typedef enum _ASICachePolicy { 17 | 18 | // The default cache policy. When you set a request to use this, it will use the cache's defaultCachePolicy 19 | // ASIDownloadCache's default cache policy is 'ASIAskServerIfModifiedWhenStaleCachePolicy' 20 | ASIUseDefaultCachePolicy = 0, 21 | 22 | // Tell the request not to read from the cache 23 | ASIDoNotReadFromCacheCachePolicy = 1, 24 | 25 | // The the request not to write to the cache 26 | ASIDoNotWriteToCacheCachePolicy = 2, 27 | 28 | // Ask the server if there is an updated version of this resource (using a conditional GET) ONLY when the cached data is stale 29 | ASIAskServerIfModifiedWhenStaleCachePolicy = 4, 30 | 31 | // Always ask the server if there is an updated version of this resource (using a conditional GET) 32 | ASIAskServerIfModifiedCachePolicy = 8, 33 | 34 | // If cached data exists, use it even if it is stale. This means requests will not talk to the server unless the resource they are requesting is not in the cache 35 | ASIOnlyLoadIfNotCachedCachePolicy = 16, 36 | 37 | // If cached data exists, use it even if it is stale. If cached data does not exist, stop (will not set an error on the request) 38 | ASIDontLoadCachePolicy = 32, 39 | 40 | // Specifies that cached data may be used if the request fails. If cached data is used, the request will succeed without error. Usually used in combination with other options above. 41 | ASIFallbackToCacheIfLoadFailsCachePolicy = 64 42 | } ASICachePolicy; 43 | 44 | // Cache storage policies control whether cached data persists between application launches (ASICachePermanentlyCacheStoragePolicy) or not (ASICachePermanentlyCacheStoragePolicy) 45 | // Calling [ASIHTTPRequest clearSession] will remove any data stored using ASICacheForSessionDurationCacheStoragePolicy 46 | typedef enum _ASICacheStoragePolicy { 47 | ASICacheForSessionDurationCacheStoragePolicy = 0, 48 | ASICachePermanentlyCacheStoragePolicy = 1 49 | } ASICacheStoragePolicy; 50 | 51 | 52 | @protocol ASICacheDelegate 53 | 54 | @required 55 | 56 | // Should return the cache policy that will be used when requests have their cache policy set to ASIDefaultCachePolicy 57 | - (ASICachePolicy)defaultCachePolicy; 58 | 59 | - (BOOL)canUseCachedDataForRequest:(ASIHTTPRequest *)request; 60 | 61 | // Should Remove cached data for a particular request 62 | - (void)removeCachedDataForRequest:(ASIHTTPRequest *)request; 63 | 64 | // Should return YES if the cache considers its cached response current for the request 65 | // Should return NO is the data is not cached, or (for example) if the cached headers state the request should have expired 66 | - (BOOL)isCachedDataCurrentForRequest:(ASIHTTPRequest *)request; 67 | 68 | // Should store the response for the passed request in the cache 69 | // When a non-zero maxAge is passed, it should be used as the expiry time for the cached response 70 | - (void)storeResponseForRequest:(ASIHTTPRequest *)request maxAge:(NSTimeInterval)maxAge; 71 | 72 | // Should return an NSDictionary of cached headers for the passed URL, if it is stored in the cache 73 | - (NSDictionary *)cachedResponseHeadersForURL:(NSURL *)url; 74 | 75 | // Should return the cached body of a response for the passed URL, if it is stored in the cache 76 | - (NSData *)cachedResponseDataForURL:(NSURL *)url; 77 | 78 | // Returns a path to the cached response data, if it exists 79 | - (NSString *)pathToCachedResponseDataForURL:(NSURL *)url; 80 | 81 | // Returns a path to the cached response headers, if they url 82 | - (NSString *)pathToCachedResponseHeadersForURL:(NSURL *)request; 83 | 84 | // Returns the location to use to store cached response headers for a particular request 85 | - (NSString *)pathToStoreCachedResponseHeadersForRequest:(ASIHTTPRequest *)request; 86 | 87 | // Returns the location to use to store a cached response body for a particular request 88 | - (NSString *)pathToStoreCachedResponseDataForRequest:(ASIHTTPRequest *)request; 89 | 90 | // Clear cached data stored for the passed storage policy 91 | - (void)clearCachedResponsesForStoragePolicy:(ASICacheStoragePolicy)cachePolicy; 92 | 93 | @end 94 | -------------------------------------------------------------------------------- /GetexceptionalAPI/GetexceptionalAPI/external/asi-http-request/ASIDataCompressor.h: -------------------------------------------------------------------------------- 1 | // 2 | // ASIDataCompressor.h 3 | // Part of ASIHTTPRequest -> http://allseeing-i.com/ASIHTTPRequest 4 | // 5 | // Created by Ben Copsey on 17/08/2010. 6 | // Copyright 2010 All-Seeing Interactive. All rights reserved. 7 | // 8 | 9 | // This is a helper class used by ASIHTTPRequest to handle deflating (compressing) data in memory and on disk 10 | // You may also find it helpful if you need to deflate data and files yourself - see the class methods below 11 | // Most of the zlib stuff is based on the sample code by Mark Adler available at http://zlib.net 12 | 13 | #import 14 | #import 15 | 16 | @interface ASIDataCompressor : NSObject { 17 | BOOL streamReady; 18 | z_stream zStream; 19 | } 20 | 21 | // Convenience constructor will call setupStream for you 22 | + (id)compressor; 23 | 24 | // Compress the passed chunk of data 25 | // Passing YES for shouldFinish will finalize the deflated data - you must pass YES when you are on the last chunk of data 26 | - (NSData *)compressBytes:(Bytef *)bytes length:(NSUInteger)length error:(NSError **)err shouldFinish:(BOOL)shouldFinish; 27 | 28 | // Convenience method - pass it some data, and you'll get deflated data back 29 | + (NSData *)compressData:(NSData*)uncompressedData error:(NSError **)err; 30 | 31 | // Convenience method - pass it a file containing the data to compress in sourcePath, and it will write deflated data to destinationPath 32 | + (BOOL)compressDataFromFile:(NSString *)sourcePath toFile:(NSString *)destinationPath error:(NSError **)err; 33 | 34 | // Sets up zlib to handle the inflating. You only need to call this yourself if you aren't using the convenience constructor 'compressor' 35 | - (NSError *)setupStream; 36 | 37 | // Tells zlib to clean up. You need to call this if you need to cancel deflating part way through 38 | // If deflating finishes or fails, this method will be called automatically 39 | - (NSError *)closeStream; 40 | 41 | @property (assign, readonly) BOOL streamReady; 42 | @end 43 | -------------------------------------------------------------------------------- /GetexceptionalAPI/GetexceptionalAPI/external/asi-http-request/ASIDataCompressor.m: -------------------------------------------------------------------------------- 1 | // 2 | // ASIDataCompressor.m 3 | // Part of ASIHTTPRequest -> http://allseeing-i.com/ASIHTTPRequest 4 | // 5 | // Created by Ben Copsey on 17/08/2010. 6 | // Copyright 2010 All-Seeing Interactive. All rights reserved. 7 | // 8 | 9 | #import "ASIDataCompressor.h" 10 | #import "ASIHTTPRequest.h" 11 | 12 | #define DATA_CHUNK_SIZE 262144 // Deal with gzipped data in 256KB chunks 13 | #define COMPRESSION_AMOUNT Z_DEFAULT_COMPRESSION 14 | 15 | @interface ASIDataCompressor () 16 | + (NSError *)deflateErrorWithCode:(int)code; 17 | @end 18 | 19 | @implementation ASIDataCompressor 20 | 21 | + (id)compressor 22 | { 23 | ASIDataCompressor *compressor = [[[self alloc] init] autorelease]; 24 | [compressor setupStream]; 25 | return compressor; 26 | } 27 | 28 | - (void)dealloc 29 | { 30 | if (streamReady) { 31 | [self closeStream]; 32 | } 33 | [super dealloc]; 34 | } 35 | 36 | - (NSError *)setupStream 37 | { 38 | if (streamReady) { 39 | return nil; 40 | } 41 | // Setup the inflate stream 42 | zStream.zalloc = Z_NULL; 43 | zStream.zfree = Z_NULL; 44 | zStream.opaque = Z_NULL; 45 | zStream.avail_in = 0; 46 | zStream.next_in = 0; 47 | int status = deflateInit2(&zStream, COMPRESSION_AMOUNT, Z_DEFLATED, (15+16), 8, Z_DEFAULT_STRATEGY); 48 | if (status != Z_OK) { 49 | return [[self class] deflateErrorWithCode:status]; 50 | } 51 | streamReady = YES; 52 | return nil; 53 | } 54 | 55 | - (NSError *)closeStream 56 | { 57 | if (!streamReady) { 58 | return nil; 59 | } 60 | // Close the deflate stream 61 | streamReady = NO; 62 | int status = deflateEnd(&zStream); 63 | if (status != Z_OK) { 64 | return [[self class] deflateErrorWithCode:status]; 65 | } 66 | return nil; 67 | } 68 | 69 | - (NSData *)compressBytes:(Bytef *)bytes length:(NSUInteger)length error:(NSError **)err shouldFinish:(BOOL)shouldFinish 70 | { 71 | if (length == 0) return nil; 72 | 73 | NSUInteger halfLength = length/2; 74 | 75 | // We'll take a guess that the compressed data will fit in half the size of the original (ie the max to compress at once is half DATA_CHUNK_SIZE), if not, we'll increase it below 76 | NSMutableData *outputData = [NSMutableData dataWithLength:length/2]; 77 | 78 | int status; 79 | 80 | zStream.next_in = bytes; 81 | zStream.avail_in = (unsigned int)length; 82 | zStream.avail_out = 0; 83 | NSError *theError = nil; 84 | 85 | NSInteger bytesProcessedAlready = zStream.total_out; 86 | while (zStream.avail_out == 0) { 87 | 88 | if (zStream.total_out-bytesProcessedAlready >= [outputData length]) { 89 | [outputData increaseLengthBy:halfLength]; 90 | } 91 | 92 | zStream.next_out = [outputData mutableBytes] + zStream.total_out-bytesProcessedAlready; 93 | zStream.avail_out = (unsigned int)([outputData length] - (zStream.total_out-bytesProcessedAlready)); 94 | status = deflate(&zStream, shouldFinish ? Z_FINISH : Z_NO_FLUSH); 95 | 96 | if (status == Z_STREAM_END) { 97 | break; 98 | } else if (status != Z_OK) { 99 | if (err) { 100 | *err = [[self class] deflateErrorWithCode:status]; 101 | } 102 | return NO; 103 | } 104 | } 105 | 106 | if (theError) { 107 | if (err) { 108 | *err = theError; 109 | } 110 | return nil; 111 | } 112 | 113 | // Set real length 114 | [outputData setLength: zStream.total_out-bytesProcessedAlready]; 115 | return outputData; 116 | } 117 | 118 | 119 | + (NSData *)compressData:(NSData*)uncompressedData error:(NSError **)err 120 | { 121 | NSError *theError = nil; 122 | NSData *outputData = [[ASIDataCompressor compressor] compressBytes:(Bytef *)[uncompressedData bytes] length:[uncompressedData length] error:&theError shouldFinish:YES]; 123 | if (theError) { 124 | if (err) { 125 | *err = theError; 126 | } 127 | return nil; 128 | } 129 | return outputData; 130 | } 131 | 132 | 133 | 134 | + (BOOL)compressDataFromFile:(NSString *)sourcePath toFile:(NSString *)destinationPath error:(NSError **)err 135 | { 136 | NSFileManager *fileManager = [[[NSFileManager alloc] init] autorelease]; 137 | 138 | // Create an empty file at the destination path 139 | if (![fileManager createFileAtPath:destinationPath contents:[NSData data] attributes:nil]) { 140 | if (err) { 141 | *err = [NSError errorWithDomain:NetworkRequestErrorDomain code:ASICompressionError userInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithFormat:@"Compression of %@ failed because we were to create a file at %@",sourcePath,destinationPath],NSLocalizedDescriptionKey,nil]]; 142 | } 143 | return NO; 144 | } 145 | 146 | // Ensure the source file exists 147 | if (![fileManager fileExistsAtPath:sourcePath]) { 148 | if (err) { 149 | *err = [NSError errorWithDomain:NetworkRequestErrorDomain code:ASICompressionError userInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithFormat:@"Compression of %@ failed the file does not exist",sourcePath],NSLocalizedDescriptionKey,nil]]; 150 | } 151 | return NO; 152 | } 153 | 154 | UInt8 inputData[DATA_CHUNK_SIZE]; 155 | NSData *outputData; 156 | NSInteger readLength; 157 | NSError *theError = nil; 158 | 159 | ASIDataCompressor *compressor = [ASIDataCompressor compressor]; 160 | 161 | NSInputStream *inputStream = [NSInputStream inputStreamWithFileAtPath:sourcePath]; 162 | [inputStream open]; 163 | NSOutputStream *outputStream = [NSOutputStream outputStreamToFileAtPath:destinationPath append:NO]; 164 | [outputStream open]; 165 | 166 | while ([compressor streamReady]) { 167 | 168 | // Read some data from the file 169 | readLength = [inputStream read:inputData maxLength:DATA_CHUNK_SIZE]; 170 | 171 | // Make sure nothing went wrong 172 | if ([inputStream streamStatus] == NSStreamEventErrorOccurred) { 173 | if (err) { 174 | *err = [NSError errorWithDomain:NetworkRequestErrorDomain code:ASICompressionError userInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithFormat:@"Compression of %@ failed because we were unable to read from the source data file",sourcePath],NSLocalizedDescriptionKey,[inputStream streamError],NSUnderlyingErrorKey,nil]]; 175 | } 176 | [compressor closeStream]; 177 | return NO; 178 | } 179 | // Have we reached the end of the input data? 180 | if (!readLength) { 181 | break; 182 | } 183 | 184 | // Attempt to deflate the chunk of data 185 | outputData = [compressor compressBytes:inputData length:readLength error:&theError shouldFinish:readLength < DATA_CHUNK_SIZE ]; 186 | if (theError) { 187 | if (err) { 188 | *err = theError; 189 | } 190 | [compressor closeStream]; 191 | return NO; 192 | } 193 | 194 | // Write the deflated data out to the destination file 195 | [outputStream write:[outputData bytes] maxLength:[outputData length]]; 196 | 197 | // Make sure nothing went wrong 198 | if ([inputStream streamStatus] == NSStreamEventErrorOccurred) { 199 | if (err) { 200 | *err = [NSError errorWithDomain:NetworkRequestErrorDomain code:ASICompressionError userInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithFormat:@"Compression of %@ failed because we were unable to write to the destination data file at &@",sourcePath,destinationPath],NSLocalizedDescriptionKey,[outputStream streamError],NSUnderlyingErrorKey,nil]]; 201 | } 202 | [compressor closeStream]; 203 | return NO; 204 | } 205 | 206 | } 207 | [inputStream close]; 208 | [outputStream close]; 209 | 210 | NSError *error = [compressor closeStream]; 211 | if (error) { 212 | if (err) { 213 | *err = error; 214 | } 215 | return NO; 216 | } 217 | 218 | return YES; 219 | } 220 | 221 | + (NSError *)deflateErrorWithCode:(int)code 222 | { 223 | return [NSError errorWithDomain:NetworkRequestErrorDomain code:ASICompressionError userInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithFormat:@"Compression of data failed with code %hi",code],NSLocalizedDescriptionKey,nil]]; 224 | } 225 | 226 | @synthesize streamReady; 227 | @end 228 | -------------------------------------------------------------------------------- /GetexceptionalAPI/GetexceptionalAPI/external/asi-http-request/ASIDataDecompressor.h: -------------------------------------------------------------------------------- 1 | // 2 | // ASIDataDecompressor.h 3 | // Part of ASIHTTPRequest -> http://allseeing-i.com/ASIHTTPRequest 4 | // 5 | // Created by Ben Copsey on 17/08/2010. 6 | // Copyright 2010 All-Seeing Interactive. All rights reserved. 7 | // 8 | 9 | // This is a helper class used by ASIHTTPRequest to handle inflating (decompressing) data in memory and on disk 10 | // You may also find it helpful if you need to inflate data and files yourself - see the class methods below 11 | // Most of the zlib stuff is based on the sample code by Mark Adler available at http://zlib.net 12 | 13 | #import 14 | #import 15 | 16 | @interface ASIDataDecompressor : NSObject { 17 | BOOL streamReady; 18 | z_stream zStream; 19 | } 20 | 21 | // Convenience constructor will call setupStream for you 22 | + (id)decompressor; 23 | 24 | // Uncompress the passed chunk of data 25 | - (NSData *)uncompressBytes:(Bytef *)bytes length:(NSUInteger)length error:(NSError **)err; 26 | 27 | // Convenience method - pass it some deflated data, and you'll get inflated data back 28 | + (NSData *)uncompressData:(NSData*)compressedData error:(NSError **)err; 29 | 30 | // Convenience method - pass it a file containing deflated data in sourcePath, and it will write inflated data to destinationPath 31 | + (BOOL)uncompressDataFromFile:(NSString *)sourcePath toFile:(NSString *)destinationPath error:(NSError **)err; 32 | 33 | // Sets up zlib to handle the inflating. You only need to call this yourself if you aren't using the convenience constructor 'decompressor' 34 | - (NSError *)setupStream; 35 | 36 | // Tells zlib to clean up. You need to call this if you need to cancel inflating part way through 37 | // If inflating finishes or fails, this method will be called automatically 38 | - (NSError *)closeStream; 39 | 40 | @property (assign, readonly) BOOL streamReady; 41 | @end 42 | -------------------------------------------------------------------------------- /GetexceptionalAPI/GetexceptionalAPI/external/asi-http-request/ASIDataDecompressor.m: -------------------------------------------------------------------------------- 1 | // 2 | // ASIDataDecompressor.m 3 | // Part of ASIHTTPRequest -> http://allseeing-i.com/ASIHTTPRequest 4 | // 5 | // Created by Ben Copsey on 17/08/2010. 6 | // Copyright 2010 All-Seeing Interactive. All rights reserved. 7 | // 8 | 9 | #import "ASIDataDecompressor.h" 10 | #import "ASIHTTPRequest.h" 11 | 12 | #define DATA_CHUNK_SIZE 262144 // Deal with gzipped data in 256KB chunks 13 | 14 | @interface ASIDataDecompressor () 15 | + (NSError *)inflateErrorWithCode:(int)code; 16 | @end; 17 | 18 | @implementation ASIDataDecompressor 19 | 20 | + (id)decompressor 21 | { 22 | ASIDataDecompressor *decompressor = [[[self alloc] init] autorelease]; 23 | [decompressor setupStream]; 24 | return decompressor; 25 | } 26 | 27 | - (void)dealloc 28 | { 29 | if (streamReady) { 30 | [self closeStream]; 31 | } 32 | [super dealloc]; 33 | } 34 | 35 | - (NSError *)setupStream 36 | { 37 | if (streamReady) { 38 | return nil; 39 | } 40 | // Setup the inflate stream 41 | zStream.zalloc = Z_NULL; 42 | zStream.zfree = Z_NULL; 43 | zStream.opaque = Z_NULL; 44 | zStream.avail_in = 0; 45 | zStream.next_in = 0; 46 | int status = inflateInit2(&zStream, (15+32)); 47 | if (status != Z_OK) { 48 | return [[self class] inflateErrorWithCode:status]; 49 | } 50 | streamReady = YES; 51 | return nil; 52 | } 53 | 54 | - (NSError *)closeStream 55 | { 56 | if (!streamReady) { 57 | return nil; 58 | } 59 | // Close the inflate stream 60 | streamReady = NO; 61 | int status = inflateEnd(&zStream); 62 | if (status != Z_OK) { 63 | return [[self class] inflateErrorWithCode:status]; 64 | } 65 | return nil; 66 | } 67 | 68 | - (NSData *)uncompressBytes:(Bytef *)bytes length:(NSUInteger)length error:(NSError **)err 69 | { 70 | if (length == 0) return nil; 71 | 72 | NSUInteger halfLength = length/2; 73 | NSMutableData *outputData = [NSMutableData dataWithLength:length+halfLength]; 74 | 75 | int status; 76 | 77 | zStream.next_in = bytes; 78 | zStream.avail_in = (unsigned int)length; 79 | zStream.avail_out = 0; 80 | NSError *theError = nil; 81 | 82 | NSInteger bytesProcessedAlready = zStream.total_out; 83 | while (zStream.avail_out == 0) { 84 | 85 | if (zStream.total_out-bytesProcessedAlready >= [outputData length]) { 86 | [outputData increaseLengthBy:halfLength]; 87 | } 88 | 89 | zStream.next_out = [outputData mutableBytes] + zStream.total_out-bytesProcessedAlready; 90 | zStream.avail_out = (unsigned int)([outputData length] - (zStream.total_out-bytesProcessedAlready)); 91 | 92 | status = inflate(&zStream, Z_NO_FLUSH); 93 | 94 | if (status == Z_STREAM_END) { 95 | break; 96 | } else if (status != Z_OK) { 97 | if (err) { 98 | *err = [[self class] inflateErrorWithCode:status]; 99 | } 100 | return nil; 101 | } 102 | } 103 | 104 | if (theError) { 105 | if (err) { 106 | *err = theError; 107 | } 108 | return nil; 109 | } 110 | 111 | // Set real length 112 | [outputData setLength: zStream.total_out-bytesProcessedAlready]; 113 | return outputData; 114 | } 115 | 116 | 117 | + (NSData *)uncompressData:(NSData*)compressedData error:(NSError **)err 118 | { 119 | NSError *theError = nil; 120 | NSData *outputData = [[ASIDataDecompressor decompressor] uncompressBytes:(Bytef *)[compressedData bytes] length:[compressedData length] error:&theError]; 121 | if (theError) { 122 | if (err) { 123 | *err = theError; 124 | } 125 | return nil; 126 | } 127 | return outputData; 128 | } 129 | 130 | + (BOOL)uncompressDataFromFile:(NSString *)sourcePath toFile:(NSString *)destinationPath error:(NSError **)err 131 | { 132 | NSFileManager *fileManager = [[[NSFileManager alloc] init] autorelease]; 133 | 134 | // Create an empty file at the destination path 135 | if (![fileManager createFileAtPath:destinationPath contents:[NSData data] attributes:nil]) { 136 | if (err) { 137 | *err = [NSError errorWithDomain:NetworkRequestErrorDomain code:ASICompressionError userInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithFormat:@"Decompression of %@ failed because we were to create a file at %@",sourcePath,destinationPath],NSLocalizedDescriptionKey,nil]]; 138 | } 139 | return NO; 140 | } 141 | 142 | // Ensure the source file exists 143 | if (![fileManager fileExistsAtPath:sourcePath]) { 144 | if (err) { 145 | *err = [NSError errorWithDomain:NetworkRequestErrorDomain code:ASICompressionError userInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithFormat:@"Decompression of %@ failed the file does not exist",sourcePath],NSLocalizedDescriptionKey,nil]]; 146 | } 147 | return NO; 148 | } 149 | 150 | UInt8 inputData[DATA_CHUNK_SIZE]; 151 | NSData *outputData; 152 | NSInteger readLength; 153 | NSError *theError = nil; 154 | 155 | 156 | ASIDataDecompressor *decompressor = [ASIDataDecompressor decompressor]; 157 | 158 | NSInputStream *inputStream = [NSInputStream inputStreamWithFileAtPath:sourcePath]; 159 | [inputStream open]; 160 | NSOutputStream *outputStream = [NSOutputStream outputStreamToFileAtPath:destinationPath append:NO]; 161 | [outputStream open]; 162 | 163 | while ([decompressor streamReady]) { 164 | 165 | // Read some data from the file 166 | readLength = [inputStream read:inputData maxLength:DATA_CHUNK_SIZE]; 167 | 168 | // Make sure nothing went wrong 169 | if ([inputStream streamStatus] == NSStreamEventErrorOccurred) { 170 | if (err) { 171 | *err = [NSError errorWithDomain:NetworkRequestErrorDomain code:ASICompressionError userInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithFormat:@"Decompression of %@ failed because we were unable to read from the source data file",sourcePath],NSLocalizedDescriptionKey,[inputStream streamError],NSUnderlyingErrorKey,nil]]; 172 | } 173 | [decompressor closeStream]; 174 | return NO; 175 | } 176 | // Have we reached the end of the input data? 177 | if (!readLength) { 178 | break; 179 | } 180 | 181 | // Attempt to inflate the chunk of data 182 | outputData = [decompressor uncompressBytes:inputData length:readLength error:&theError]; 183 | if (theError) { 184 | if (err) { 185 | *err = theError; 186 | } 187 | [decompressor closeStream]; 188 | return NO; 189 | } 190 | 191 | // Write the inflated data out to the destination file 192 | [outputStream write:[outputData bytes] maxLength:[outputData length]]; 193 | 194 | // Make sure nothing went wrong 195 | if ([inputStream streamStatus] == NSStreamEventErrorOccurred) { 196 | if (err) { 197 | *err = [NSError errorWithDomain:NetworkRequestErrorDomain code:ASICompressionError userInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithFormat:@"Decompression of %@ failed because we were unable to write to the destination data file at &@",sourcePath,destinationPath],NSLocalizedDescriptionKey,[outputStream streamError],NSUnderlyingErrorKey,nil]]; 198 | } 199 | [decompressor closeStream]; 200 | return NO; 201 | } 202 | 203 | } 204 | 205 | [inputStream close]; 206 | [outputStream close]; 207 | 208 | NSError *error = [decompressor closeStream]; 209 | if (error) { 210 | if (err) { 211 | *err = error; 212 | } 213 | return NO; 214 | } 215 | 216 | return YES; 217 | } 218 | 219 | 220 | + (NSError *)inflateErrorWithCode:(int)code 221 | { 222 | return [NSError errorWithDomain:NetworkRequestErrorDomain code:ASICompressionError userInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithFormat:@"Decompression of data failed with code %hi",code],NSLocalizedDescriptionKey,nil]]; 223 | } 224 | 225 | @synthesize streamReady; 226 | @end 227 | -------------------------------------------------------------------------------- /GetexceptionalAPI/GetexceptionalAPI/external/asi-http-request/ASIDownloadCache.h: -------------------------------------------------------------------------------- 1 | // 2 | // ASIDownloadCache.h 3 | // Part of ASIHTTPRequest -> http://allseeing-i.com/ASIHTTPRequest 4 | // 5 | // Created by Ben Copsey on 01/05/2010. 6 | // Copyright 2010 All-Seeing Interactive. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "ASICacheDelegate.h" 11 | 12 | @interface ASIDownloadCache : NSObject { 13 | 14 | // The default cache policy for this cache 15 | // Requests that store data in the cache will use this cache policy if their cache policy is set to ASIDefaultCachePolicy 16 | // Defaults to ASIReloadIfDifferentCachePolicy 17 | ASICachePolicy defaultCachePolicy; 18 | 19 | // The directory in which cached data will be stored 20 | // Defaults to a directory called 'ASIHTTPRequestCache' in the temporary directory 21 | NSString *storagePath; 22 | 23 | // Mediates access to the cache 24 | NSRecursiveLock *accessLock; 25 | 26 | // When YES, the cache will look for cache-control / pragma: no-cache headers, and won't reuse store responses if it finds them 27 | BOOL shouldRespectCacheControlHeaders; 28 | } 29 | 30 | // Returns a static instance of an ASIDownloadCache 31 | // In most circumstances, it will make sense to use this as a global cache, rather than creating your own cache 32 | // To make ASIHTTPRequests use it automatically, use [ASIHTTPRequest setDefaultCache:[ASIDownloadCache sharedCache]]; 33 | + (id)sharedCache; 34 | 35 | // A helper function that determines if the server has requested data should not be cached by looking at the request's response headers 36 | + (BOOL)serverAllowsResponseCachingForRequest:(ASIHTTPRequest *)request; 37 | 38 | // A date formatter that can be used to construct an RFC 1123 date 39 | // The returned formatter is safe to use on the calling thread 40 | // Do not use this formatter for parsing dates because the format can vary slightly - use ASIHTTPRequest's dateFromRFC1123String: class method instead 41 | + (NSDateFormatter *)rfc1123DateFormatter; 42 | 43 | @property (assign, nonatomic) ASICachePolicy defaultCachePolicy; 44 | @property (retain, nonatomic) NSString *storagePath; 45 | @property (retain) NSRecursiveLock *accessLock; 46 | @property (assign) BOOL shouldRespectCacheControlHeaders; 47 | @end 48 | -------------------------------------------------------------------------------- /GetexceptionalAPI/GetexceptionalAPI/external/asi-http-request/ASIFormDataRequest.h: -------------------------------------------------------------------------------- 1 | // 2 | // ASIFormDataRequest.h 3 | // Part of ASIHTTPRequest -> http://allseeing-i.com/ASIHTTPRequest 4 | // 5 | // Created by Ben Copsey on 07/11/2008. 6 | // Copyright 2008-2009 All-Seeing Interactive. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "ASIHTTPRequest.h" 11 | #import "ASIHTTPRequestConfig.h" 12 | 13 | typedef enum _ASIPostFormat { 14 | ASIMultipartFormDataPostFormat = 0, 15 | ASIURLEncodedPostFormat = 1 16 | 17 | } ASIPostFormat; 18 | 19 | @interface ASIFormDataRequest : ASIHTTPRequest { 20 | 21 | // Parameters that will be POSTed to the url 22 | NSMutableArray *postData; 23 | 24 | // Files that will be POSTed to the url 25 | NSMutableArray *fileData; 26 | 27 | ASIPostFormat postFormat; 28 | 29 | NSStringEncoding stringEncoding; 30 | 31 | #if DEBUG_FORM_DATA_REQUEST 32 | // Will store a string version of the request body that will be printed to the console when ASIHTTPREQUEST_DEBUG is set in GCC_PREPROCESSOR_DEFINITIONS 33 | NSString *debugBodyString; 34 | #endif 35 | 36 | } 37 | 38 | #pragma mark utilities 39 | - (NSString*)encodeURL:(NSString *)string; 40 | 41 | #pragma mark setup request 42 | 43 | // Add a POST variable to the request 44 | - (void)addPostValue:(id )value forKey:(NSString *)key; 45 | 46 | // Set a POST variable for this request, clearing any others with the same key 47 | - (void)setPostValue:(id )value forKey:(NSString *)key; 48 | 49 | // Add the contents of a local file to the request 50 | - (void)addFile:(NSString *)filePath forKey:(NSString *)key; 51 | 52 | // Same as above, but you can specify the content-type and file name 53 | - (void)addFile:(id)data withFileName:(NSString *)fileName andContentType:(NSString *)contentType forKey:(NSString *)key; 54 | 55 | // Add the contents of a local file to the request, clearing any others with the same key 56 | - (void)setFile:(NSString *)filePath forKey:(NSString *)key; 57 | 58 | // Same as above, but you can specify the content-type and file name 59 | - (void)setFile:(id)data withFileName:(NSString *)fileName andContentType:(NSString *)contentType forKey:(NSString *)key; 60 | 61 | // Add the contents of an NSData object to the request 62 | - (void)addData:(NSData *)data forKey:(NSString *)key; 63 | 64 | // Same as above, but you can specify the content-type and file name 65 | - (void)addData:(id)data withFileName:(NSString *)fileName andContentType:(NSString *)contentType forKey:(NSString *)key; 66 | 67 | // Add the contents of an NSData object to the request, clearing any others with the same key 68 | - (void)setData:(NSData *)data forKey:(NSString *)key; 69 | 70 | // Same as above, but you can specify the content-type and file name 71 | - (void)setData:(id)data withFileName:(NSString *)fileName andContentType:(NSString *)contentType forKey:(NSString *)key; 72 | 73 | 74 | @property (assign) ASIPostFormat postFormat; 75 | @property (assign) NSStringEncoding stringEncoding; 76 | @end 77 | -------------------------------------------------------------------------------- /GetexceptionalAPI/GetexceptionalAPI/external/asi-http-request/ASIFormDataRequest.m: -------------------------------------------------------------------------------- 1 | // 2 | // ASIFormDataRequest.m 3 | // Part of ASIHTTPRequest -> http://allseeing-i.com/ASIHTTPRequest 4 | // 5 | // Created by Ben Copsey on 07/11/2008. 6 | // Copyright 2008-2009 All-Seeing Interactive. All rights reserved. 7 | // 8 | 9 | #import "ASIFormDataRequest.h" 10 | 11 | 12 | // Private stuff 13 | @interface ASIFormDataRequest () 14 | - (void)buildMultipartFormDataPostBody; 15 | - (void)buildURLEncodedPostBody; 16 | - (void)appendPostString:(NSString *)string; 17 | 18 | @property (retain) NSMutableArray *postData; 19 | @property (retain) NSMutableArray *fileData; 20 | 21 | #if DEBUG_FORM_DATA_REQUEST 22 | - (void)addToDebugBody:(NSString *)string; 23 | @property (retain, nonatomic) NSString *debugBodyString; 24 | #endif 25 | 26 | @end 27 | 28 | @implementation ASIFormDataRequest 29 | 30 | #pragma mark utilities 31 | - (NSString*)encodeURL:(NSString *)string 32 | { 33 | NSString *newString = NSMakeCollectable([(NSString *)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)string, NULL, CFSTR(":/?#[]@!$ &'()*+,;=\"<>%{}|\\^~`"), CFStringConvertNSStringEncodingToEncoding([self stringEncoding])) autorelease]); 34 | if (newString) { 35 | return newString; 36 | } 37 | return @""; 38 | } 39 | 40 | #pragma mark init / dealloc 41 | 42 | + (id)requestWithURL:(NSURL *)newURL 43 | { 44 | return [[[self alloc] initWithURL:newURL] autorelease]; 45 | } 46 | 47 | - (id)initWithURL:(NSURL *)newURL 48 | { 49 | self = [super initWithURL:newURL]; 50 | [self setPostFormat:ASIURLEncodedPostFormat]; 51 | [self setStringEncoding:NSUTF8StringEncoding]; 52 | return self; 53 | } 54 | 55 | - (void)dealloc 56 | { 57 | #if DEBUG_FORM_DATA_REQUEST 58 | [debugBodyString release]; 59 | #endif 60 | 61 | [postData release]; 62 | [fileData release]; 63 | [super dealloc]; 64 | } 65 | 66 | #pragma mark setup request 67 | 68 | - (void)addPostValue:(id )value forKey:(NSString *)key 69 | { 70 | if (![self postData]) { 71 | [self setPostData:[NSMutableArray array]]; 72 | } 73 | [[self postData] addObject:[NSDictionary dictionaryWithObjectsAndKeys:[value description],@"value",key,@"key",nil]]; 74 | } 75 | 76 | - (void)setPostValue:(id )value forKey:(NSString *)key 77 | { 78 | // Remove any existing value 79 | NSUInteger i; 80 | for (i=0; i<[[self postData] count]; i++) { 81 | NSDictionary *val = [[self postData] objectAtIndex:i]; 82 | if ([[val objectForKey:@"key"] isEqualToString:key]) { 83 | [[self postData] removeObjectAtIndex:i]; 84 | i--; 85 | } 86 | } 87 | [self addPostValue:value forKey:key]; 88 | } 89 | 90 | 91 | - (void)addFile:(NSString *)filePath forKey:(NSString *)key 92 | { 93 | [self addFile:filePath withFileName:nil andContentType:nil forKey:key]; 94 | } 95 | 96 | - (void)addFile:(id)data withFileName:(NSString *)fileName andContentType:(NSString *)contentType forKey:(NSString *)key 97 | { 98 | if (![self fileData]) { 99 | [self setFileData:[NSMutableArray array]]; 100 | } 101 | 102 | // If data is a path to a local file 103 | if ([data isKindOfClass:[NSString class]]) { 104 | BOOL isDirectory = NO; 105 | BOOL fileExists = [[[[NSFileManager alloc] init] autorelease] fileExistsAtPath:(NSString *)data isDirectory:&isDirectory]; 106 | if (!fileExists || isDirectory) { 107 | [self failWithError:[NSError errorWithDomain:NetworkRequestErrorDomain code:ASIInternalErrorWhileBuildingRequestType userInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithFormat:@"No file exists at %@",data],NSLocalizedDescriptionKey,nil]]]; 108 | } 109 | 110 | // If the caller didn't specify a custom file name, we'll use the file name of the file we were passed 111 | if (!fileName) { 112 | fileName = [(NSString *)data lastPathComponent]; 113 | } 114 | 115 | // If we were given the path to a file, and the user didn't specify a mime type, we can detect it from the file extension 116 | if (!contentType) { 117 | contentType = [ASIHTTPRequest mimeTypeForFileAtPath:data]; 118 | } 119 | } 120 | 121 | NSDictionary *fileInfo = [NSDictionary dictionaryWithObjectsAndKeys:data, @"data", contentType, @"contentType", fileName, @"fileName", key, @"key", nil]; 122 | [[self fileData] addObject:fileInfo]; 123 | } 124 | 125 | 126 | - (void)setFile:(NSString *)filePath forKey:(NSString *)key 127 | { 128 | [self setFile:filePath withFileName:nil andContentType:nil forKey:key]; 129 | } 130 | 131 | - (void)setFile:(id)data withFileName:(NSString *)fileName andContentType:(NSString *)contentType forKey:(NSString *)key 132 | { 133 | // Remove any existing value 134 | NSUInteger i; 135 | for (i=0; i<[[self fileData] count]; i++) { 136 | NSDictionary *val = [[self fileData] objectAtIndex:i]; 137 | if ([[val objectForKey:@"key"] isEqualToString:key]) { 138 | [[self fileData] removeObjectAtIndex:i]; 139 | i--; 140 | } 141 | } 142 | [self addFile:data withFileName:fileName andContentType:contentType forKey:key]; 143 | } 144 | 145 | - (void)addData:(NSData *)data forKey:(NSString *)key 146 | { 147 | [self addData:data withFileName:@"file" andContentType:nil forKey:key]; 148 | } 149 | 150 | - (void)addData:(id)data withFileName:(NSString *)fileName andContentType:(NSString *)contentType forKey:(NSString *)key 151 | { 152 | if (![self fileData]) { 153 | [self setFileData:[NSMutableArray array]]; 154 | } 155 | if (!contentType) { 156 | contentType = @"application/octet-stream"; 157 | } 158 | 159 | NSDictionary *fileInfo = [NSDictionary dictionaryWithObjectsAndKeys:data, @"data", contentType, @"contentType", fileName, @"fileName", key, @"key", nil]; 160 | [[self fileData] addObject:fileInfo]; 161 | } 162 | 163 | - (void)setData:(NSData *)data forKey:(NSString *)key 164 | { 165 | [self setData:data withFileName:@"file" andContentType:nil forKey:key]; 166 | } 167 | 168 | - (void)setData:(id)data withFileName:(NSString *)fileName andContentType:(NSString *)contentType forKey:(NSString *)key 169 | { 170 | // Remove any existing value 171 | NSUInteger i; 172 | for (i=0; i<[[self fileData] count]; i++) { 173 | NSDictionary *val = [[self fileData] objectAtIndex:i]; 174 | if ([[val objectForKey:@"key"] isEqualToString:key]) { 175 | [[self fileData] removeObjectAtIndex:i]; 176 | i--; 177 | } 178 | } 179 | [self addData:data withFileName:fileName andContentType:contentType forKey:key]; 180 | } 181 | 182 | - (void)buildPostBody 183 | { 184 | if ([self haveBuiltPostBody]) { 185 | return; 186 | } 187 | 188 | #if DEBUG_FORM_DATA_REQUEST 189 | [self setDebugBodyString:@""]; 190 | #endif 191 | 192 | if (![self postData] && ![self fileData]) { 193 | [super buildPostBody]; 194 | return; 195 | } 196 | if ([[self fileData] count] > 0) { 197 | [self setShouldStreamPostDataFromDisk:YES]; 198 | } 199 | 200 | if ([self postFormat] == ASIURLEncodedPostFormat) { 201 | [self buildURLEncodedPostBody]; 202 | } else { 203 | [self buildMultipartFormDataPostBody]; 204 | } 205 | 206 | [super buildPostBody]; 207 | 208 | #if DEBUG_FORM_DATA_REQUEST 209 | NSLog(@"%@",[self debugBodyString]); 210 | [self setDebugBodyString:nil]; 211 | #endif 212 | } 213 | 214 | 215 | - (void)buildMultipartFormDataPostBody 216 | { 217 | #if DEBUG_FORM_DATA_REQUEST 218 | [self addToDebugBody:@"\r\n==== Building a multipart/form-data body ====\r\n"]; 219 | #endif 220 | 221 | NSString *charset = (NSString *)CFStringConvertEncodingToIANACharSetName(CFStringConvertNSStringEncodingToEncoding([self stringEncoding])); 222 | 223 | // Set your own boundary string only if really obsessive. We don't bother to check if post data contains the boundary, since it's pretty unlikely that it does. 224 | NSString *stringBoundary = @"0xKhTmLbOuNdArY"; 225 | 226 | [self addRequestHeader:@"Content-Type" value:[NSString stringWithFormat:@"multipart/form-data; charset=%@; boundary=%@", charset, stringBoundary]]; 227 | 228 | [self appendPostString:[NSString stringWithFormat:@"--%@\r\n",stringBoundary]]; 229 | 230 | // Adds post data 231 | NSString *endItemBoundary = [NSString stringWithFormat:@"\r\n--%@\r\n",stringBoundary]; 232 | NSUInteger i=0; 233 | for (NSDictionary *val in [self postData]) { 234 | [self appendPostString:[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n",[val objectForKey:@"key"]]]; 235 | [self appendPostString:[val objectForKey:@"value"]]; 236 | i++; 237 | if (i != [[self postData] count] || [[self fileData] count] > 0) { //Only add the boundary if this is not the last item in the post body 238 | [self appendPostString:endItemBoundary]; 239 | } 240 | } 241 | 242 | // Adds files to upload 243 | i=0; 244 | for (NSDictionary *val in [self fileData]) { 245 | 246 | [self appendPostString:[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"%@\"\r\n", [val objectForKey:@"key"], [val objectForKey:@"fileName"]]]; 247 | [self appendPostString:[NSString stringWithFormat:@"Content-Type: %@\r\n\r\n", [val objectForKey:@"contentType"]]]; 248 | 249 | id data = [val objectForKey:@"data"]; 250 | if ([data isKindOfClass:[NSString class]]) { 251 | [self appendPostDataFromFile:data]; 252 | } else { 253 | [self appendPostData:data]; 254 | } 255 | i++; 256 | // Only add the boundary if this is not the last item in the post body 257 | if (i != [[self fileData] count]) { 258 | [self appendPostString:endItemBoundary]; 259 | } 260 | } 261 | 262 | [self appendPostString:[NSString stringWithFormat:@"\r\n--%@--\r\n",stringBoundary]]; 263 | 264 | #if DEBUG_FORM_DATA_REQUEST 265 | [self addToDebugBody:@"==== End of multipart/form-data body ====\r\n"]; 266 | #endif 267 | } 268 | 269 | - (void)buildURLEncodedPostBody 270 | { 271 | 272 | // We can't post binary data using application/x-www-form-urlencoded 273 | if ([[self fileData] count] > 0) { 274 | [self setPostFormat:ASIMultipartFormDataPostFormat]; 275 | [self buildMultipartFormDataPostBody]; 276 | return; 277 | } 278 | 279 | #if DEBUG_FORM_DATA_REQUEST 280 | [self addToDebugBody:@"\r\n==== Building an application/x-www-form-urlencoded body ====\r\n"]; 281 | #endif 282 | 283 | 284 | NSString *charset = (NSString *)CFStringConvertEncodingToIANACharSetName(CFStringConvertNSStringEncodingToEncoding([self stringEncoding])); 285 | 286 | [self addRequestHeader:@"Content-Type" value:[NSString stringWithFormat:@"application/x-www-form-urlencoded; charset=%@",charset]]; 287 | 288 | 289 | NSUInteger i=0; 290 | NSUInteger count = [[self postData] count]-1; 291 | for (NSDictionary *val in [self postData]) { 292 | NSString *data = [NSString stringWithFormat:@"%@=%@%@", [self encodeURL:[val objectForKey:@"key"]], [self encodeURL:[val objectForKey:@"value"]],(i http://allseeing-i.com/ASIHTTPRequest 4 | // 5 | // Created by Ben Copsey on 14/12/2009. 6 | // Copyright 2009 All-Seeing Interactive. All rights reserved. 7 | // 8 | 9 | 10 | // ====== 11 | // Debug output configuration options 12 | // ====== 13 | 14 | // When set to 1 ASIHTTPRequests will print information about what a request is doing 15 | #ifndef DEBUG_REQUEST_STATUS 16 | #define DEBUG_REQUEST_STATUS 0 17 | #endif 18 | 19 | // When set to 1, ASIFormDataRequests will print information about the request body to the console 20 | #ifndef DEBUG_FORM_DATA_REQUEST 21 | #define DEBUG_FORM_DATA_REQUEST 0 22 | #endif 23 | 24 | // When set to 1, ASIHTTPRequests will print information about bandwidth throttling to the console 25 | #ifndef DEBUG_THROTTLING 26 | #define DEBUG_THROTTLING 0 27 | #endif 28 | 29 | // When set to 1, ASIHTTPRequests will print information about persistent connections to the console 30 | #ifndef DEBUG_PERSISTENT_CONNECTIONS 31 | #define DEBUG_PERSISTENT_CONNECTIONS 0 32 | #endif 33 | -------------------------------------------------------------------------------- /GetexceptionalAPI/GetexceptionalAPI/external/asi-http-request/ASIHTTPRequestDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // ASIHTTPRequestDelegate.h 3 | // Part of ASIHTTPRequest -> http://allseeing-i.com/ASIHTTPRequest 4 | // 5 | // Created by Ben Copsey on 13/04/2010. 6 | // Copyright 2010 All-Seeing Interactive. All rights reserved. 7 | // 8 | 9 | @class ASIHTTPRequest; 10 | 11 | @protocol ASIHTTPRequestDelegate 12 | 13 | @optional 14 | 15 | // These are the default delegate methods for request status 16 | // You can use different ones by setting didStartSelector / didFinishSelector / didFailSelector 17 | - (void)requestStarted:(ASIHTTPRequest *)request; 18 | - (void)request:(ASIHTTPRequest *)request didReceiveResponseHeaders:(NSDictionary *)responseHeaders; 19 | - (void)request:(ASIHTTPRequest *)request willRedirectToURL:(NSURL *)newURL; 20 | - (void)requestFinished:(ASIHTTPRequest *)request; 21 | - (void)requestFailed:(ASIHTTPRequest *)request; 22 | - (void)requestRedirected:(ASIHTTPRequest *)request; 23 | 24 | // When a delegate implements this method, it is expected to process all incoming data itself 25 | // This means that responseData / responseString / downloadDestinationPath etc are ignored 26 | // You can have the request call a different method by setting didReceiveDataSelector 27 | - (void)request:(ASIHTTPRequest *)request didReceiveData:(NSData *)data; 28 | 29 | // If a delegate implements one of these, it will be asked to supply credentials when none are available 30 | // The delegate can then either restart the request ([request retryUsingSuppliedCredentials]) once credentials have been set 31 | // or cancel it ([request cancelAuthentication]) 32 | - (void)authenticationNeededForRequest:(ASIHTTPRequest *)request; 33 | - (void)proxyAuthenticationNeededForRequest:(ASIHTTPRequest *)request; 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /GetexceptionalAPI/GetexceptionalAPI/external/asi-http-request/ASIInputStream.h: -------------------------------------------------------------------------------- 1 | // 2 | // ASIInputStream.h 3 | // Part of ASIHTTPRequest -> http://allseeing-i.com/ASIHTTPRequest 4 | // 5 | // Created by Ben Copsey on 10/08/2009. 6 | // Copyright 2009 All-Seeing Interactive. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class ASIHTTPRequest; 12 | 13 | // This is a wrapper for NSInputStream that pretends to be an NSInputStream itself 14 | // Subclassing NSInputStream seems to be tricky, and may involve overriding undocumented methods, so we'll cheat instead. 15 | // It is used by ASIHTTPRequest whenever we have a request body, and handles measuring and throttling the bandwidth used for uploading 16 | 17 | @interface ASIInputStream : NSObject { 18 | NSInputStream *stream; 19 | ASIHTTPRequest *request; 20 | } 21 | + (id)inputStreamWithFileAtPath:(NSString *)path request:(ASIHTTPRequest *)request; 22 | + (id)inputStreamWithData:(NSData *)data request:(ASIHTTPRequest *)request; 23 | 24 | @property (retain, nonatomic) NSInputStream *stream; 25 | @property (assign, nonatomic) ASIHTTPRequest *request; 26 | @end 27 | -------------------------------------------------------------------------------- /GetexceptionalAPI/GetexceptionalAPI/external/asi-http-request/ASIInputStream.m: -------------------------------------------------------------------------------- 1 | // 2 | // ASIInputStream.m 3 | // Part of ASIHTTPRequest -> http://allseeing-i.com/ASIHTTPRequest 4 | // 5 | // Created by Ben Copsey on 10/08/2009. 6 | // Copyright 2009 All-Seeing Interactive. All rights reserved. 7 | // 8 | 9 | #import "ASIInputStream.h" 10 | #import "ASIHTTPRequest.h" 11 | 12 | // Used to ensure only one request can read data at once 13 | static NSLock *readLock = nil; 14 | 15 | @implementation ASIInputStream 16 | 17 | + (void)initialize 18 | { 19 | if (self == [ASIInputStream class]) { 20 | readLock = [[NSLock alloc] init]; 21 | } 22 | } 23 | 24 | + (id)inputStreamWithFileAtPath:(NSString *)path request:(ASIHTTPRequest *)theRequest 25 | { 26 | ASIInputStream *theStream = [[[self alloc] init] autorelease]; 27 | [theStream setRequest:theRequest]; 28 | [theStream setStream:[NSInputStream inputStreamWithFileAtPath:path]]; 29 | return theStream; 30 | } 31 | 32 | + (id)inputStreamWithData:(NSData *)data request:(ASIHTTPRequest *)theRequest 33 | { 34 | ASIInputStream *theStream = [[[self alloc] init] autorelease]; 35 | [theStream setRequest:theRequest]; 36 | [theStream setStream:[NSInputStream inputStreamWithData:data]]; 37 | return theStream; 38 | } 39 | 40 | - (void)dealloc 41 | { 42 | [stream release]; 43 | [super dealloc]; 44 | } 45 | 46 | // Called when CFNetwork wants to read more of our request body 47 | // When throttling is on, we ask ASIHTTPRequest for the maximum amount of data we can read 48 | - (NSInteger)read:(uint8_t *)buffer maxLength:(NSUInteger)len 49 | { 50 | [readLock lock]; 51 | unsigned long toRead = len; 52 | if ([ASIHTTPRequest isBandwidthThrottled]) { 53 | toRead = [ASIHTTPRequest maxUploadReadLength]; 54 | if (toRead > len) { 55 | toRead = len; 56 | } else if (toRead == 0) { 57 | toRead = 1; 58 | } 59 | [request performThrottling]; 60 | } 61 | [ASIHTTPRequest incrementBandwidthUsedInLastSecond:toRead]; 62 | [readLock unlock]; 63 | return [stream read:buffer maxLength:toRead]; 64 | } 65 | 66 | /* 67 | * Implement NSInputStream mandatory methods to make sure they are implemented 68 | * (necessary for MacRuby for example) and avoid the overhead of method 69 | * forwarding for these common methods. 70 | */ 71 | - (void)open 72 | { 73 | [stream open]; 74 | } 75 | 76 | - (void)close 77 | { 78 | [stream close]; 79 | } 80 | 81 | - (id)delegate 82 | { 83 | return [stream delegate]; 84 | } 85 | 86 | - (void)setDelegate:(id)delegate 87 | { 88 | [stream setDelegate:delegate]; 89 | } 90 | 91 | - (void)scheduleInRunLoop:(NSRunLoop *)aRunLoop forMode:(NSString *)mode 92 | { 93 | [stream scheduleInRunLoop:aRunLoop forMode:mode]; 94 | } 95 | 96 | - (void)removeFromRunLoop:(NSRunLoop *)aRunLoop forMode:(NSString *)mode 97 | { 98 | [stream removeFromRunLoop:aRunLoop forMode:mode]; 99 | } 100 | 101 | - (id)propertyForKey:(NSString *)key 102 | { 103 | return [stream propertyForKey:key]; 104 | } 105 | 106 | - (BOOL)setProperty:(id)property forKey:(NSString *)key 107 | { 108 | return [stream setProperty:property forKey:key]; 109 | } 110 | 111 | - (NSStreamStatus)streamStatus 112 | { 113 | return [stream streamStatus]; 114 | } 115 | 116 | - (NSError *)streamError 117 | { 118 | return [stream streamError]; 119 | } 120 | 121 | // If we get asked to perform a method we don't have (probably internal ones), 122 | // we'll just forward the message to our stream 123 | 124 | - (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector 125 | { 126 | return [stream methodSignatureForSelector:aSelector]; 127 | } 128 | 129 | - (void)forwardInvocation:(NSInvocation *)anInvocation 130 | { 131 | [anInvocation invokeWithTarget:stream]; 132 | } 133 | 134 | @synthesize stream; 135 | @synthesize request; 136 | @end 137 | -------------------------------------------------------------------------------- /GetexceptionalAPI/GetexceptionalAPI/external/asi-http-request/ASINetworkQueue.h: -------------------------------------------------------------------------------- 1 | // 2 | // ASINetworkQueue.h 3 | // Part of ASIHTTPRequest -> http://allseeing-i.com/ASIHTTPRequest 4 | // 5 | // Created by Ben Copsey on 07/11/2008. 6 | // Copyright 2008-2009 All-Seeing Interactive. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "ASIHTTPRequestDelegate.h" 11 | #import "ASIProgressDelegate.h" 12 | 13 | @interface ASINetworkQueue : NSOperationQueue { 14 | 15 | // Delegate will get didFail + didFinish messages (if set) 16 | id delegate; 17 | 18 | // Will be called when a request starts with the request as the argument 19 | SEL requestDidStartSelector; 20 | 21 | // Will be called when a request receives response headers 22 | // Should take the form request:didRecieveResponseHeaders:, where the first argument is the request, and the second the headers dictionary 23 | SEL requestDidReceiveResponseHeadersSelector; 24 | 25 | // Will be called when a request is about to redirect 26 | // Should take the form request:willRedirectToURL:, where the first argument is the request, and the second the new url 27 | SEL requestWillRedirectSelector; 28 | 29 | // Will be called when a request completes with the request as the argument 30 | SEL requestDidFinishSelector; 31 | 32 | // Will be called when a request fails with the request as the argument 33 | SEL requestDidFailSelector; 34 | 35 | // Will be called when the queue finishes with the queue as the argument 36 | SEL queueDidFinishSelector; 37 | 38 | // Upload progress indicator, probably an NSProgressIndicator or UIProgressView 39 | id uploadProgressDelegate; 40 | 41 | // Total amount uploaded so far for all requests in this queue 42 | unsigned long long bytesUploadedSoFar; 43 | 44 | // Total amount to be uploaded for all requests in this queue - requests add to this figure as they work out how much data they have to transmit 45 | unsigned long long totalBytesToUpload; 46 | 47 | // Download progress indicator, probably an NSProgressIndicator or UIProgressView 48 | id downloadProgressDelegate; 49 | 50 | // Total amount downloaded so far for all requests in this queue 51 | unsigned long long bytesDownloadedSoFar; 52 | 53 | // Total amount to be downloaded for all requests in this queue - requests add to this figure as they receive Content-Length headers 54 | unsigned long long totalBytesToDownload; 55 | 56 | // When YES, the queue will cancel all requests when a request fails. Default is YES 57 | BOOL shouldCancelAllRequestsOnFailure; 58 | 59 | //Number of real requests (excludes HEAD requests created to manage showAccurateProgress) 60 | int requestsCount; 61 | 62 | // When NO, this request will only update the progress indicator when it completes 63 | // When YES, this request will update the progress indicator according to how much data it has received so far 64 | // When YES, the queue will first perform HEAD requests for all GET requests in the queue, so it can calculate the total download size before it starts 65 | // NO means better performance, because it skips this step for GET requests, and it won't waste time updating the progress indicator until a request completes 66 | // Set to YES if the size of a requests in the queue varies greatly for much more accurate results 67 | // Default for requests in the queue is NO 68 | BOOL showAccurateProgress; 69 | 70 | // Storage container for additional queue information. 71 | NSDictionary *userInfo; 72 | 73 | } 74 | 75 | // Convenience constructor 76 | + (id)queue; 77 | 78 | // Call this to reset a queue - it will cancel all operations, clear delegates, and suspend operation 79 | - (void)reset; 80 | 81 | // Used internally to manage HEAD requests when showAccurateProgress is YES, do not use! 82 | - (void)addHEADOperation:(NSOperation *)operation; 83 | 84 | // All ASINetworkQueues are paused when created so that total size can be calculated before the queue starts 85 | // This method will start the queue 86 | - (void)go; 87 | 88 | @property (assign, nonatomic, setter=setUploadProgressDelegate:) id uploadProgressDelegate; 89 | @property (assign, nonatomic, setter=setDownloadProgressDelegate:) id downloadProgressDelegate; 90 | 91 | @property (assign) SEL requestDidStartSelector; 92 | @property (assign) SEL requestDidReceiveResponseHeadersSelector; 93 | @property (assign) SEL requestWillRedirectSelector; 94 | @property (assign) SEL requestDidFinishSelector; 95 | @property (assign) SEL requestDidFailSelector; 96 | @property (assign) SEL queueDidFinishSelector; 97 | @property (assign) BOOL shouldCancelAllRequestsOnFailure; 98 | @property (assign) id delegate; 99 | @property (assign) BOOL showAccurateProgress; 100 | @property (assign, readonly) int requestsCount; 101 | @property (retain) NSDictionary *userInfo; 102 | 103 | @property (assign) unsigned long long bytesUploadedSoFar; 104 | @property (assign) unsigned long long totalBytesToUpload; 105 | @property (assign) unsigned long long bytesDownloadedSoFar; 106 | @property (assign) unsigned long long totalBytesToDownload; 107 | 108 | @end 109 | -------------------------------------------------------------------------------- /GetexceptionalAPI/GetexceptionalAPI/external/asi-http-request/ASINetworkQueue.m: -------------------------------------------------------------------------------- 1 | // 2 | // ASINetworkQueue.m 3 | // Part of ASIHTTPRequest -> http://allseeing-i.com/ASIHTTPRequest 4 | // 5 | // Created by Ben Copsey on 07/11/2008. 6 | // Copyright 2008-2009 All-Seeing Interactive. All rights reserved. 7 | // 8 | 9 | #import "ASINetworkQueue.h" 10 | #import "ASIHTTPRequest.h" 11 | 12 | // Private stuff 13 | @interface ASINetworkQueue () 14 | - (void)resetProgressDelegate:(id *)progressDelegate; 15 | @property (assign) int requestsCount; 16 | @end 17 | 18 | @implementation ASINetworkQueue 19 | 20 | - (id)init 21 | { 22 | self = [super init]; 23 | [self setShouldCancelAllRequestsOnFailure:YES]; 24 | [self setMaxConcurrentOperationCount:4]; 25 | [self setSuspended:YES]; 26 | 27 | return self; 28 | } 29 | 30 | + (id)queue 31 | { 32 | return [[[self alloc] init] autorelease]; 33 | } 34 | 35 | - (void)dealloc 36 | { 37 | //We need to clear the queue on any requests that haven't got around to cleaning up yet, as otherwise they'll try to let us know if something goes wrong, and we'll be long gone by then 38 | for (ASIHTTPRequest *request in [self operations]) { 39 | [request setQueue:nil]; 40 | } 41 | [userInfo release]; 42 | [super dealloc]; 43 | } 44 | 45 | - (void)setSuspended:(BOOL)suspend 46 | { 47 | [super setSuspended:suspend]; 48 | } 49 | 50 | - (void)reset 51 | { 52 | [self cancelAllOperations]; 53 | [self setDelegate:nil]; 54 | [self setDownloadProgressDelegate:nil]; 55 | [self setUploadProgressDelegate:nil]; 56 | [self setRequestDidStartSelector:NULL]; 57 | [self setRequestDidReceiveResponseHeadersSelector:NULL]; 58 | [self setRequestDidFailSelector:NULL]; 59 | [self setRequestDidFinishSelector:NULL]; 60 | [self setQueueDidFinishSelector:NULL]; 61 | [self setSuspended:YES]; 62 | } 63 | 64 | 65 | - (void)go 66 | { 67 | [self setSuspended:NO]; 68 | } 69 | 70 | - (void)cancelAllOperations 71 | { 72 | [self setBytesUploadedSoFar:0]; 73 | [self setTotalBytesToUpload:0]; 74 | [self setBytesDownloadedSoFar:0]; 75 | [self setTotalBytesToDownload:0]; 76 | [super cancelAllOperations]; 77 | } 78 | 79 | - (void)setUploadProgressDelegate:(id)newDelegate 80 | { 81 | uploadProgressDelegate = newDelegate; 82 | [self resetProgressDelegate:&uploadProgressDelegate]; 83 | 84 | } 85 | 86 | - (void)setDownloadProgressDelegate:(id)newDelegate 87 | { 88 | downloadProgressDelegate = newDelegate; 89 | [self resetProgressDelegate:&downloadProgressDelegate]; 90 | } 91 | 92 | - (void)resetProgressDelegate:(id *)progressDelegate 93 | { 94 | #if !TARGET_OS_IPHONE 95 | // If the uploadProgressDelegate is an NSProgressIndicator, we set its MaxValue to 1.0 so we can treat it similarly to UIProgressViews 96 | SEL selector = @selector(setMaxValue:); 97 | if ([*progressDelegate respondsToSelector:selector]) { 98 | double max = 1.0; 99 | [ASIHTTPRequest performSelector:selector onTarget:progressDelegate withObject:nil amount:&max callerToRetain:nil]; 100 | } 101 | selector = @selector(setDoubleValue:); 102 | if ([*progressDelegate respondsToSelector:selector]) { 103 | double value = 0.0; 104 | [ASIHTTPRequest performSelector:selector onTarget:progressDelegate withObject:nil amount:&value callerToRetain:nil]; 105 | } 106 | #else 107 | SEL selector = @selector(setProgress:); 108 | if ([*progressDelegate respondsToSelector:selector]) { 109 | float value = 0.0f; 110 | [ASIHTTPRequest performSelector:selector onTarget:progressDelegate withObject:nil amount:&value callerToRetain:nil]; 111 | } 112 | #endif 113 | } 114 | 115 | - (void)addHEADOperation:(NSOperation *)operation 116 | { 117 | if ([operation isKindOfClass:[ASIHTTPRequest class]]) { 118 | 119 | ASIHTTPRequest *request = (ASIHTTPRequest *)operation; 120 | [request setRequestMethod:@"HEAD"]; 121 | [request setQueuePriority:10]; 122 | [request setShowAccurateProgress:YES]; 123 | [request setQueue:self]; 124 | 125 | // Important - we are calling NSOperation's add method - we don't want to add this as a normal request! 126 | [super addOperation:request]; 127 | } 128 | } 129 | 130 | // Only add ASIHTTPRequests to this queue!! 131 | - (void)addOperation:(NSOperation *)operation 132 | { 133 | if (![operation isKindOfClass:[ASIHTTPRequest class]]) { 134 | [NSException raise:@"AttemptToAddInvalidRequest" format:@"Attempted to add an object that was not an ASIHTTPRequest to an ASINetworkQueue"]; 135 | } 136 | 137 | [self setRequestsCount:[self requestsCount]+1]; 138 | 139 | ASIHTTPRequest *request = (ASIHTTPRequest *)operation; 140 | 141 | if ([self showAccurateProgress]) { 142 | 143 | // Force the request to build its body (this may change requestMethod) 144 | [request buildPostBody]; 145 | 146 | // If this is a GET request and we want accurate progress, perform a HEAD request first to get the content-length 147 | // We'll only do this before the queue is started 148 | // If requests are added after the queue is started they will probably move the overall progress backwards anyway, so there's no value performing the HEAD requests first 149 | // Instead, they'll update the total progress if and when they receive a content-length header 150 | if ([[request requestMethod] isEqualToString:@"GET"]) { 151 | if ([self isSuspended]) { 152 | ASIHTTPRequest *HEADRequest = [request HEADRequest]; 153 | [self addHEADOperation:HEADRequest]; 154 | [request addDependency:HEADRequest]; 155 | if ([request shouldResetDownloadProgress]) { 156 | [self resetProgressDelegate:&downloadProgressDelegate]; 157 | [request setShouldResetDownloadProgress:NO]; 158 | } 159 | } 160 | } 161 | [request buildPostBody]; 162 | [self request:nil incrementUploadSizeBy:[request postLength]]; 163 | 164 | 165 | } else { 166 | [self request:nil incrementDownloadSizeBy:1]; 167 | [self request:nil incrementUploadSizeBy:1]; 168 | } 169 | // Tell the request not to increment the upload size when it starts, as we've already added its length 170 | if ([request shouldResetUploadProgress]) { 171 | [self resetProgressDelegate:&uploadProgressDelegate]; 172 | [request setShouldResetUploadProgress:NO]; 173 | } 174 | 175 | [request setShowAccurateProgress:[self showAccurateProgress]]; 176 | 177 | [request setQueue:self]; 178 | [super addOperation:request]; 179 | 180 | } 181 | 182 | - (void)requestStarted:(ASIHTTPRequest *)request 183 | { 184 | if ([self requestDidStartSelector]) { 185 | [[self delegate] performSelector:[self requestDidStartSelector] withObject:request]; 186 | } 187 | } 188 | 189 | - (void)request:(ASIHTTPRequest *)request didReceiveResponseHeaders:(NSDictionary *)responseHeaders 190 | { 191 | if ([self requestDidReceiveResponseHeadersSelector]) { 192 | [[self delegate] performSelector:[self requestDidReceiveResponseHeadersSelector] withObject:request withObject:responseHeaders]; 193 | } 194 | } 195 | 196 | - (void)request:(ASIHTTPRequest *)request willRedirectToURL:(NSURL *)newURL 197 | { 198 | if ([self requestWillRedirectSelector]) { 199 | [[self delegate] performSelector:[self requestWillRedirectSelector] withObject:request withObject:newURL]; 200 | } 201 | } 202 | 203 | - (void)requestFinished:(ASIHTTPRequest *)request 204 | { 205 | [self setRequestsCount:[self requestsCount]-1]; 206 | if ([self requestDidFinishSelector]) { 207 | [[self delegate] performSelector:[self requestDidFinishSelector] withObject:request]; 208 | } 209 | if ([self requestsCount] == 0) { 210 | if ([self queueDidFinishSelector]) { 211 | [[self delegate] performSelector:[self queueDidFinishSelector] withObject:self]; 212 | } 213 | } 214 | } 215 | 216 | - (void)requestFailed:(ASIHTTPRequest *)request 217 | { 218 | [self setRequestsCount:[self requestsCount]-1]; 219 | if ([self requestDidFailSelector]) { 220 | [[self delegate] performSelector:[self requestDidFailSelector] withObject:request]; 221 | } 222 | if ([self requestsCount] == 0) { 223 | if ([self queueDidFinishSelector]) { 224 | [[self delegate] performSelector:[self queueDidFinishSelector] withObject:self]; 225 | } 226 | } 227 | if ([self shouldCancelAllRequestsOnFailure] && [self requestsCount] > 0) { 228 | [self cancelAllOperations]; 229 | } 230 | 231 | } 232 | 233 | 234 | - (void)request:(ASIHTTPRequest *)request didReceiveBytes:(long long)bytes 235 | { 236 | [self setBytesDownloadedSoFar:[self bytesDownloadedSoFar]+bytes]; 237 | if ([self downloadProgressDelegate]) { 238 | [ASIHTTPRequest updateProgressIndicator:&downloadProgressDelegate withProgress:[self bytesDownloadedSoFar] ofTotal:[self totalBytesToDownload]]; 239 | } 240 | } 241 | 242 | - (void)request:(ASIHTTPRequest *)request didSendBytes:(long long)bytes 243 | { 244 | [self setBytesUploadedSoFar:[self bytesUploadedSoFar]+bytes]; 245 | if ([self uploadProgressDelegate]) { 246 | [ASIHTTPRequest updateProgressIndicator:&uploadProgressDelegate withProgress:[self bytesUploadedSoFar] ofTotal:[self totalBytesToUpload]]; 247 | } 248 | } 249 | 250 | - (void)request:(ASIHTTPRequest *)request incrementDownloadSizeBy:(long long)newLength 251 | { 252 | [self setTotalBytesToDownload:[self totalBytesToDownload]+newLength]; 253 | } 254 | 255 | - (void)request:(ASIHTTPRequest *)request incrementUploadSizeBy:(long long)newLength 256 | { 257 | [self setTotalBytesToUpload:[self totalBytesToUpload]+newLength]; 258 | } 259 | 260 | 261 | // Since this queue takes over as the delegate for all requests it contains, it should forward authorisation requests to its own delegate 262 | - (void)authenticationNeededForRequest:(ASIHTTPRequest *)request 263 | { 264 | if ([[self delegate] respondsToSelector:@selector(authenticationNeededForRequest:)]) { 265 | [[self delegate] performSelector:@selector(authenticationNeededForRequest:) withObject:request]; 266 | } 267 | } 268 | 269 | - (void)proxyAuthenticationNeededForRequest:(ASIHTTPRequest *)request 270 | { 271 | if ([[self delegate] respondsToSelector:@selector(proxyAuthenticationNeededForRequest:)]) { 272 | [[self delegate] performSelector:@selector(proxyAuthenticationNeededForRequest:) withObject:request]; 273 | } 274 | } 275 | 276 | 277 | - (BOOL)respondsToSelector:(SEL)selector 278 | { 279 | // We handle certain methods differently because whether our delegate implements them or not can affect how the request should behave 280 | 281 | // If the delegate implements this, the request will stop to wait for credentials 282 | if (selector == @selector(authenticationNeededForRequest:)) { 283 | if ([[self delegate] respondsToSelector:@selector(authenticationNeededForRequest:)]) { 284 | return YES; 285 | } 286 | return NO; 287 | 288 | // If the delegate implements this, the request will to wait for credentials 289 | } else if (selector == @selector(proxyAuthenticationNeededForRequest:)) { 290 | if ([[self delegate] respondsToSelector:@selector(proxyAuthenticationNeededForRequest:)]) { 291 | return YES; 292 | } 293 | return NO; 294 | 295 | // If the delegate implements requestWillRedirectSelector, the request will stop to allow the delegate to change the url 296 | } else if (selector == @selector(request:willRedirectToURL:)) { 297 | if ([self requestWillRedirectSelector] && [[self delegate] respondsToSelector:[self requestWillRedirectSelector]]) { 298 | return YES; 299 | } 300 | return NO; 301 | } 302 | return [super respondsToSelector:selector]; 303 | } 304 | 305 | #pragma mark NSCopying 306 | 307 | - (id)copyWithZone:(NSZone *)zone 308 | { 309 | ASINetworkQueue *newQueue = [[[self class] alloc] init]; 310 | [newQueue setDelegate:[self delegate]]; 311 | [newQueue setRequestDidStartSelector:[self requestDidStartSelector]]; 312 | [newQueue setRequestWillRedirectSelector:[self requestWillRedirectSelector]]; 313 | [newQueue setRequestDidReceiveResponseHeadersSelector:[self requestDidReceiveResponseHeadersSelector]]; 314 | [newQueue setRequestDidFinishSelector:[self requestDidFinishSelector]]; 315 | [newQueue setRequestDidFailSelector:[self requestDidFailSelector]]; 316 | [newQueue setQueueDidFinishSelector:[self queueDidFinishSelector]]; 317 | [newQueue setUploadProgressDelegate:[self uploadProgressDelegate]]; 318 | [newQueue setDownloadProgressDelegate:[self downloadProgressDelegate]]; 319 | [newQueue setShouldCancelAllRequestsOnFailure:[self shouldCancelAllRequestsOnFailure]]; 320 | [newQueue setShowAccurateProgress:[self showAccurateProgress]]; 321 | [newQueue setUserInfo:[[[self userInfo] copyWithZone:zone] autorelease]]; 322 | return newQueue; 323 | } 324 | 325 | 326 | @synthesize requestsCount; 327 | @synthesize bytesUploadedSoFar; 328 | @synthesize totalBytesToUpload; 329 | @synthesize bytesDownloadedSoFar; 330 | @synthesize totalBytesToDownload; 331 | @synthesize shouldCancelAllRequestsOnFailure; 332 | @synthesize uploadProgressDelegate; 333 | @synthesize downloadProgressDelegate; 334 | @synthesize requestDidStartSelector; 335 | @synthesize requestDidReceiveResponseHeadersSelector; 336 | @synthesize requestWillRedirectSelector; 337 | @synthesize requestDidFinishSelector; 338 | @synthesize requestDidFailSelector; 339 | @synthesize queueDidFinishSelector; 340 | @synthesize delegate; 341 | @synthesize showAccurateProgress; 342 | @synthesize userInfo; 343 | @end 344 | -------------------------------------------------------------------------------- /GetexceptionalAPI/GetexceptionalAPI/external/asi-http-request/ASIProgressDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // ASIProgressDelegate.h 3 | // Part of ASIHTTPRequest -> http://allseeing-i.com/ASIHTTPRequest 4 | // 5 | // Created by Ben Copsey on 13/04/2010. 6 | // Copyright 2010 All-Seeing Interactive. All rights reserved. 7 | // 8 | 9 | @class ASIHTTPRequest; 10 | 11 | @protocol ASIProgressDelegate 12 | 13 | @optional 14 | 15 | // These methods are used to update UIProgressViews (iPhone OS) or NSProgressIndicators (Mac OS X) 16 | // If you are using a custom progress delegate, you may find it easier to implement didReceiveBytes / didSendBytes instead 17 | #if TARGET_OS_IPHONE 18 | - (void)setProgress:(float)newProgress; 19 | #else 20 | - (void)setDoubleValue:(double)newProgress; 21 | - (void)setMaxValue:(double)newMax; 22 | #endif 23 | 24 | // Called when the request receives some data - bytes is the length of that data 25 | - (void)request:(ASIHTTPRequest *)request didReceiveBytes:(long long)bytes; 26 | 27 | // Called when the request sends some data 28 | // The first 32KB (128KB on older platforms) of data sent is not included in this amount because of limitations with the CFNetwork API 29 | // bytes may be less than zero if a request needs to remove upload progress (probably because the request needs to run again) 30 | - (void)request:(ASIHTTPRequest *)request didSendBytes:(long long)bytes; 31 | 32 | // Called when a request needs to change the length of the content to download 33 | - (void)request:(ASIHTTPRequest *)request incrementDownloadSizeBy:(long long)newLength; 34 | 35 | // Called when a request needs to change the length of the content to upload 36 | // newLength may be less than zero when a request needs to remove the size of the internal buffer from progress tracking 37 | - (void)request:(ASIHTTPRequest *)request incrementUploadSizeBy:(long long)newLength; 38 | @end 39 | -------------------------------------------------------------------------------- /GetexceptionalAPI/GetexceptionalAPI/external/json_framework_2.3/JSON.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2009 Stig Brautaset. All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of the author nor the names of its contributors may be used 15 | to endorse or promote products derived from this software without specific 16 | prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | /** 31 | @mainpage A strict JSON parser and generator for Objective-C 32 | 33 | JSON (JavaScript Object Notation) is a lightweight data-interchange 34 | format. This framework provides two apis for parsing and generating 35 | JSON. One standard object-based and a higher level api consisting of 36 | categories added to existing Objective-C classes. 37 | 38 | This framework does its best to be as strict as possible, both in what it accepts and what it generates. For example, it does not support trailing commas in arrays or objects. Nor does it support embedded comments, or anything else not in the JSON specification. This is considered a feature. 39 | 40 | @section Features 41 | 42 | @li Easy-to-use API. 43 | @li Strict parsing & generation. 44 | @li Stack of error available in case of failure so you can easily figure out what is wrong. 45 | @li Optional pretty-printing of JSON output. 46 | @li Optionally sorted dictionary keys in JSON output. 47 | @li Configurable recursion depth for parsing, for added security. 48 | 49 | 50 | @section Links 51 | 52 | @li Google code project site. 53 | @li Browse the source at github. 54 | @li Online version of the API documentation. 55 | 56 | */ 57 | 58 | #if (TARGET_OS_IPHONE) 59 | 60 | #import "SBJsonParser.h" 61 | #import "SBJsonWriter.h" 62 | #import "NSObject+SBJSON.h" 63 | #import "NSString+SBJSON.h" 64 | 65 | #else 66 | 67 | #import 68 | #import 69 | #import 70 | #import 71 | 72 | #endif 73 | -------------------------------------------------------------------------------- /GetexceptionalAPI/GetexceptionalAPI/external/json_framework_2.3/NSObject+SBJSON.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2009 Stig Brautaset. All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of the author nor the names of its contributors may be used 15 | to endorse or promote products derived from this software without specific 16 | prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #import 31 | 32 | 33 | /** 34 | @brief Adds JSON generation to Foundation classes 35 | 36 | This is a category on NSObject that adds methods for returning JSON representations 37 | of standard objects to the objects themselves. This means you can call the 38 | -JSONRepresentation method on an NSArray object and it'll do what you want. 39 | */ 40 | @interface NSObject (NSObject_SBJSON) 41 | 42 | /** 43 | @brief Returns a string containing the receiver encoded in JSON. 44 | 45 | This method is added as a category on NSObject but is only actually 46 | supported for the following objects: 47 | @li NSDictionary 48 | @li NSArray 49 | */ 50 | - (NSString *)JSONRepresentation; 51 | 52 | @end 53 | 54 | -------------------------------------------------------------------------------- /GetexceptionalAPI/GetexceptionalAPI/external/json_framework_2.3/NSObject+SBJSON.m: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2009 Stig Brautaset. All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of the author nor the names of its contributors may be used 15 | to endorse or promote products derived from this software without specific 16 | prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #import "NSObject+SBJSON.h" 31 | #import "SBJsonWriter.h" 32 | 33 | @implementation NSObject (NSObject_SBJSON) 34 | 35 | - (NSString *)JSONRepresentation { 36 | SBJsonWriter *jsonWriter = [SBJsonWriter new]; 37 | NSString *json = [jsonWriter stringWithObject:self]; 38 | if (!json) 39 | NSLog(@"-JSONRepresentation failed. Error trace is: %@", [jsonWriter errorTrace]); 40 | [jsonWriter release]; 41 | return json; 42 | } 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /GetexceptionalAPI/GetexceptionalAPI/external/json_framework_2.3/NSString+SBJSON.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2009 Stig Brautaset. All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of the author nor the names of its contributors may be used 15 | to endorse or promote products derived from this software without specific 16 | prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #import 31 | 32 | /** 33 | @brief Adds JSON parsing methods to NSString 34 | 35 | This is a category on NSString that adds methods for parsing the target string. 36 | */ 37 | @interface NSString (NSString_SBJSON) 38 | 39 | /** 40 | @brief Returns the NSDictionary or NSArray represented by the current string's JSON representation. 41 | 42 | Returns the dictionary or array represented in the receiver, or nil on error. 43 | 44 | Returns the NSDictionary or NSArray represented by the current string's JSON representation. 45 | */ 46 | - (id)JSONValue; 47 | 48 | @end 49 | -------------------------------------------------------------------------------- /GetexceptionalAPI/GetexceptionalAPI/external/json_framework_2.3/NSString+SBJSON.m: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2007-2009 Stig Brautaset. All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of the author nor the names of its contributors may be used 15 | to endorse or promote products derived from this software without specific 16 | prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #import "NSString+SBJSON.h" 31 | #import "SBJsonParser.h" 32 | 33 | @implementation NSString (NSString_SBJSON) 34 | 35 | - (id)JSONValue 36 | { 37 | SBJsonParser *jsonParser = [SBJsonParser new]; 38 | id repr = [jsonParser objectWithString:self]; 39 | if (!repr) 40 | NSLog(@"-JSONValue failed. Error trace is: %@", [jsonParser errorTrace]); 41 | [jsonParser release]; 42 | return repr; 43 | } 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /GetexceptionalAPI/GetexceptionalAPI/external/json_framework_2.3/SBJsonBase.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2009 Stig Brautaset. All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of the author nor the names of its contributors may be used 15 | to endorse or promote products derived from this software without specific 16 | prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #import 31 | 32 | extern NSString * SBJSONErrorDomain; 33 | 34 | 35 | enum { 36 | EUNSUPPORTED = 1, 37 | EPARSENUM, 38 | EPARSE, 39 | EFRAGMENT, 40 | ECTRL, 41 | EUNICODE, 42 | EDEPTH, 43 | EESCAPE, 44 | ETRAILCOMMA, 45 | ETRAILGARBAGE, 46 | EEOF, 47 | EINPUT 48 | }; 49 | 50 | /** 51 | @brief Common base class for parsing & writing. 52 | 53 | This class contains the common error-handling code and option between the parser/writer. 54 | */ 55 | @interface SBJsonBase : NSObject { 56 | NSMutableArray *errorTrace; 57 | 58 | @protected 59 | NSUInteger depth, maxDepth; 60 | } 61 | 62 | /** 63 | @brief The maximum recursing depth. 64 | 65 | Defaults to 512. If the input is nested deeper than this the input will be deemed to be 66 | malicious and the parser returns nil, signalling an error. ("Nested too deep".) You can 67 | turn off this security feature by setting the maxDepth value to 0. 68 | */ 69 | @property NSUInteger maxDepth; 70 | 71 | /** 72 | @brief Return an error trace, or nil if there was no errors. 73 | 74 | Note that this method returns the trace of the last method that failed. 75 | You need to check the return value of the call you're making to figure out 76 | if the call actually failed, before you know call this method. 77 | */ 78 | @property(copy,readonly) NSArray* errorTrace; 79 | 80 | /// @internal for use in subclasses to add errors to the stack trace 81 | - (void)addErrorWithCode:(NSUInteger)code description:(NSString*)str; 82 | 83 | /// @internal for use in subclasess to clear the error before a new parsing attempt 84 | - (void)clearErrorTrace; 85 | 86 | @end 87 | -------------------------------------------------------------------------------- /GetexceptionalAPI/GetexceptionalAPI/external/json_framework_2.3/SBJsonBase.m: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2009 Stig Brautaset. All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of the author nor the names of its contributors may be used 15 | to endorse or promote products derived from this software without specific 16 | prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #import "SBJsonBase.h" 31 | NSString * SBJSONErrorDomain = @"org.brautaset.JSON.ErrorDomain"; 32 | 33 | 34 | @implementation SBJsonBase 35 | 36 | @synthesize errorTrace; 37 | @synthesize maxDepth; 38 | 39 | - (id)init { 40 | self = [super init]; 41 | if (self) 42 | self.maxDepth = 512; 43 | return self; 44 | } 45 | 46 | - (void)dealloc { 47 | [errorTrace release]; 48 | [super dealloc]; 49 | } 50 | 51 | - (void)addErrorWithCode:(NSUInteger)code description:(NSString*)str { 52 | NSDictionary *userInfo; 53 | if (!errorTrace) { 54 | errorTrace = [NSMutableArray new]; 55 | userInfo = [NSDictionary dictionaryWithObject:str forKey:NSLocalizedDescriptionKey]; 56 | 57 | } else { 58 | userInfo = [NSDictionary dictionaryWithObjectsAndKeys: 59 | str, NSLocalizedDescriptionKey, 60 | [errorTrace lastObject], NSUnderlyingErrorKey, 61 | nil]; 62 | } 63 | 64 | NSError *error = [NSError errorWithDomain:SBJSONErrorDomain code:code userInfo:userInfo]; 65 | 66 | [self willChangeValueForKey:@"errorTrace"]; 67 | [errorTrace addObject:error]; 68 | [self didChangeValueForKey:@"errorTrace"]; 69 | } 70 | 71 | - (void)clearErrorTrace { 72 | [self willChangeValueForKey:@"errorTrace"]; 73 | [errorTrace release]; 74 | errorTrace = nil; 75 | [self didChangeValueForKey:@"errorTrace"]; 76 | } 77 | 78 | @end 79 | -------------------------------------------------------------------------------- /GetexceptionalAPI/GetexceptionalAPI/external/json_framework_2.3/SBJsonParser.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2009 Stig Brautaset. All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of the author nor the names of its contributors may be used 15 | to endorse or promote products derived from this software without specific 16 | prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #import 31 | #import "SBJsonBase.h" 32 | 33 | /** 34 | @brief The JSON parser class. 35 | 36 | JSON is mapped to Objective-C types in the following way: 37 | 38 | @li Null -> NSNull 39 | @li String -> NSMutableString 40 | @li Array -> NSMutableArray 41 | @li Object -> NSMutableDictionary 42 | @li Boolean -> NSNumber (initialised with -initWithBool:) 43 | @li Number -> (NSNumber | NSDecimalNumber) 44 | 45 | Since Objective-C doesn't have a dedicated class for boolean values, these turns into NSNumber 46 | instances. These are initialised with the -initWithBool: method, and 47 | round-trip back to JSON properly. (They won't silently suddenly become 0 or 1; they'll be 48 | represented as 'true' and 'false' again.) 49 | 50 | As an optimisation short JSON integers turn into NSNumber instances, while complex ones turn into NSDecimalNumber instances. 51 | We can thus avoid any loss of precision as JSON allows ridiculously large numbers. 52 | 53 | */ 54 | @interface SBJsonParser : SBJsonBase { 55 | 56 | @private 57 | const char *c; 58 | } 59 | 60 | /** 61 | @brief Return the object represented by the given string 62 | 63 | Returns the object represented by the passed-in string or nil on error. The returned object can be 64 | a string, number, boolean, null, array or dictionary. 65 | 66 | @param repr the json string to parse 67 | */ 68 | - (id)objectWithString:(NSString *)repr; 69 | 70 | /** 71 | @brief Return the object represented by the given string 72 | 73 | Returns the object represented by the passed-in string or nil on error. The returned object can be 74 | a string, number, boolean, null, array or dictionary. 75 | 76 | @param jsonText the json string to parse 77 | @param error pointer to an NSError object to populate on error 78 | */ 79 | 80 | - (id)objectWithString:(NSString*)jsonText 81 | error:(NSError**)error; 82 | 83 | 84 | @end 85 | 86 | 87 | -------------------------------------------------------------------------------- /GetexceptionalAPI/GetexceptionalAPI/external/json_framework_2.3/SBJsonWriter.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2009 Stig Brautaset. All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of the author nor the names of its contributors may be used 15 | to endorse or promote products derived from this software without specific 16 | prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #import 31 | #import "SBJsonBase.h" 32 | 33 | /** 34 | @brief The JSON writer class. 35 | 36 | Objective-C types are mapped to JSON types in the following way: 37 | 38 | @li NSNull -> Null 39 | @li NSString -> String 40 | @li NSArray -> Array 41 | @li NSDictionary -> Object 42 | @li NSNumber (-initWithBool:) -> Boolean 43 | @li NSNumber -> Number 44 | 45 | In JSON the keys of an object must be strings. NSDictionary keys need 46 | not be, but attempting to convert an NSDictionary with non-string keys 47 | into JSON will throw an exception. 48 | 49 | NSNumber instances created with the +initWithBool: method are 50 | converted into the JSON boolean "true" and "false" values, and vice 51 | versa. Any other NSNumber instances are converted to a JSON number the 52 | way you would expect. 53 | 54 | */ 55 | @interface SBJsonWriter : SBJsonBase { 56 | 57 | @private 58 | BOOL sortKeys, humanReadable; 59 | } 60 | 61 | /** 62 | @brief Whether we are generating human-readable (multiline) JSON. 63 | 64 | Set whether or not to generate human-readable JSON. The default is NO, which produces 65 | JSON without any whitespace. (Except inside strings.) If set to YES, generates human-readable 66 | JSON with linebreaks after each array value and dictionary key/value pair, indented two 67 | spaces per nesting level. 68 | */ 69 | @property BOOL humanReadable; 70 | 71 | /** 72 | @brief Whether or not to sort the dictionary keys in the output. 73 | 74 | If this is set to YES, the dictionary keys in the JSON output will be in sorted order. 75 | (This is useful if you need to compare two structures, for example.) The default is NO. 76 | */ 77 | @property BOOL sortKeys; 78 | 79 | /** 80 | @brief Return JSON representation (or fragment) for the given object. 81 | 82 | Returns a string containing JSON representation of the passed in value, or nil on error. 83 | If nil is returned and @p error is not NULL, @p *error can be interrogated to find the cause of the error. 84 | 85 | @param value any instance that can be represented as a JSON fragment 86 | 87 | */ 88 | - (NSString*)stringWithObject:(id)value; 89 | 90 | /** 91 | @brief Return JSON representation (or fragment) for the given object. 92 | 93 | Returns a string containing JSON representation of the passed in value, or nil on error. 94 | If nil is returned and @p error is not NULL, @p *error can be interrogated to find the cause of the error. 95 | 96 | @param value any instance that can be represented as a JSON fragment 97 | @param error pointer to object to be populated with NSError on failure 98 | 99 | */- (NSString*)stringWithObject:(id)value 100 | error:(NSError**)error; 101 | 102 | 103 | @end 104 | 105 | /** 106 | @brief Allows generation of JSON for otherwise unsupported classes. 107 | 108 | If you have a custom class that you want to create a JSON representation for you can implement 109 | this method in your class. It should return a representation of your object defined 110 | in terms of objects that can be translated into JSON. For example, a Person 111 | object might implement it like this: 112 | 113 | @code 114 | - (id)proxyForJson { 115 | return [NSDictionary dictionaryWithObjectsAndKeys: 116 | name, @"name", 117 | phone, @"phone", 118 | email, @"email", 119 | nil]; 120 | } 121 | @endcode 122 | 123 | */ 124 | @interface NSObject (SBProxyForJson) 125 | - (id)proxyForJson; 126 | @end 127 | 128 | -------------------------------------------------------------------------------- /GetexceptionalAPI/GetexceptionalAPI/external/json_framework_2.3/SBJsonWriter.m: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2009 Stig Brautaset. All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of the author nor the names of its contributors may be used 15 | to endorse or promote products derived from this software without specific 16 | prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #import "SBJsonWriter.h" 31 | 32 | @interface SBJsonWriter () 33 | 34 | - (BOOL)appendValue:(id)fragment into:(NSMutableString*)json; 35 | - (BOOL)appendArray:(NSArray*)fragment into:(NSMutableString*)json; 36 | - (BOOL)appendDictionary:(NSDictionary*)fragment into:(NSMutableString*)json; 37 | - (BOOL)appendString:(NSString*)fragment into:(NSMutableString*)json; 38 | 39 | - (NSString*)indent; 40 | 41 | @end 42 | 43 | @implementation SBJsonWriter 44 | 45 | @synthesize sortKeys; 46 | @synthesize humanReadable; 47 | 48 | static NSMutableCharacterSet *kEscapeChars; 49 | 50 | + (void)initialize { 51 | kEscapeChars = [[NSMutableCharacterSet characterSetWithRange: NSMakeRange(0,32)] retain]; 52 | [kEscapeChars addCharactersInString: @"\"\\"]; 53 | } 54 | 55 | - (NSString*)stringWithObject:(id)value { 56 | [self clearErrorTrace]; 57 | 58 | if ([value isKindOfClass:[NSDictionary class]] || [value isKindOfClass:[NSArray class]]) { 59 | depth = 0; 60 | NSMutableString *json = [NSMutableString stringWithCapacity:128]; 61 | if ([self appendValue:value into:json]) 62 | return json; 63 | } 64 | 65 | if ([value respondsToSelector:@selector(proxyForJson)]) { 66 | NSString *tmp = [self stringWithObject:[value proxyForJson]]; 67 | if (tmp) 68 | return tmp; 69 | } 70 | 71 | [self addErrorWithCode:EFRAGMENT description:@"Not valid type for JSON"]; 72 | return nil; 73 | } 74 | 75 | - (NSString*)stringWithObject:(id)value error:(NSError**)error { 76 | NSString *tmp = [self stringWithObject:value]; 77 | if (tmp) 78 | return tmp; 79 | 80 | if (error) 81 | *error = [self.errorTrace lastObject]; 82 | return nil; 83 | } 84 | 85 | - (NSString*)indent { 86 | return [@"\n" stringByPaddingToLength:1 + 2 * depth withString:@" " startingAtIndex:0]; 87 | } 88 | 89 | - (BOOL)appendValue:(id)fragment into:(NSMutableString*)json { 90 | if ([fragment isKindOfClass:[NSDictionary class]]) { 91 | if (![self appendDictionary:fragment into:json]) 92 | return NO; 93 | 94 | } else if ([fragment isKindOfClass:[NSArray class]]) { 95 | if (![self appendArray:fragment into:json]) 96 | return NO; 97 | 98 | } else if ([fragment isKindOfClass:[NSString class]]) { 99 | if (![self appendString:fragment into:json]) 100 | return NO; 101 | 102 | } else if ([fragment isKindOfClass:[NSNumber class]]) { 103 | if ('c' == *[fragment objCType]) { 104 | [json appendString:[fragment boolValue] ? @"true" : @"false"]; 105 | } else if ([fragment isEqualToNumber:[NSDecimalNumber notANumber]]) { 106 | [self addErrorWithCode:EUNSUPPORTED description:@"NaN is not a valid number in JSON"]; 107 | return NO; 108 | 109 | } else if ([fragment isEqualToNumber:[NSNumber numberWithDouble:INFINITY]] || [fragment isEqualToNumber:[NSNumber numberWithDouble:-INFINITY]]) { 110 | [self addErrorWithCode:EUNSUPPORTED description:@"Infinity is not a valid number in JSON"]; 111 | return NO; 112 | 113 | } else { 114 | [json appendString:[fragment stringValue]]; 115 | } 116 | } else if ([fragment isKindOfClass:[NSNull class]]) { 117 | [json appendString:@"null"]; 118 | } else if ([fragment respondsToSelector:@selector(proxyForJson)]) { 119 | [self appendValue:[fragment proxyForJson] into:json]; 120 | 121 | } else { 122 | [self addErrorWithCode:EUNSUPPORTED description:[NSString stringWithFormat:@"JSON serialisation not supported for %@", [fragment class]]]; 123 | return NO; 124 | } 125 | return YES; 126 | } 127 | 128 | - (BOOL)appendArray:(NSArray*)fragment into:(NSMutableString*)json { 129 | if (maxDepth && ++depth > maxDepth) { 130 | [self addErrorWithCode:EDEPTH description: @"Nested too deep"]; 131 | return NO; 132 | } 133 | [json appendString:@"["]; 134 | 135 | BOOL addComma = NO; 136 | for (id value in fragment) { 137 | if (addComma) 138 | [json appendString:@","]; 139 | else 140 | addComma = YES; 141 | 142 | if ([self humanReadable]) 143 | [json appendString:[self indent]]; 144 | 145 | if (![self appendValue:value into:json]) { 146 | return NO; 147 | } 148 | } 149 | 150 | depth--; 151 | if ([self humanReadable] && [fragment count]) 152 | [json appendString:[self indent]]; 153 | [json appendString:@"]"]; 154 | return YES; 155 | } 156 | 157 | - (BOOL)appendDictionary:(NSDictionary*)fragment into:(NSMutableString*)json { 158 | if (maxDepth && ++depth > maxDepth) { 159 | [self addErrorWithCode:EDEPTH description: @"Nested too deep"]; 160 | return NO; 161 | } 162 | [json appendString:@"{"]; 163 | 164 | NSString *colon = [self humanReadable] ? @" : " : @":"; 165 | BOOL addComma = NO; 166 | NSArray *keys = [fragment allKeys]; 167 | if (self.sortKeys) 168 | keys = [keys sortedArrayUsingSelector:@selector(compare:)]; 169 | 170 | for (id value in keys) { 171 | if (addComma) 172 | [json appendString:@","]; 173 | else 174 | addComma = YES; 175 | 176 | if ([self humanReadable]) 177 | [json appendString:[self indent]]; 178 | 179 | if (![value isKindOfClass:[NSString class]]) { 180 | [self addErrorWithCode:EUNSUPPORTED description: @"JSON object key must be string"]; 181 | return NO; 182 | } 183 | 184 | if (![self appendString:value into:json]) 185 | return NO; 186 | 187 | [json appendString:colon]; 188 | if (![self appendValue:[fragment objectForKey:value] into:json]) { 189 | [self addErrorWithCode:EUNSUPPORTED description:[NSString stringWithFormat:@"Unsupported value for key %@ in object", value]]; 190 | return NO; 191 | } 192 | } 193 | 194 | depth--; 195 | if ([self humanReadable] && [fragment count]) 196 | [json appendString:[self indent]]; 197 | [json appendString:@"}"]; 198 | return YES; 199 | } 200 | 201 | - (BOOL)appendString:(NSString*)fragment into:(NSMutableString*)json { 202 | 203 | [json appendString:@"\""]; 204 | 205 | NSRange esc = [fragment rangeOfCharacterFromSet:kEscapeChars]; 206 | if ( !esc.length ) { 207 | // No special chars -- can just add the raw string: 208 | [json appendString:fragment]; 209 | 210 | } else { 211 | NSUInteger length = [fragment length]; 212 | for (NSUInteger i = 0; i < length; i++) { 213 | unichar uc = [fragment characterAtIndex:i]; 214 | switch (uc) { 215 | case '"': [json appendString:@"\\\""]; break; 216 | case '\\': [json appendString:@"\\\\"]; break; 217 | case '\t': [json appendString:@"\\t"]; break; 218 | case '\n': [json appendString:@"\\n"]; break; 219 | case '\r': [json appendString:@"\\r"]; break; 220 | case '\b': [json appendString:@"\\b"]; break; 221 | case '\f': [json appendString:@"\\f"]; break; 222 | default: 223 | if (uc < 0x20) { 224 | [json appendFormat:@"\\u%04x", uc]; 225 | } else { 226 | CFStringAppendCharacters((CFMutableStringRef)json, &uc, 1); 227 | } 228 | break; 229 | 230 | } 231 | } 232 | } 233 | 234 | [json appendString:@"\""]; 235 | return YES; 236 | } 237 | 238 | 239 | @end 240 | -------------------------------------------------------------------------------- /GetexceptionalAPI/GetexceptionalAPI/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // GetexceptionalAPI 4 | // 5 | // Created by Jörg Polakowski on 23/03/11. 6 | // Copyright 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | int main(int argc, char *argv[]) 12 | { 13 | NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 14 | int retVal = UIApplicationMain(argc, argv, nil, nil); 15 | [pool release]; 16 | return retVal; 17 | } 18 | -------------------------------------------------------------------------------- /GetexceptionalAPI/GetexceptionalAPITests/GetexceptionalAPITests-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | mobilemelting.${PRODUCT_NAME:rfc1034identifier} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundlePackageType 14 | BNDL 15 | CFBundleShortVersionString 16 | 1.0 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /GetexceptionalAPI/GetexceptionalAPITests/GetexceptionalAPITests-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'GetexceptionalAPITests' target in the 'GetexceptionalAPITests' project 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #import 7 | #endif 8 | -------------------------------------------------------------------------------- /GetexceptionalAPI/GetexceptionalAPITests/GetexceptionalAPITests.h: -------------------------------------------------------------------------------- 1 | // 2 | // GetexceptionalAPITests.h 3 | // GetexceptionalAPITests 4 | // 5 | // Created by Jörg Polakowski on 23/03/11. 6 | // Copyright 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | 12 | @interface GetexceptionalAPITests : SenTestCase { 13 | @private 14 | 15 | } 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /GetexceptionalAPI/GetexceptionalAPITests/GetexceptionalAPITests.m: -------------------------------------------------------------------------------- 1 | // 2 | // GetexceptionalAPITests.m 3 | // GetexceptionalAPITests 4 | // 5 | // Created by Jörg Polakowski on 23/03/11. 6 | // Copyright 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import "GetexceptionalAPITests.h" 10 | 11 | 12 | @implementation GetexceptionalAPITests 13 | 14 | - (void)setUp 15 | { 16 | [super setUp]; 17 | 18 | // Set-up code here. 19 | } 20 | 21 | - (void)tearDown 22 | { 23 | // Tear-down code here. 24 | 25 | [super tearDown]; 26 | } 27 | 28 | - (void)testExample 29 | { 30 | STFail(@"Unit tests are not implemented yet in GetexceptionalAPITests"); 31 | } 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /GetexceptionalAPI/GetexceptionalAPITests/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Exceptional API Wrapper 2 | 3 | ## Intro 4 | 5 | A wrapper on the [Exceptional](http://getexceptional.com) API for iOS. This wrapper uses the 6 | device's internet connection to report errors to your Exceptional account. 7 | 8 | ## Quickstart 9 | 10 | In your terminal: 11 | 12 | - git clone git@github.com:leviathan/getexceptional-api-wrapper.git 13 | 14 | In your Xcode project: 15 | 16 | - drag the GetexceptionalAPI folder into your project 17 | - drag the external folder into your project (decide which dependencies you need) 18 | - open the exceptional.plist file and add your API_KEY (this can be retrieved from the exceptional website) 19 | 20 | ## External Dependencies 21 | 22 | - [ASIHTTPRequest](http://allseeing-i.com/ASIHTTPRequest) 23 | - [JSON framework](https://github.com/stig/json-framework) 24 | - [ISO 8601 parser and unparser](http://boredzo.org/iso8601parser) 25 | 26 | ## Using the Wrapper in your code 27 | 28 | ### The Basics 29 | 30 | You only need to import the API files into your project. You may need to reference the external 31 | dependencies as well. 32 | 33 | ### Instantiating the API object 34 | 35 | Setup the Wrapper as a default NSSetUncaughtExceptionHandler. This way all exceptions, which occur 36 | in the app will be automatically reported to your account. 37 | 38 | [[GTExceptionalAPI sharedAPI] setupExceptionHandling]; 39 | 40 | Doing this is optional. You may also report exceptions directly by using a try - catch block. 41 | 42 | @try { 43 | ... your potentially risky code 44 | } 45 | @catch (NSException *exception) { 46 | [[GTExceptionalAPI sharedAPI] reportException:exception wait:NO]; 47 | } 48 | 49 | ## Analyze Errors 50 | 51 | Errors will be reported to your Exceptional account. 52 | Here is a description how you can analyze them: [Analyze iOS errors - the easy way](http://www.blog.mobile-melting.de/?p=382) 53 | Let me know, if the blog entry covers all your concerns! 54 | 55 | ## Todo's 56 | 57 | - log the error in a file and send it the next time the app starts 58 | - handle error signals and report them as well -------------------------------------------------------------------------------- /TestApps/iPhoneTestApp/iPhoneTestApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /TestApps/iPhoneTestApp/iPhoneTestApp.xcodeproj/xcuserdata/colins.xcuserdatad/xcschemes/iPhoneTestApp.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | 14 | 20 | 21 | 22 | 23 | 24 | 29 | 30 | 32 | 38 | 39 | 40 | 41 | 42 | 50 | 51 | 57 | 58 | 59 | 60 | 61 | 62 | 69 | 70 | 76 | 77 | 78 | 79 | 81 | 82 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /TestApps/iPhoneTestApp/iPhoneTestApp.xcodeproj/xcuserdata/colins.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | iPhoneTestApp.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 1F1EC0B31339F983007B5A96 16 | 17 | primary 18 | 19 | 20 | 1F1EC0D11339F983007B5A96 21 | 22 | primary 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /TestApps/iPhoneTestApp/iPhoneTestApp/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /TestApps/iPhoneTestApp/iPhoneTestApp/en.lproj/MainWindow.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 800 5 | 10D540 6 | 760 7 | 1038.29 8 | 460.00 9 | 10 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 11 | 81 12 | 13 | 14 | YES 15 | 16 | 17 | 18 | YES 19 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 20 | 21 | 22 | YES 23 | 24 | YES 25 | 26 | 27 | YES 28 | 29 | 30 | 31 | YES 32 | 33 | IBFilesOwner 34 | IBCocoaTouchFramework 35 | 36 | 37 | IBFirstResponder 38 | IBCocoaTouchFramework 39 | 40 | 41 | 42 | 292 43 | {768, 1024} 44 | 45 | 46 | 1 47 | MSAxIDEAA 48 | 49 | NO 50 | NO 51 | 52 | 2 53 | 54 | IBIPadFramework 55 | YES 56 | 57 | 58 | IBIPadFramework 59 | 60 | 61 | 62 | 63 | YES 64 | 65 | 66 | window 67 | 68 | 69 | 70 | 7 71 | 72 | 73 | 74 | delegate 75 | 76 | 77 | 78 | 8 79 | 80 | 81 | 82 | 83 | YES 84 | 85 | 0 86 | 87 | 88 | 89 | 90 | 91 | -1 92 | 93 | 94 | File's Owner 95 | 96 | 97 | -2 98 | 99 | 100 | 101 | 102 | 2 103 | 104 | 105 | 106 | 107 | 6 108 | 109 | 110 | 111 | 112 | 113 | 114 | YES 115 | 116 | YES 117 | -1.CustomClassName 118 | -2.CustomClassName 119 | 2.IBEditorWindowLastContentRect 120 | 2.IBPluginDependency 121 | 6.CustomClassName 122 | 6.IBPluginDependency 123 | 124 | 125 | YES 126 | UIApplication 127 | UIResponder 128 | {{226, 57}, {783, 799}} 129 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 130 | iPhoneTestAppAppDelegate 131 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 132 | 133 | 134 | 135 | YES 136 | 137 | 138 | YES 139 | 140 | 141 | 142 | 143 | YES 144 | 145 | 146 | YES 147 | 148 | 149 | 150 | 8 151 | 152 | 153 | 154 | YES 155 | 156 | iPhoneTestAppAppDelegate 157 | NSObject 158 | 159 | window 160 | UIWindow 161 | 162 | 163 | IBProjectSource 164 | iPhoneTestAppAppDelegate.h 165 | 166 | 167 | 168 | iPhoneTestAppAppDelegate 169 | NSObject 170 | 171 | IBUserSource 172 | 173 | 174 | 175 | 176 | 177 | YES 178 | 179 | NSObject 180 | 181 | IBFrameworkSource 182 | Foundation.framework/Headers/NSError.h 183 | 184 | 185 | 186 | NSObject 187 | 188 | IBFrameworkSource 189 | Foundation.framework/Headers/NSFileManager.h 190 | 191 | 192 | 193 | NSObject 194 | 195 | IBFrameworkSource 196 | Foundation.framework/Headers/NSKeyValueCoding.h 197 | 198 | 199 | 200 | NSObject 201 | 202 | IBFrameworkSource 203 | Foundation.framework/Headers/NSKeyValueObserving.h 204 | 205 | 206 | 207 | NSObject 208 | 209 | IBFrameworkSource 210 | Foundation.framework/Headers/NSKeyedArchiver.h 211 | 212 | 213 | 214 | NSObject 215 | 216 | IBFrameworkSource 217 | Foundation.framework/Headers/NSNetServices.h 218 | 219 | 220 | 221 | NSObject 222 | 223 | IBFrameworkSource 224 | Foundation.framework/Headers/NSObject.h 225 | 226 | 227 | 228 | NSObject 229 | 230 | IBFrameworkSource 231 | Foundation.framework/Headers/NSPort.h 232 | 233 | 234 | 235 | NSObject 236 | 237 | IBFrameworkSource 238 | Foundation.framework/Headers/NSRunLoop.h 239 | 240 | 241 | 242 | NSObject 243 | 244 | IBFrameworkSource 245 | Foundation.framework/Headers/NSStream.h 246 | 247 | 248 | 249 | NSObject 250 | 251 | IBFrameworkSource 252 | Foundation.framework/Headers/NSThread.h 253 | 254 | 255 | 256 | NSObject 257 | 258 | IBFrameworkSource 259 | Foundation.framework/Headers/NSURL.h 260 | 261 | 262 | 263 | NSObject 264 | 265 | IBFrameworkSource 266 | Foundation.framework/Headers/NSURLConnection.h 267 | 268 | 269 | 270 | NSObject 271 | 272 | IBFrameworkSource 273 | Foundation.framework/Headers/NSXMLParser.h 274 | 275 | 276 | 277 | NSObject 278 | 279 | IBFrameworkSource 280 | UIKit.framework/Headers/UIAccessibility.h 281 | 282 | 283 | 284 | NSObject 285 | 286 | IBFrameworkSource 287 | UIKit.framework/Headers/UINibLoading.h 288 | 289 | 290 | 291 | NSObject 292 | 293 | IBFrameworkSource 294 | UIKit.framework/Headers/UIResponder.h 295 | 296 | 297 | 298 | UIApplication 299 | UIResponder 300 | 301 | IBFrameworkSource 302 | UIKit.framework/Headers/UIApplication.h 303 | 304 | 305 | 306 | UIResponder 307 | NSObject 308 | 309 | 310 | 311 | UIResponder 312 | 313 | IBFrameworkSource 314 | UIKit.framework/Headers/UITextInput.h 315 | 316 | 317 | 318 | UIView 319 | 320 | IBFrameworkSource 321 | UIKit.framework/Headers/UITextField.h 322 | 323 | 324 | 325 | UIView 326 | UIResponder 327 | 328 | IBFrameworkSource 329 | UIKit.framework/Headers/UIView.h 330 | 331 | 332 | 333 | UIWindow 334 | UIView 335 | 336 | IBFrameworkSource 337 | UIKit.framework/Headers/UIWindow.h 338 | 339 | 340 | 341 | 342 | 0 343 | IBIPadFramework 344 | 345 | com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS 346 | 347 | 348 | 349 | com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 350 | 351 | 352 | YES 353 | iPhoneTestApp.xcodeproj 354 | 3 355 | 81 356 | 357 | 358 | -------------------------------------------------------------------------------- /TestApps/iPhoneTestApp/iPhoneTestApp/iPhoneTestApp-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIconFile 12 | 13 | CFBundleIdentifier 14 | mobilemelting.${PRODUCT_NAME:rfc1034identifier} 15 | CFBundleInfoDictionaryVersion 16 | 6.0 17 | CFBundleName 18 | ${PRODUCT_NAME} 19 | CFBundlePackageType 20 | APPL 21 | CFBundleShortVersionString 22 | 1.0 23 | CFBundleSignature 24 | ???? 25 | CFBundleVersion 26 | 1.0 27 | LSRequiresIPhoneOS 28 | 29 | NSMainNibFile 30 | MainWindow 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | 35 | UISupportedInterfaceOrientations~ipad 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationLandscapeLeft 39 | UIInterfaceOrientationLandscapeRight 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /TestApps/iPhoneTestApp/iPhoneTestApp/iPhoneTestApp-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'iPhoneTestApp' target in the 'iPhoneTestApp' project 3 | // 4 | 5 | #import 6 | 7 | #ifndef __IPHONE_3_0 8 | #warning "This project uses features only available in iPhone SDK 3.0 and later." 9 | #endif 10 | 11 | #ifdef __OBJC__ 12 | #import 13 | #import 14 | #endif 15 | -------------------------------------------------------------------------------- /TestApps/iPhoneTestApp/iPhoneTestApp/iPhoneTestAppAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // iPhoneTestAppAppDelegate.h 3 | // iPhoneTestApp 4 | // 5 | // Created by Jörg Polakowski on 23/03/11. 6 | // Copyright 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface iPhoneTestAppAppDelegate : NSObject { 12 | 13 | } 14 | 15 | @property (nonatomic, retain) IBOutlet UIWindow *window; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /TestApps/iPhoneTestApp/iPhoneTestApp/iPhoneTestAppAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // iPhoneTestAppAppDelegate.m 3 | // iPhoneTestApp 4 | // 5 | // Created by Jörg Polakowski on 23/03/11. 6 | // Copyright 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import "iPhoneTestAppAppDelegate.h" 10 | 11 | @implementation iPhoneTestAppAppDelegate 12 | 13 | 14 | @synthesize window=_window; 15 | 16 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 17 | { 18 | // Override point for customization after application launch. 19 | [self.window makeKeyAndVisible]; 20 | return YES; 21 | } 22 | 23 | - (void)applicationWillResignActive:(UIApplication *)application 24 | { 25 | /* 26 | Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 27 | Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 28 | */ 29 | } 30 | 31 | - (void)applicationDidEnterBackground:(UIApplication *)application 32 | { 33 | /* 34 | Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 35 | If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 36 | */ 37 | } 38 | 39 | - (void)applicationWillEnterForeground:(UIApplication *)application 40 | { 41 | /* 42 | Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 43 | */ 44 | } 45 | 46 | - (void)applicationDidBecomeActive:(UIApplication *)application 47 | { 48 | /* 49 | Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 50 | */ 51 | } 52 | 53 | - (void)applicationWillTerminate:(UIApplication *)application 54 | { 55 | /* 56 | Called when the application is about to terminate. 57 | Save data if appropriate. 58 | See also applicationDidEnterBackground:. 59 | */ 60 | } 61 | 62 | - (void)dealloc 63 | { 64 | [_window release]; 65 | [super dealloc]; 66 | } 67 | 68 | @end 69 | -------------------------------------------------------------------------------- /TestApps/iPhoneTestApp/iPhoneTestApp/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // iPhoneTestApp 4 | // 5 | // Created by Jörg Polakowski on 23/03/11. 6 | // Copyright 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | int main(int argc, char *argv[]) 12 | { 13 | NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 14 | int retVal = UIApplicationMain(argc, argv, nil, nil); 15 | [pool release]; 16 | return retVal; 17 | } 18 | -------------------------------------------------------------------------------- /TestApps/iPhoneTestApp/iPhoneTestAppTests/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /TestApps/iPhoneTestApp/iPhoneTestAppTests/iPhoneTestAppTests-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | mobilemelting.${PRODUCT_NAME:rfc1034identifier} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundlePackageType 14 | BNDL 15 | CFBundleShortVersionString 16 | 1.0 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /TestApps/iPhoneTestApp/iPhoneTestAppTests/iPhoneTestAppTests-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'iPhoneTestAppTests' target in the 'iPhoneTestAppTests' project 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #import 7 | #endif 8 | -------------------------------------------------------------------------------- /TestApps/iPhoneTestApp/iPhoneTestAppTests/iPhoneTestAppTests.h: -------------------------------------------------------------------------------- 1 | // 2 | // iPhoneTestAppTests.h 3 | // iPhoneTestAppTests 4 | // 5 | // Created by Jörg Polakowski on 23/03/11. 6 | // Copyright 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | 12 | @interface iPhoneTestAppTests : SenTestCase { 13 | @private 14 | 15 | } 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /TestApps/iPhoneTestApp/iPhoneTestAppTests/iPhoneTestAppTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // iPhoneTestAppTests.m 3 | // iPhoneTestAppTests 4 | // 5 | // Created by Jörg Polakowski on 23/03/11. 6 | // Copyright 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import "iPhoneTestAppTests.h" 10 | 11 | 12 | @implementation iPhoneTestAppTests 13 | 14 | - (void)setUp 15 | { 16 | [super setUp]; 17 | 18 | // Set-up code here. 19 | } 20 | 21 | - (void)tearDown 22 | { 23 | // Tear-down code here. 24 | 25 | [super tearDown]; 26 | } 27 | 28 | - (void)testExample 29 | { 30 | STFail(@"Unit tests are not implemented yet in iPhoneTestAppTests"); 31 | } 32 | 33 | @end 34 | --------------------------------------------------------------------------------