Merge branch 'release/2.2.2'

* release/2.2.2:
  Some more 2 space indentation fixes
  fix example
  Set the delegate for Hockey and Quincy
  Remove unit test files and target
  Add appstore detection property
  Add workaround for not requiring -all_load linker flag and some Xcode project adjustments
  Updated manager for quincy logging and new delegate
  One more 2 space indentation fixes
  Add new delegate which fires when the user selected "Send Always" in the alert
  Fix for an older commit in QuincyKit being only half complete
  Don't treat empty server responses as success
  Added optional logging for debugging help
  set HOCKEYLIB_STATIC_LIBRARY define
  as a library, build for armv6 & armv7
  add xcworkspacedata
  add default xcodeproj
  Removing returning shared instance before dispatch_once is invoked
This commit is contained in:
Andreas Linde 2011-12-13 18:46:41 +01:00
commit 92f531b5f9
17 changed files with 859 additions and 397 deletions

1
.gitignore vendored
View File

@ -7,7 +7,6 @@ build/*
*.perspective
*.perspectivev3
!default.perspectivev3
*.xcworkspace
!default.xcworkspace
xcuserdata
profile

View File

@ -36,10 +36,10 @@ NSBundle *hockeyBundle(void) {
}
NSString *BWmd5(NSString *str) {
const char *cStr = [str UTF8String];
unsigned char result[CC_MD5_DIGEST_LENGTH];
CC_MD5( cStr, strlen(cStr), result );
return [NSString
const char *cStr = [str UTF8String];
unsigned char result[CC_MD5_DIGEST_LENGTH];
CC_MD5( cStr, strlen(cStr), result );
return [NSString
stringWithFormat: @"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
result[0], result[1],
result[2], result[3],

View File

@ -123,8 +123,6 @@ static NSString *kHockeyErrorDomain = @"HockeyErrorDomain";
static BWHockeyManager *sharedInstance = nil;
static dispatch_once_t pred;
if (sharedInstance) return sharedInstance;
dispatch_once(&pred, ^{
sharedInstance = [BWHockeyManager alloc];
sharedInstance = [sharedInstance init];

View File

@ -62,7 +62,7 @@
}
- (id)init {
return [self init:[BWHockeyManager sharedHockeyManager]];
return [self init:[BWHockeyManager sharedHockeyManager]];
}
#pragma mark -

View File

@ -295,26 +295,26 @@
}
- (CAGradientLayer *)backgroundLayer {
UIColor *colorOne = [UIColor colorWithWhite:0.9 alpha:1.0];
UIColor *colorTwo = [UIColor colorWithHue:0.625 saturation:0.0 brightness:0.85 alpha:1.0];
UIColor *colorThree = [UIColor colorWithHue:0.625 saturation:0.0 brightness:0.7 alpha:1.0];
UIColor *colorFour = [UIColor colorWithHue:0.625 saturation:0.0 brightness:0.4 alpha:1.0];
UIColor *colorOne = [UIColor colorWithWhite:0.9 alpha:1.0];
UIColor *colorTwo = [UIColor colorWithHue:0.625 saturation:0.0 brightness:0.85 alpha:1.0];
UIColor *colorThree = [UIColor colorWithHue:0.625 saturation:0.0 brightness:0.7 alpha:1.0];
UIColor *colorFour = [UIColor colorWithHue:0.625 saturation:0.0 brightness:0.4 alpha:1.0];
NSArray *colors = [NSArray arrayWithObjects:(id)colorOne.CGColor, colorTwo.CGColor, colorThree.CGColor, colorFour.CGColor, nil];
NSArray *colors = [NSArray arrayWithObjects:(id)colorOne.CGColor, colorTwo.CGColor, colorThree.CGColor, colorFour.CGColor, nil];
NSNumber *stopOne = [NSNumber numberWithFloat:0.0];
NSNumber *stopTwo = [NSNumber numberWithFloat:0.02];
NSNumber *stopThree = [NSNumber numberWithFloat:0.99];
NSNumber *stopFour = [NSNumber numberWithFloat:1.0];
NSNumber *stopOne = [NSNumber numberWithFloat:0.0];
NSNumber *stopTwo = [NSNumber numberWithFloat:0.02];
NSNumber *stopThree = [NSNumber numberWithFloat:0.99];
NSNumber *stopFour = [NSNumber numberWithFloat:1.0];
NSArray *locations = [NSArray arrayWithObjects:stopOne, stopTwo, stopThree, stopFour, nil];
NSArray *locations = [NSArray arrayWithObjects:stopOne, stopTwo, stopThree, stopFour, nil];
CAGradientLayer *headerLayer = [CAGradientLayer layer];
//headerLayer.frame = CGRectMake(0.0, 0.0, 320.0, 77.0);
headerLayer.colors = colors;
headerLayer.locations = locations;
CAGradientLayer *headerLayer = [CAGradientLayer layer];
//headerLayer.frame = CGRectMake(0.0, 0.0, 320.0, 77.0);
headerLayer.colors = colors;
headerLayer.locations = locations;
return headerLayer;
return headerLayer;
}
- (void)viewDidLoad {

View File

@ -29,6 +29,8 @@
#import <Foundation/Foundation.h>
#define BWQuincyLog(fmt, ...) do { if([BWQuincyManager sharedQuincyManager].isLoggingEnabled) { NSLog((@"[QuincyLib] %s/%d " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__); }} while(0)
#define kQuincyBundleName @"Quincy.bundle"
NSBundle *quincyBundle(void);
@ -52,31 +54,31 @@ NSString *BWQuincyLocalize(NSString *stringToken);
#define BWQuincyNetworkBecomeReachable @"NetworkDidBecomeReachable"
typedef enum QuincyKitAlertType {
QuincyKitAlertTypeSend = 0,
QuincyKitAlertTypeFeedback = 1,
QuincyKitAlertTypeSend = 0,
QuincyKitAlertTypeFeedback = 1,
} CrashAlertType;
typedef enum CrashReportStatus {
// The status of the crash is queued, need to check later (HockeyApp)
CrashReportStatusQueued = -80,
CrashReportStatusQueued = -80,
// This app version is set to discontinued, no new crash reports accepted by the server
CrashReportStatusFailureVersionDiscontinued = -30,
CrashReportStatusFailureVersionDiscontinued = -30,
// XML: Sender version string contains not allowed characters, only alphanumberical including space and . are allowed
CrashReportStatusFailureXMLSenderVersionNotAllowed = -21,
CrashReportStatusFailureXMLSenderVersionNotAllowed = -21,
// XML: Version string contains not allowed characters, only alphanumberical including space and . are allowed
CrashReportStatusFailureXMLVersionNotAllowed = -20,
CrashReportStatusFailureXMLVersionNotAllowed = -20,
// SQL for adding a symoblicate todo entry in the database failed
CrashReportStatusFailureSQLAddSymbolicateTodo = -18,
CrashReportStatusFailureSQLAddSymbolicateTodo = -18,
// SQL for adding crash log in the database failed
CrashReportStatusFailureSQLAddCrashlog = -17,
CrashReportStatusFailureSQLAddCrashlog = -17,
// SQL for adding a new version in the database failed
CrashReportStatusFailureSQLAddVersion = -16,
CrashReportStatusFailureSQLAddVersion = -16,
// SQL for checking if the version is already added in the database failed
CrashReportStatusFailureSQLCheckVersionExists = -15,
@ -137,6 +139,9 @@ typedef enum CrashReportStatus {
// Invoked before the user is asked to send a crash report, so you can do additional actions. E.g. to make sure not to ask the user for an app rating :)
-(void) willShowSubmitCrashReportAlert;
// Invoked after the user did choose to send crashes always in the alert
-(void) userDidChooseSendAlways;
@end
@interface BWQuincyManager : NSObject <NSXMLParserDelegate> {
@ -144,6 +149,7 @@ typedef enum CrashReportStatus {
id <BWQuincyManagerDelegate> _delegate;
BOOL _loggingEnabled;
BOOL _showAlwaysButton;
BOOL _feedbackActivated;
BOOL _autoSubmitCrashReport;
@ -156,19 +162,19 @@ typedef enum CrashReportStatus {
NSString *_feedbackRequestID;
float _feedbackDelayInterval;
NSMutableString *_contentOfProperty;
CrashReportStatus _serverResult;
NSMutableString *_contentOfProperty;
CrashReportStatus _serverResult;
int _analyzerStarted;
NSString *_crashesDir;
int _analyzerStarted;
NSString *_crashesDir;
BOOL _crashIdenticalCurrentVersion;
BOOL _crashIdenticalCurrentVersion;
BOOL _crashReportActivated;
NSMutableArray *_crashFiles;
NSMutableArray *_crashFiles;
NSMutableData *_responseData;
NSInteger _statusCode;
NSMutableData *_responseData;
NSInteger _statusCode;
NSURLConnection *_urlConnection;
@ -189,6 +195,10 @@ typedef enum CrashReportStatus {
///////////////////////////////////////////////////////////////////////////////////////////////////
// settings
// if YES, states will be logged using NSLog. Only enable this for debugging!
// if NO, nothing will be logged. (default)
@property (nonatomic, assign, getter=isLoggingEnabled) BOOL loggingEnabled;
// nil, using the default localization files (Default)
// set to another string which will be appended to the Quincy localization file name, "Alternate" is another provided text set
@property (nonatomic, retain) NSString *languageStyle;

View File

@ -87,12 +87,12 @@ NSString *BWQuincyLocalize(NSString *stringToken) {
@synthesize autoSubmitDeviceUDID = _autoSubmitDeviceUDID;
@synthesize languageStyle = _languageStyle;
@synthesize didCrashInLastSession = _didCrashInLastSession;
@synthesize loggingEnabled = _loggingEnabled;
@synthesize appIdentifier = _appIdentifier;
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 40000
+(BWQuincyManager *)sharedQuincyManager
{
+(BWQuincyManager *)sharedQuincyManager {
static BWQuincyManager *sharedInstance = nil;
static dispatch_once_t pred;
@ -105,86 +105,87 @@ NSString *BWQuincyLocalize(NSString *stringToken) {
}
#else
+ (BWQuincyManager *)sharedQuincyManager {
static BWQuincyManager *quincyManager = nil;
static BWQuincyManager *quincyManager = nil;
if (quincyManager == nil) {
quincyManager = [[BWQuincyManager alloc] init];
}
if (quincyManager == nil) {
quincyManager = [[BWQuincyManager alloc] init];
}
return quincyManager;
return quincyManager;
}
#endif
- (id) init {
if ((self = [super init])) {
_serverResult = CrashReportStatusUnknown;
_crashIdenticalCurrentVersion = YES;
_crashData = nil;
_serverResult = CrashReportStatusUnknown;
_crashIdenticalCurrentVersion = YES;
_crashData = nil;
_urlConnection = nil;
_submissionURL = nil;
_submissionURL = nil;
_responseData = nil;
_appIdentifier = nil;
_sendingInProgress = NO;
_languageStyle = nil;
_didCrashInLastSession = NO;
_loggingEnabled = NO;
self.delegate = nil;
self.delegate = nil;
self.feedbackActivated = NO;
self.showAlwaysButton = NO;
self.autoSubmitCrashReport = NO;
self.autoSubmitDeviceUDID = NO;
NSString *testValue = [[NSUserDefaults standardUserDefaults] stringForKey:kQuincyKitAnalyzerStarted];
if (testValue) {
_analyzerStarted = [[NSUserDefaults standardUserDefaults] integerForKey:kQuincyKitAnalyzerStarted];
} else {
_analyzerStarted = 0;
}
NSString *testValue = [[NSUserDefaults standardUserDefaults] stringForKey:kQuincyKitAnalyzerStarted];
if (testValue) {
_analyzerStarted = [[NSUserDefaults standardUserDefaults] integerForKey:kQuincyKitAnalyzerStarted];
} else {
_analyzerStarted = 0;
}
testValue = nil;
testValue = [[NSUserDefaults standardUserDefaults] stringForKey:kQuincyKitActivated];
if (testValue) {
_crashReportActivated = [[NSUserDefaults standardUserDefaults] boolForKey:kQuincyKitActivated];
} else {
_crashReportActivated = YES;
[[NSUserDefaults standardUserDefaults] setValue:[NSNumber numberWithBool:YES] forKey:kQuincyKitActivated];
}
testValue = nil;
testValue = [[NSUserDefaults standardUserDefaults] stringForKey:kQuincyKitActivated];
if (testValue) {
_crashReportActivated = [[NSUserDefaults standardUserDefaults] boolForKey:kQuincyKitActivated];
} else {
_crashReportActivated = YES;
[[NSUserDefaults standardUserDefaults] setValue:[NSNumber numberWithBool:YES] forKey:kQuincyKitActivated];
}
if (_crashReportActivated) {
_crashFiles = [[NSMutableArray alloc] init];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
_crashesDir = [[NSString stringWithFormat:@"%@", [[paths objectAtIndex:0] stringByAppendingPathComponent:@"/crashes/"]] retain];
if (_crashReportActivated) {
_crashFiles = [[NSMutableArray alloc] init];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
_crashesDir = [[NSString stringWithFormat:@"%@", [[paths objectAtIndex:0] stringByAppendingPathComponent:@"/crashes/"]] retain];
NSFileManager *fm = [NSFileManager defaultManager];
NSFileManager *fm = [NSFileManager defaultManager];
if (![fm fileExistsAtPath:_crashesDir]) {
NSDictionary *attributes = [NSDictionary dictionaryWithObject: [NSNumber numberWithUnsignedLong: 0755] forKey: NSFilePosixPermissions];
NSError *theError = NULL;
if (![fm fileExistsAtPath:_crashesDir]) {
NSDictionary *attributes = [NSDictionary dictionaryWithObject: [NSNumber numberWithUnsignedLong: 0755] forKey: NSFilePosixPermissions];
NSError *theError = NULL;
[fm createDirectoryAtPath:_crashesDir withIntermediateDirectories: YES attributes: attributes error: &theError];
}
PLCrashReporter *crashReporter = [PLCrashReporter sharedReporter];
NSError *error = NULL;
// Check if we previously crashed
if ([crashReporter hasPendingCrashReport]) {
_didCrashInLastSession = YES;
[self handleCrashReport];
[fm createDirectoryAtPath:_crashesDir withIntermediateDirectories: YES attributes: attributes error: &theError];
}
// Enable the Crash Reporter
if (![crashReporter enableCrashReporterAndReturnError: &error])
NSLog(@"Warning: Could not enable crash reporter: %@", error);
PLCrashReporter *crashReporter = [PLCrashReporter sharedReporter];
NSError *error = NULL;
// Check if we previously crashed
if ([crashReporter hasPendingCrashReport]) {
_didCrashInLastSession = YES;
[self handleCrashReport];
}
// Enable the Crash Reporter
if (![crashReporter enableCrashReporterAndReturnError: &error])
NSLog(@"WARNING: Could not enable crash reporter: %@", error);
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(startManager) name:BWQuincyNetworkBecomeReachable object:nil];
}
}
if (!quincyBundle()) {
NSLog(@"WARNING: Quincy.bundle is missing in the app bundle!");
NSLog(@"WARNING: Quincy.bundle is missing, will send reports automatically!");
}
}
return self;
}
return self;
}
@ -206,10 +207,10 @@ NSString *BWQuincyLocalize(NSString *stringToken) {
[_crashData release];
[_crashesDir release];
[_crashFiles release];
[_crashesDir release];
[_crashFiles release];
[super dealloc];
[super dealloc];
}
@ -256,9 +257,9 @@ NSString *BWQuincyLocalize(NSString *stringToken) {
if (!_sendingInProgress && [self hasPendingCrashReport]) {
_sendingInProgress = YES;
if (!quincyBundle()) {
NSLog(@"Quincy.bundle is missing, sending report automatically!");
NSLog(@"WARNING: Quincy.bundle is missing, sending reports automatically!");
[self _sendCrashReports];
} else if (!self.autoSubmitCrashReport && [self hasNonApprovedCrashReports]) {
} else if (![self autoSendCrashReports] && [self hasNonApprovedCrashReports]) {
if (self.delegate != nil && [self.delegate respondsToSelector:@selector(willShowSubmitCrashReportAlert)]) {
[self.delegate willShowSubmitCrashReportAlert];
@ -290,8 +291,8 @@ NSString *BWQuincyLocalize(NSString *stringToken) {
if (!approvedCrashReports || [approvedCrashReports count] == 0) return YES;
for (NSUInteger i=0; i < [_crashFiles count]; i++) {
NSString *filename = [_crashFiles objectAtIndex:i];
for (NSUInteger i=0; i < [_crashFiles count]; i++) {
NSString *filename = [_crashFiles objectAtIndex:i];
if (![approvedCrashReports objectForKey:filename]) return YES;
}
@ -300,73 +301,74 @@ NSString *BWQuincyLocalize(NSString *stringToken) {
}
- (BOOL)hasPendingCrashReport {
if (_crashReportActivated) {
NSFileManager *fm = [NSFileManager defaultManager];
if (_crashReportActivated) {
NSFileManager *fm = [NSFileManager defaultManager];
if ([_crashFiles count] == 0 && [fm fileExistsAtPath:_crashesDir]) {
NSString *file = nil;
if ([_crashFiles count] == 0 && [fm fileExistsAtPath:_crashesDir]) {
NSString *file = nil;
NSError *error = NULL;
NSDirectoryEnumerator *dirEnum = [fm enumeratorAtPath: _crashesDir];
NSDirectoryEnumerator *dirEnum = [fm enumeratorAtPath: _crashesDir];
while ((file = [dirEnum nextObject])) {
NSDictionary *fileAttributes = [fm attributesOfItemAtPath:[_crashesDir stringByAppendingPathComponent:file] error:&error];
if ([[fileAttributes objectForKey:NSFileSize] intValue] > 0) {
[_crashFiles addObject:file];
}
}
}
if ([_crashFiles count] > 0) {
return YES;
} else
return NO;
} else
return NO;
while ((file = [dirEnum nextObject])) {
NSDictionary *fileAttributes = [fm attributesOfItemAtPath:[_crashesDir stringByAppendingPathComponent:file] error:&error];
if ([[fileAttributes objectForKey:NSFileSize] intValue] > 0) {
[_crashFiles addObject:file];
}
}
}
if ([_crashFiles count] > 0) {
BWQuincyLog(@"Pending crash reports found.");
return YES;
} else
return NO;
} else
return NO;
}
- (void) showCrashStatusMessage {
UIAlertView *alertView = nil;
UIAlertView *alertView = nil;
if (_serverResult >= CrashReportStatusAssigned &&
_crashIdenticalCurrentVersion &&
quincyBundle()) {
// show some feedback to the user about the crash status
NSString *appName = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"];
switch (_serverResult) {
case CrashReportStatusAssigned:
alertView = [[UIAlertView alloc] initWithTitle: [NSString stringWithFormat:BWQuincyLocalize(@"CrashResponseTitle"), appName ]
if (_serverResult >= CrashReportStatusAssigned &&
_crashIdenticalCurrentVersion &&
quincyBundle()) {
// show some feedback to the user about the crash status
NSString *appName = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"];
switch (_serverResult) {
case CrashReportStatusAssigned:
alertView = [[UIAlertView alloc] initWithTitle: [NSString stringWithFormat:BWQuincyLocalize(@"CrashResponseTitle"), appName ]
message: [NSString stringWithFormat:BWQuincyLocalize(@"CrashResponseNextRelease"), appName]
delegate: self
cancelButtonTitle: BWQuincyLocalize(@"CrashResponseTitleOK")
otherButtonTitles: nil];
break;
case CrashReportStatusSubmitted:
alertView = [[UIAlertView alloc] initWithTitle: [NSString stringWithFormat:BWQuincyLocalize(@"CrashResponseTitle"), appName ]
break;
case CrashReportStatusSubmitted:
alertView = [[UIAlertView alloc] initWithTitle: [NSString stringWithFormat:BWQuincyLocalize(@"CrashResponseTitle"), appName ]
message: [NSString stringWithFormat:BWQuincyLocalize(@"CrashResponseWaitingApple"), appName]
delegate: self
cancelButtonTitle: BWQuincyLocalize(@"CrashResponseTitleOK")
otherButtonTitles: nil];
break;
case CrashReportStatusAvailable:
alertView = [[UIAlertView alloc] initWithTitle: [NSString stringWithFormat:BWQuincyLocalize(@"CrashResponseTitle"), appName ]
break;
case CrashReportStatusAvailable:
alertView = [[UIAlertView alloc] initWithTitle: [NSString stringWithFormat:BWQuincyLocalize(@"CrashResponseTitle"), appName ]
message: [NSString stringWithFormat:BWQuincyLocalize(@"CrashResponseAvailable"), appName]
delegate: self
cancelButtonTitle: BWQuincyLocalize(@"CrashResponseTitleOK")
otherButtonTitles: nil];
break;
default:
alertView = nil;
break;
}
break;
default:
alertView = nil;
break;
}
if (alertView) {
[alertView setTag: QuincyKitAlertTypeFeedback];
[alertView show];
[alertView release];
}
}
if (alertView) {
[alertView setTag: QuincyKitAlertTypeFeedback];
[alertView show];
[alertView release];
}
}
}
@ -374,22 +376,31 @@ NSString *BWQuincyLocalize(NSString *stringToken) {
#pragma mark UIAlertView Delegate
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex {
if ([alertView tag] == QuincyKitAlertTypeSend) {
switch (buttonIndex) {
case 0:
if ([alertView tag] == QuincyKitAlertTypeSend) {
switch (buttonIndex) {
case 0:
_sendingInProgress = NO;
[self _cleanCrashReports];
break;
case 1:
[self _sendCrashReports];
break;
case 2:
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:kAutomaticallySendCrashReports];
[self _sendCrashReports];
break;
}
}
[self _cleanCrashReports];
break;
case 1:
[self _sendCrashReports];
break;
case 2: {
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:kAutomaticallySendCrashReports];
[[NSUserDefaults standardUserDefaults] synchronize];
if (self.delegate != nil && [self.delegate respondsToSelector:@selector(userDidChooseSendAlways)]) {
[self.delegate userDidChooseSendAlways];
}
[self _sendCrashReports];
break;
}
default:
_sendingInProgress = NO;
[self _cleanCrashReports];
break;
}
}
}
#pragma mark -
@ -398,40 +409,40 @@ NSString *BWQuincyLocalize(NSString *stringToken) {
#pragma mark NSXMLParser
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
if (qName) {
elementName = qName;
}
if (qName) {
elementName = qName;
}
if ([elementName isEqualToString:@"result"]) {
_contentOfProperty = [NSMutableString string];
if ([elementName isEqualToString:@"result"]) {
_contentOfProperty = [NSMutableString string];
}
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
if (qName) {
elementName = qName;
}
if (qName) {
elementName = qName;
}
// open source implementation
if ([elementName isEqualToString: @"result"]) {
if ([_contentOfProperty intValue] > _serverResult) {
_serverResult = (CrashReportStatus)[_contentOfProperty intValue];
} else {
if ([elementName isEqualToString: @"result"]) {
if ([_contentOfProperty intValue] > _serverResult) {
_serverResult = (CrashReportStatus)[_contentOfProperty intValue];
} else {
CrashReportStatus errorcode = (CrashReportStatus)[_contentOfProperty intValue];
NSLog(@"CrashReporter ended in error code: %i", errorcode);
}
}
NSLog(@"CrashReporter ended in error code: %i", errorcode);
}
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
if (_contentOfProperty) {
// If the current element is one whose content we care about, append 'string'
// to the property that holds the content of the current element.
if (string != nil) {
[_contentOfProperty appendString:string];
}
}
if (_contentOfProperty) {
// If the current element is one whose content we care about, append 'string'
// to the property that holds the content of the current element.
if (string != nil) {
[_contentOfProperty appendString:string];
}
}
}
#pragma mark -
@ -439,13 +450,13 @@ NSString *BWQuincyLocalize(NSString *stringToken) {
- (NSString *)_getDevicePlatform {
size_t size = 0;
sysctlbyname("hw.machine", NULL, &size, NULL, 0);
char *answer = (char*)malloc(size);
sysctlbyname("hw.machine", answer, &size, NULL, 0);
NSString *platform = [NSString stringWithCString:answer encoding: NSUTF8StringEncoding];
free(answer);
return platform;
size_t size = 0;
sysctlbyname("hw.machine", NULL, &size, NULL, 0);
char *answer = (char*)malloc(size);
sysctlbyname("hw.machine", answer, &size, NULL, 0);
NSString *platform = [NSString stringWithCString:answer encoding: NSUTF8StringEncoding];
free(answer);
return platform;
}
- (NSString *)deviceIdentifier {
@ -461,52 +472,52 @@ NSString *BWQuincyLocalize(NSString *stringToken) {
NSMutableDictionary *approvedCrashReports = [NSMutableDictionary dictionaryWithDictionary:[[NSUserDefaults standardUserDefaults] dictionaryForKey: kApprovedCrashReports]];
NSFileManager *fm = [NSFileManager defaultManager];
NSError *error = NULL;
NSError *error = NULL;
NSString *userid = @"";
NSString *contact = @"";
NSString *description = @"";
NSString *userid = @"";
NSString *contact = @"";
NSString *description = @"";
if (self.autoSubmitDeviceUDID && [[NSBundle mainBundle] pathForResource:@"embedded" ofType:@"mobileprovision"]) {
userid = [self deviceIdentifier];
} else if (self.delegate != nil && [self.delegate respondsToSelector:@selector(crashReportUserID)]) {
userid = [self.delegate crashReportUserID] ?: @"";
}
userid = [self.delegate crashReportUserID] ?: @"";
}
if (self.delegate != nil && [self.delegate respondsToSelector:@selector(crashReportContact)]) {
contact = [self.delegate crashReportContact] ?: @"";
}
if (self.delegate != nil && [self.delegate respondsToSelector:@selector(crashReportContact)]) {
contact = [self.delegate crashReportContact] ?: @"";
}
if (self.delegate != nil && [self.delegate respondsToSelector:@selector(crashReportDescription)]) {
description = [self.delegate crashReportDescription] ?: @"";
}
if (self.delegate != nil && [self.delegate respondsToSelector:@selector(crashReportDescription)]) {
description = [self.delegate crashReportDescription] ?: @"";
}
NSMutableString *crashes = nil;
_crashIdenticalCurrentVersion = NO;
for (NSUInteger i=0; i < [_crashFiles count]; i++) {
NSString *filename = [_crashesDir stringByAppendingPathComponent:[_crashFiles objectAtIndex:i]];
NSData *crashData = [NSData dataWithContentsOfFile:filename];
for (NSUInteger i=0; i < [_crashFiles count]; i++) {
NSString *filename = [_crashesDir stringByAppendingPathComponent:[_crashFiles objectAtIndex:i]];
NSData *crashData = [NSData dataWithContentsOfFile:filename];
if ([crashData length] > 0) {
PLCrashReport *report = [[[PLCrashReport alloc] initWithData:crashData error:&error] autorelease];
if ([crashData length] > 0) {
PLCrashReport *report = [[[PLCrashReport alloc] initWithData:crashData error:&error] autorelease];
if (report == nil) {
NSLog(@"Could not parse crash report");
continue;
}
NSString *crashLogString = [PLCrashReportTextFormatter stringValueForCrashReport:report withTextFormat:PLCrashReportTextFormatiOS];
NSString *crashLogString = [PLCrashReportTextFormatter stringValueForCrashReport:report withTextFormat:PLCrashReportTextFormatiOS];
if ([report.applicationInfo.applicationVersion compare:[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"]] == NSOrderedSame) {
_crashIdenticalCurrentVersion = YES;
}
if ([report.applicationInfo.applicationVersion compare:[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"]] == NSOrderedSame) {
_crashIdenticalCurrentVersion = YES;
}
if (crashes == nil) {
crashes = [NSMutableString string];
}
[crashes appendFormat:@"<crash><applicationname>%s</applicationname><bundleidentifier>%@</bundleidentifier><systemversion>%@</systemversion><platform>%@</platform><senderversion>%@</senderversion><version>%@</version><log><![CDATA[%@]]></log><userid>%@</userid><contact>%@</contact><description><![CDATA[%@]]></description></crash>",
[crashes appendFormat:@"<crash><applicationname>%s</applicationname><bundleidentifier>%@</bundleidentifier><systemversion>%@</systemversion><platform>%@</platform><senderversion>%@</senderversion><version>%@</version><log><![CDATA[%@]]></log><userid>%@</userid><contact>%@</contact><description><![CDATA[%@]]></description></crash>",
[[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleExecutable"] UTF8String],
report.applicationInfo.applicationIdentifier,
report.systemInfo.operatingSystemVersion,
@ -516,21 +527,22 @@ NSString *BWQuincyLocalize(NSString *stringToken) {
[crashLogString stringByReplacingOccurrencesOfString:@"]]>" withString:@"]]" @"]]><![CDATA[" @">" options:NSLiteralSearch range:NSMakeRange(0,crashLogString.length)],
userid,
contact,
[description stringByReplacingOccurrencesOfString:@"]]>" withString:@"]]" @"]]><![CDATA[" @">" options:NSLiteralSearch range:NSMakeRange(0,description.length)]];
[description stringByReplacingOccurrencesOfString:@"]]>" withString:@"]]" @"]]><![CDATA[" @">" options:NSLiteralSearch range:NSMakeRange(0,description.length)]];
// store this crash report as user approved, so if it fails it will retry automatically
[approvedCrashReports setObject:[NSNumber numberWithBool:YES] forKey:[_crashFiles objectAtIndex:i]];
} else {
} else {
// we cannot do anything with this report, so delete it
[fm removeItemAtPath:filename error:&error];
}
}
}
[[NSUserDefaults standardUserDefaults] setObject:approvedCrashReports forKey:kApprovedCrashReports];
[[NSUserDefaults standardUserDefaults] synchronize];
if (crashes != nil) {
BWQuincyLog(@"Sending crash reports:\n%@", crashes);
[self _postXML:[NSString stringWithFormat:@"<crashes>%@</crashes>", crashes]
toURL:[NSURL URLWithString:self.submissionURL]];
@ -559,56 +571,60 @@ NSString *BWQuincyLocalize(NSString *stringToken) {
- (void)_checkForFeedbackStatus {
NSMutableURLRequest *request = nil;
request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@api/2/apps/%@/crashes/%@",
self.submissionURL,
[self.appIdentifier stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding],
_feedbackRequestID
]
]];
request = [NSMutableURLRequest requestWithURL:
[NSURL URLWithString:[NSString stringWithFormat:@"%@api/2/apps/%@/crashes/%@",
self.submissionURL,
[self.appIdentifier stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding],
_feedbackRequestID
]
]];
[request setCachePolicy: NSURLRequestReloadIgnoringLocalCacheData];
[request setValue:@"Quincy/iOS" forHTTPHeaderField:@"User-Agent"];
[request setCachePolicy: NSURLRequestReloadIgnoringLocalCacheData];
[request setValue:@"Quincy/iOS" forHTTPHeaderField:@"User-Agent"];
[request setValue:@"gzip" forHTTPHeaderField:@"Accept-Encoding"];
[request setTimeoutInterval: 15];
[request setHTTPMethod:@"GET"];
[request setTimeoutInterval: 15];
[request setHTTPMethod:@"GET"];
_serverResult = CrashReportStatusUnknown;
_statusCode = 200;
_serverResult = CrashReportStatusUnknown;
_statusCode = 200;
// Release when done in the delegate method
_responseData = [[NSMutableData alloc] init];
// Release when done in the delegate method
_responseData = [[NSMutableData alloc] init];
if (self.delegate != nil && [self.delegate respondsToSelector:@selector(connectionOpened)]) {
[self.delegate connectionOpened];
}
if (self.delegate != nil && [self.delegate respondsToSelector:@selector(connectionOpened)]) {
[self.delegate connectionOpened];
}
_urlConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
_urlConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
BWQuincyLog(@"Requesting feedback status.");
}
- (void)_postXML:(NSString*)xml toURL:(NSURL*)url {
NSMutableURLRequest *request = nil;
NSMutableURLRequest *request = nil;
NSString *boundary = @"----FOO";
if (self.appIdentifier) {
request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@api/2/apps/%@/crashes",
self.submissionURL,
[self.appIdentifier stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]
]
]];
request = [NSMutableURLRequest requestWithURL:
[NSURL URLWithString:[NSString stringWithFormat:@"%@api/2/apps/%@/crashes",
self.submissionURL,
[self.appIdentifier stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]
]
]];
} else {
request = [NSMutableURLRequest requestWithURL:url];
}
[request setCachePolicy: NSURLRequestReloadIgnoringLocalCacheData];
[request setValue:@"Quincy/iOS" forHTTPHeaderField:@"User-Agent"];
[request setCachePolicy: NSURLRequestReloadIgnoringLocalCacheData];
[request setValue:@"Quincy/iOS" forHTTPHeaderField:@"User-Agent"];
[request setValue:@"gzip" forHTTPHeaderField:@"Accept-Encoding"];
[request setTimeoutInterval: 15];
[request setHTTPMethod:@"POST"];
NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary];
[request setValue:contentType forHTTPHeaderField:@"Content-type"];
[request setTimeoutInterval: 15];
[request setHTTPMethod:@"POST"];
NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary];
[request setValue:contentType forHTTPHeaderField:@"Content-type"];
NSMutableData *postBody = [NSMutableData data];
[postBody appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
NSMutableData *postBody = [NSMutableData data];
[postBody appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
if (self.appIdentifier) {
[postBody appendData:[@"Content-Disposition: form-data; name=\"xml\"; filename=\"crash.xml\"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[postBody appendData:[[NSString stringWithFormat:@"Content-Type: text/xml\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
@ -620,49 +636,54 @@ NSString *BWQuincyLocalize(NSString *stringToken) {
[request setHTTPBody:postBody];
_serverResult = CrashReportStatusUnknown;
_statusCode = 200;
_serverResult = CrashReportStatusUnknown;
_statusCode = 200;
//Release when done in the delegate method
_responseData = [[NSMutableData alloc] init];
//Release when done in the delegate method
_responseData = [[NSMutableData alloc] init];
if (self.delegate != nil && [self.delegate respondsToSelector:@selector(connectionOpened)]) {
[self.delegate connectionOpened];
}
if (self.delegate != nil && [self.delegate respondsToSelector:@selector(connectionOpened)]) {
[self.delegate connectionOpened];
}
_urlConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
_urlConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
if (!_urlConnection) {
BWQuincyLog(@"Sending crash reports could not start!");
_sendingInProgress = NO;
} else {
BWQuincyLog(@"Sending crash reports started.");
}
}
#pragma mark NSURLConnection Delegate
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
_statusCode = [(NSHTTPURLResponse *)response statusCode];
}
if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
_statusCode = [(NSHTTPURLResponse *)response statusCode];
}
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[_responseData appendData:data];
[_responseData appendData:data];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
[_responseData release];
_responseData = nil;
[_responseData release];
_responseData = nil;
_urlConnection = nil;
if (self.delegate != nil && [self.delegate respondsToSelector:@selector(connectionClosed)]) {
[self.delegate connectionClosed];
}
if (self.delegate != nil && [self.delegate respondsToSelector:@selector(connectionClosed)]) {
[self.delegate connectionClosed];
}
BWQuincyLog(@"ERROR: %@", [error localizedDescription]);
_sendingInProgress = NO;
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
if (_statusCode >= 200 && _statusCode < 400) {
if (_statusCode >= 200 && _statusCode < 400 && _responseData != nil && [_responseData length] > 0) {
[self _cleanCrashReports];
_feedbackRequestID = nil;
@ -672,6 +693,8 @@ NSString *BWQuincyLocalize(NSString *stringToken) {
mutabilityOption:NSPropertyListMutableContainersAndLeaves
format:nil
errorDescription:NULL];
BWQuincyLog(@"Received API response: %@", response);
_serverResult = (CrashReportStatus)[[response objectForKey:@"status"] intValue];
if ([response objectForKey:@"id"]) {
_feedbackRequestID = [[NSString alloc] initWithString:[response objectForKey:@"id"]];
@ -680,6 +703,8 @@ NSString *BWQuincyLocalize(NSString *stringToken) {
_feedbackDelayInterval *= 0.01;
}
} else {
BWQuincyLog(@"Received API response: %@", [[[NSString alloc] initWithBytes:[_responseData bytes] length:[_responseData length] encoding: NSUTF8StringEncoding] autorelease]);
NSXMLParser *parser = [[NSXMLParser alloc] initWithData:_responseData];
// Set self as the delegate of the parser so that it will receive the parser delegate methods callbacks.
[parser setDelegate:self];
@ -705,15 +730,21 @@ NSString *BWQuincyLocalize(NSString *stringToken) {
[self showCrashStatusMessage];
}
}
}
} else {
if (_responseData == nil || [_responseData length] == 0) {
BWQuincyLog(@"ERROR: Sending failed with an empty response!");
} else {
BWQuincyLog(@"ERROR: Sending failed with status code: %i", _statusCode);
}
}
[_responseData release];
_responseData = nil;
[_responseData release];
_responseData = nil;
_urlConnection = nil;
if (self.delegate != nil && [self.delegate respondsToSelector:@selector(connectionClosed)]) {
[self.delegate connectionClosed];
}
if (self.delegate != nil && [self.delegate respondsToSelector:@selector(connectionClosed)]) {
[self.delegate connectionClosed];
}
_sendingInProgress = NO;
}
@ -724,15 +755,15 @@ NSString *BWQuincyLocalize(NSString *stringToken) {
// Called to handle a pending crash report.
//
- (void) handleCrashReport {
PLCrashReporter *crashReporter = [PLCrashReporter sharedReporter];
NSError *error = NULL;
PLCrashReporter *crashReporter = [PLCrashReporter sharedReporter];
NSError *error = NULL;
// check if the next call ran successfully the last time
if (_analyzerStarted == 0) {
// mark the start of the routine
_analyzerStarted = 1;
[[NSUserDefaults standardUserDefaults] setValue:[NSNumber numberWithInt:_analyzerStarted] forKey:kQuincyKitAnalyzerStarted];
[[NSUserDefaults standardUserDefaults] synchronize];
if (_analyzerStarted == 0) {
// mark the start of the routine
_analyzerStarted = 1;
[[NSUserDefaults standardUserDefaults] setValue:[NSNumber numberWithInt:_analyzerStarted] forKey:kQuincyKitAnalyzerStarted];
[[NSUserDefaults standardUserDefaults] synchronize];
// Try loading the crash report
_crashData = [[NSData alloc] initWithData:[crashReporter loadPendingCrashReportDataAndReturnError: &error]];
@ -743,17 +774,17 @@ NSString *BWQuincyLocalize(NSString *stringToken) {
NSLog(@"Could not load crash report: %@", error);
} else {
[_crashData writeToFile:[_crashesDir stringByAppendingPathComponent: cacheFilename] atomically:YES];
}
}
}
}
// Purge the report
// mark the end of the routine
_analyzerStarted = 0;
[[NSUserDefaults standardUserDefaults] setValue:[NSNumber numberWithInt:_analyzerStarted] forKey:kQuincyKitAnalyzerStarted];
// Purge the report
// mark the end of the routine
_analyzerStarted = 0;
[[NSUserDefaults standardUserDefaults] setValue:[NSNumber numberWithInt:_analyzerStarted] forKey:kQuincyKitAnalyzerStarted];
[[NSUserDefaults standardUserDefaults] synchronize];
[crashReporter purgePendingCrashReport];
return;
[crashReporter purgePendingCrashReport];
return;
}

View File

@ -0,0 +1,25 @@
//
// CNSFixCategoryBug.h
// HockeySDK
//
// Created by Andreas Linde on 12/7/11.
// Copyright (c) 2011 Andreas Linde. All rights reserved.
//
#ifndef HockeySDK_CNSFixCategoryBug_h
#define HockeySDK_CNSFixCategoryBug_h
/**
Add this macro before each category implementation, so we don't have to use
-all_load or -force_load to load object files from static libraries that only contain
categories and no classes.
See http://developer.apple.com/library/mac/#qa/qa2006/qa1490.html for more info.
Shamelessly borrowed from Three20
*/
#define CNS_FIX_CATEGORY_BUG(name) @interface CNS_FIX_CATEGORY_BUG##name @end \
@implementation CNS_FIX_CATEGORY_BUG##name @end
#endif

View File

@ -80,6 +80,9 @@
// user for an app rating :)
- (void)willShowSubmitCrashReportAlert;
// Invoked after the user did choose to send crashes always in the alert
-(void) userDidChooseSendAlways;
@end
@interface CNSHockeyManager : NSObject {
@ -201,6 +204,10 @@
// Default: HockeyComparisonResultGreater
@property (nonatomic, assign) HockeyComparisonResult compareVersionType;
// if YES the app is installed from the app store
// if NO the app is installed via ad-hoc or enterprise distribution
@property (nonatomic, readonly) BOOL isAppStoreEnvironment;
#pragma mark - Public Methods
// Returns the shared manager object

View File

@ -42,10 +42,6 @@
static CNSHockeyManager *sharedInstance = nil;
static dispatch_once_t pred;
if (sharedInstance) {
return sharedInstance;
}
dispatch_once(&pred, ^{
sharedInstance = [CNSHockeyManager alloc];
sharedInstance = [sharedInstance init];
@ -55,13 +51,13 @@
}
#else
+ (CNSHockeyManager *)sharedHockeyManager {
static CNSHockeyManager *hockeyManager = nil;
static CNSHockeyManager *hockeyManager = nil;
if (hockeyManager == nil) {
hockeyManager = [[CNSHockeyManager alloc] init];
}
if (hockeyManager == nil) {
hockeyManager = [[CNSHockeyManager alloc] init];
}
return hockeyManager;
return hockeyManager;
}
#endif
@ -149,10 +145,12 @@
- (BOOL)isLoggingEnabled {
return [[BWHockeyManager sharedHockeyManager] isLoggingEnabled];
return [[BWQuincyManager sharedQuincyManager] isLoggingEnabled];
}
- (void)setLoggingEnabled:(BOOL)loggingEnabled {
return [[BWHockeyManager sharedHockeyManager] setLoggingEnabled:loggingEnabled];
return [[BWQuincyManager sharedQuincyManager] setLoggingEnabled:loggingEnabled];
}
#pragma mark - Public Instance Methods (Crash Reporting)
@ -299,6 +297,10 @@
[[BWHockeyManager sharedHockeyManager] setCompareVersionType:compareVersionType];
}
- (BOOL)isAppStoreEnvironment {
return [[BWHockeyManager sharedHockeyManager] isAppStoreEnvironment];
}
- (BOOL)isUpdateAvailable {
return [[BWHockeyManager sharedHockeyManager] isUpdateAvailable];
}
@ -348,12 +350,14 @@
- (void)configureQuincyManager {
[[BWQuincyManager sharedQuincyManager] setAppIdentifier:appIdentifier];
[[BWQuincyManager sharedQuincyManager] setDelegate:delegate];
}
- (void)configureHockeyManager {
[[BWHockeyManager sharedHockeyManager] setAppIdentifier:appIdentifier];
[[BWHockeyManager sharedHockeyManager] setCheckForTracker:YES];
[[BWHockeyManager sharedHockeyManager] setDelegate:delegate];
// Only if JMC is part of the project
if ([[self class] isJMCPresent]) {
[[BWHockeyManager sharedHockeyManager] addObserver:self forKeyPath:@"trackerConfig" options:0 context:nil];

View File

@ -25,6 +25,10 @@
#import "NSString+HockeyAdditions.h"
#ifdef HOCKEYLIB_STATIC_LIBRARY
#import "CNSFixCategoryBug.h"
CNS_FIX_CATEGORY_BUG(NSString_HockeyAdditions)
#endif
@implementation NSString (HockeyAdditions)
@ -47,29 +51,28 @@
return result;
}
- (NSComparisonResult)versionCompare:(NSString *)other
{
// Extract plain version number from self
NSString *plainSelf = self;
NSRange letterRange = [plainSelf rangeOfCharacterFromSet: [NSCharacterSet letterCharacterSet]];
if (letterRange.length)
plainSelf = [plainSelf substringToIndex: letterRange.location];
- (NSComparisonResult)versionCompare:(NSString *)other {
// Extract plain version number from self
NSString *plainSelf = self;
NSRange letterRange = [plainSelf rangeOfCharacterFromSet: [NSCharacterSet letterCharacterSet]];
if (letterRange.length)
plainSelf = [plainSelf substringToIndex: letterRange.location];
// Extract plain version number from other
NSString *plainOther = other;
letterRange = [plainOther rangeOfCharacterFromSet: [NSCharacterSet letterCharacterSet]];
if (letterRange.length)
plainOther = [plainOther substringToIndex: letterRange.location];
// Extract plain version number from other
NSString *plainOther = other;
letterRange = [plainOther rangeOfCharacterFromSet: [NSCharacterSet letterCharacterSet]];
if (letterRange.length)
plainOther = [plainOther substringToIndex: letterRange.location];
// Compare plain versions
NSComparisonResult result = [plainSelf compare:plainOther options:NSNumericSearch];
// Compare plain versions
NSComparisonResult result = [plainSelf compare:plainOther options:NSNumericSearch];
// If plain versions are equal, compare full versions
if (result == NSOrderedSame)
result = [self compare:other options:NSNumericSearch];
// If plain versions are equal, compare full versions
if (result == NSOrderedSame)
result = [self compare:other options:NSNumericSearch];
// Done
return result;
// Done
return result;
}
@end

View File

@ -232,8 +232,8 @@
- (CGSize)sizeThatFits:(CGSize)size {
CGSize constr = (CGSize){.height = self.frame.size.height, .width = PS_MAX_WIDTH};
CGSize newSize = [self.buttonData.label sizeWithFont:self.titleLabel.font constrainedToSize:constr lineBreakMode:UILineBreakModeMiddleTruncation];
CGFloat newWidth = newSize.width + (PS_PADDING * 2);
CGSize newSize = [self.buttonData.label sizeWithFont:self.titleLabel.font constrainedToSize:constr lineBreakMode:UILineBreakModeMiddleTruncation];
CGFloat newWidth = newSize.width + (PS_PADDING * 2);
CGFloat newHeight = PS_MIN_HEIGHT > newSize.height ? PS_MIN_HEIGHT : newSize.height;
CGSize sizeThatFits = CGSizeMake(newWidth, newHeight);
@ -250,7 +250,7 @@
rect.size.height = self.frame.size.height;
aLayer.frame = rect;
[aLayer layoutIfNeeded];
}
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -52,15 +52,15 @@ body { font: 13px 'Helvetica Neue', Helvetica; word-wrap:break-word; padding:8px
#pragma mark private
- (void)addWebView {
if(webViewContent_) {
if(webViewContent_) {
CGRect webViewRect = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height);
if(!webView_) {
webView_ = [[[UIWebView alloc] initWithFrame:webViewRect] retain];
[self addSubview:webView_];
webView_.hidden = YES;
webView_.backgroundColor = self.cellBackgroundColor;
webView_.opaque = NO;
webView_.delegate = self;
if(!webView_) {
webView_ = [[[UIWebView alloc] initWithFrame:webViewRect] retain];
[self addSubview:webView_];
webView_.hidden = YES;
webView_.backgroundColor = self.cellBackgroundColor;
webView_.opaque = NO;
webView_.delegate = self;
webView_.autoresizingMask = UIViewAutoresizingFlexibleWidth;
for(UIView* subView in webView_.subviews){
@ -79,32 +79,32 @@ body { font: 13px 'Helvetica Neue', Helvetica; word-wrap:break-word; padding:8px
}
}
}
else
webView_.frame = webViewRect;
else
webView_.frame = webViewRect;
NSString *deviceWidth = UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad ? [NSString stringWithFormat:@"%d", CGRectGetWidth(self.bounds)] : @"device-width";
//BWHockeyLog(@"%@\n%@\%@", PSWebTableViewCellHtmlTemplate, deviceWidth, self.webViewContent);
NSString *contentHtml = [NSString stringWithFormat:PSWebTableViewCellHtmlTemplate, deviceWidth, self.webViewContent];
[webView_ loadHTMLString:contentHtml baseURL:nil];
}
[webView_ loadHTMLString:contentHtml baseURL:nil];
}
}
- (void)showWebView {
webView_.hidden = NO;
webView_.hidden = NO;
self.textLabel.text = @"";
[self setNeedsDisplay];
[self setNeedsDisplay];
}
- (void)removeWebView {
if(webView_) {
webView_.delegate = nil;
[webView_ resignFirstResponder];
[webView_ removeFromSuperview];
[webView_ release];
}
webView_ = nil;
[self setNeedsDisplay];
if(webView_) {
webView_.delegate = nil;
[webView_ resignFirstResponder];
[webView_ removeFromSuperview];
[webView_ release];
}
webView_ = nil;
[self setNeedsDisplay];
}
@ -163,15 +163,15 @@ body { font: 13px 'Helvetica Neue', Helvetica; word-wrap:break-word; padding:8px
#pragma mark UIWebView
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
if(navigationType == UIWebViewNavigationTypeOther)
return YES;
if(navigationType == UIWebViewNavigationTypeOther)
return YES;
return NO;
}
- (void)webViewDidFinishLoad:(UIWebView *)webView {
if(webViewContent_)
if(webViewContent_)
[self showWebView];
CGRect frame = webView_.frame;

View File

@ -26,6 +26,11 @@
#import "UIImage+HockeyAdditions.h"
#import "BWGlobal.h"
#ifdef HOCKEYLIB_STATIC_LIBRARY
#import "CNSFixCategoryBug.h"
CNS_FIX_CATEGORY_BUG(UIImage_HockeyAdditionsPrivate)
#endif
// Private helper methods
@interface UIImage (HockeyAdditionsPrivate)
- (void)addRoundedRectToPath:(CGRect)rect context:(CGContextRef)context ovalWidth:(CGFloat)ovalWidth ovalHeight:(CGFloat)ovalHeight;
@ -82,9 +87,9 @@ CGImageRef CreateGradientImage(int pixelsWide, int pixelsHigh, float fromAlpha,
- (UIImage *)bw_roundedCornerImage:(NSInteger)cornerSize borderSize:(NSInteger)borderSize {
// If the image does not have an alpha layer, add one
UIImage *roundedImage = nil;
UIImage *roundedImage = nil;
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 40000
BW_IF_IOS4_OR_GREATER(
BW_IF_IOS4_OR_GREATER(
UIGraphicsBeginImageContextWithOptions(self.size, NO, 0.0); // 0.0 for scale means "correct scale for device's main screen".
CGImageRef sourceImg = CGImageCreateWithImageInRect([self CGImage], CGRectMake(0, 0, self.size.width * self.scale, self.size.height * self.scale)); // cropping happens here.
@ -219,20 +224,21 @@ CGImageRef CreateGradientImage(int pixelsWide, int pixelsHigh, float fromAlpha,
image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
)
if (!image) {
// Try older method.
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(NULL, scaledWidth, scaledHeight, 8, (fitSize.width * 4),
colorSpace, kCGImageAlphaPremultipliedLast);
CGImageRef sourceImg = CGImageCreateWithImageInRect([self CGImage], sourceRect);
CGContextDrawImage(context, destRect, sourceImg);
CGImageRelease(sourceImg);
CGImageRef finalImage = CGBitmapContextCreateImage(context);
CGContextRelease(context);
CGColorSpaceRelease(colorSpace);
image = [UIImage imageWithCGImage:finalImage];
CGImageRelease(finalImage);
}
// Try older method.
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(NULL, scaledWidth, scaledHeight, 8, (fitSize.width * 4),
colorSpace, kCGImageAlphaPremultipliedLast);
CGImageRef sourceImg = CGImageCreateWithImageInRect([self CGImage], sourceRect);
CGContextDrawImage(context, destRect, sourceImg);
CGImageRelease(sourceImg);
CGImageRef finalImage = CGBitmapContextCreateImage(context);
CGContextRelease(context);
CGColorSpaceRelease(colorSpace);
image = [UIImage imageWithCGImage:finalImage];
CGImageRelease(finalImage);
}
return image;
}
@ -240,37 +246,37 @@ CGImageRef CreateGradientImage(int pixelsWide, int pixelsHigh, float fromAlpha,
CGImageRef CreateGradientImage(int pixelsWide, int pixelsHigh, float fromAlpha, float toAlpha) {
CGImageRef theCGImage = NULL;
CGImageRef theCGImage = NULL;
// gradient is always black-white and the mask must be in the gray colorspace
// gradient is always black-white and the mask must be in the gray colorspace
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();
// create the bitmap context
CGContextRef gradientBitmapContext = CGBitmapContextCreate(NULL, pixelsWide, pixelsHigh,
8, 0, colorSpace, kCGImageAlphaNone);
// create the bitmap context
CGContextRef gradientBitmapContext = CGBitmapContextCreate(NULL, pixelsWide, pixelsHigh,
8, 0, colorSpace, kCGImageAlphaNone);
// define the start and end grayscale values (with the alpha, even though
// our bitmap context doesn't support alpha the gradient requires it)
CGFloat colors[] = {toAlpha, 1.0, fromAlpha, 1.0};
// define the start and end grayscale values (with the alpha, even though
// our bitmap context doesn't support alpha the gradient requires it)
CGFloat colors[] = {toAlpha, 1.0, fromAlpha, 1.0};
// create the CGGradient and then release the gray color space
CGGradientRef grayScaleGradient = CGGradientCreateWithColorComponents(colorSpace, colors, NULL, 2);
CGColorSpaceRelease(colorSpace);
// create the CGGradient and then release the gray color space
CGGradientRef grayScaleGradient = CGGradientCreateWithColorComponents(colorSpace, colors, NULL, 2);
CGColorSpaceRelease(colorSpace);
// create the start and end points for the gradient vector (straight down)
CGPoint gradientEndPoint = CGPointZero;
CGPoint gradientStartPoint = CGPointMake(0, pixelsHigh);
// create the start and end points for the gradient vector (straight down)
CGPoint gradientEndPoint = CGPointZero;
CGPoint gradientStartPoint = CGPointMake(0, pixelsHigh);
// draw the gradient into the gray bitmap context
CGContextDrawLinearGradient(gradientBitmapContext, grayScaleGradient, gradientStartPoint,
// draw the gradient into the gray bitmap context
CGContextDrawLinearGradient(gradientBitmapContext, grayScaleGradient, gradientStartPoint,
gradientEndPoint, kCGGradientDrawsAfterEndLocation);
CGGradientRelease(grayScaleGradient);
CGGradientRelease(grayScaleGradient);
// convert the context into a CGImageRef and release the context
theCGImage = CGBitmapContextCreateImage(gradientBitmapContext);
CGContextRelease(gradientBitmapContext);
// convert the context into a CGImageRef and release the context
theCGImage = CGBitmapContextCreateImage(gradientBitmapContext);
CGContextRelease(gradientBitmapContext);
// return the imageref containing the gradient
// return the imageref containing the gradient
return theCGImage;
}
@ -288,29 +294,29 @@ CGContextRef MyOpenBitmapContext(int pixelsWide, int pixelsHigh) {
- (UIImage *)bw_reflectedImageWithHeight:(NSUInteger)height fromAlpha:(float)fromAlpha toAlpha:(float)toAlpha {
if(height == 0)
return nil;
return nil;
// create a bitmap graphics context the size of the image
CGContextRef mainViewContentContext = MyOpenBitmapContext(self.size.width, height);
// create a bitmap graphics context the size of the image
CGContextRef mainViewContentContext = MyOpenBitmapContext(self.size.width, height);
// create a 2 bit CGImage containing a gradient that will be used for masking the
// main view content to create the 'fade' of the reflection. The CGImageCreateWithMask
// function will stretch the bitmap image as required, so we can create a 1 pixel wide gradient
CGImageRef gradientMaskImage = CreateGradientImage(1, height, fromAlpha, toAlpha);
// create a 2 bit CGImage containing a gradient that will be used for masking the
// main view content to create the 'fade' of the reflection. The CGImageCreateWithMask
// function will stretch the bitmap image as required, so we can create a 1 pixel wide gradient
CGImageRef gradientMaskImage = CreateGradientImage(1, height, fromAlpha, toAlpha);
// create an image by masking the bitmap of the mainView content with the gradient view
// then release the pre-masked content bitmap and the gradient bitmap
CGContextClipToMask(mainViewContentContext, CGRectMake(0.0, 0.0, self.size.width, height), gradientMaskImage);
CGImageRelease(gradientMaskImage);
// create an image by masking the bitmap of the mainView content with the gradient view
// then release the pre-masked content bitmap and the gradient bitmap
CGContextClipToMask(mainViewContentContext, CGRectMake(0.0, 0.0, self.size.width, height), gradientMaskImage);
CGImageRelease(gradientMaskImage);
// draw the image into the bitmap context
CGContextDrawImage(mainViewContentContext, CGRectMake(0, 0, self.size.width, self.size.height), self.CGImage);
// draw the image into the bitmap context
CGContextDrawImage(mainViewContentContext, CGRectMake(0, 0, self.size.width, self.size.height), self.CGImage);
// convert the finished reflection image to a UIImage
UIImage *theImage = UIGraphicsGetImageFromCurrentImageContext(); // returns autoreleased
// convert the finished reflection image to a UIImage
UIImage *theImage = UIGraphicsGetImageFromCurrentImageContext(); // returns autoreleased
UIGraphicsEndImageContext();
return theImage;
return theImage;
}
- (id)bw_initWithContentsOfResolutionIndependentFile:(NSString *)path {
@ -337,10 +343,10 @@ CGContextRef MyOpenBitmapContext(int pixelsWide, int pixelsHigh) {
+ (UIImage *)bw_imageNamed:(NSString *)imageName bundle:(NSString *)bundleName {
NSString *resourcePath = [[NSBundle mainBundle] resourcePath];
NSString *bundlePath = [resourcePath stringByAppendingPathComponent:bundleName];
NSString *imagePath = [bundlePath stringByAppendingPathComponent:imageName];
return [UIImage bw_imageWithContentsOfResolutionIndependentFile:imagePath];
NSString *resourcePath = [[NSBundle mainBundle] resourcePath];
NSString *bundlePath = [resourcePath stringByAppendingPathComponent:bundleName];
NSString *imagePath = [bundlePath stringByAppendingPathComponent:imageName];
return [UIImage bw_imageWithContentsOfResolutionIndependentFile:imagePath];
}
@end

View File

@ -70,7 +70,7 @@ Drag & drop the HockeySDK folder from your project directory to your Xcode proje
1. Open your AppDelegate.m file.
2. Add the following line at the top of the file below your own #import statements:<pre><code>#import "BWHockeyManager.h"</code></pre>
2. Add the following line at the top of the file below your own #import statements:<pre><code>#import "CNSHockeyManager.h"</code></pre>
3. Search for the method application:didFinishLaunchingWithOptions:

View File

@ -0,0 +1,372 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
1E322DAD148FCE2100077977 /* CNSFixCategoryBug.h in Headers */ = {isa = PBXBuildFile; fileRef = 1E322DAC148FCE2100077977 /* CNSFixCategoryBug.h */; };
E400561E148D79B500EB22B9 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E400561D148D79B500EB22B9 /* Foundation.framework */; };
E41EB471148D7BF50015DEDC /* BWApp.h in Headers */ = {isa = PBXBuildFile; fileRef = E41EB459148D7BF50015DEDC /* BWApp.h */; };
E41EB472148D7BF50015DEDC /* BWApp.m in Sources */ = {isa = PBXBuildFile; fileRef = E41EB45A148D7BF50015DEDC /* BWApp.m */; };
E41EB473148D7BF50015DEDC /* BWGlobal.h in Headers */ = {isa = PBXBuildFile; fileRef = E41EB45B148D7BF50015DEDC /* BWGlobal.h */; };
E41EB474148D7BF50015DEDC /* BWGlobal.m in Sources */ = {isa = PBXBuildFile; fileRef = E41EB45C148D7BF50015DEDC /* BWGlobal.m */; };
E41EB475148D7BF50015DEDC /* BWHockeyManager.h in Headers */ = {isa = PBXBuildFile; fileRef = E41EB45D148D7BF50015DEDC /* BWHockeyManager.h */; };
E41EB476148D7BF50015DEDC /* BWHockeyManager.m in Sources */ = {isa = PBXBuildFile; fileRef = E41EB45E148D7BF50015DEDC /* BWHockeyManager.m */; };
E41EB477148D7BF50015DEDC /* BWHockeySettingsViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = E41EB45F148D7BF50015DEDC /* BWHockeySettingsViewController.h */; };
E41EB478148D7BF50015DEDC /* BWHockeySettingsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = E41EB460148D7BF50015DEDC /* BWHockeySettingsViewController.m */; };
E41EB479148D7BF50015DEDC /* BWHockeyViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = E41EB461148D7BF50015DEDC /* BWHockeyViewController.h */; };
E41EB47A148D7BF50015DEDC /* BWHockeyViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = E41EB462148D7BF50015DEDC /* BWHockeyViewController.m */; };
E41EB47B148D7BF50015DEDC /* BWQuincyManager.h in Headers */ = {isa = PBXBuildFile; fileRef = E41EB463148D7BF50015DEDC /* BWQuincyManager.h */; };
E41EB47C148D7BF50015DEDC /* BWQuincyManager.m in Sources */ = {isa = PBXBuildFile; fileRef = E41EB464148D7BF50015DEDC /* BWQuincyManager.m */; };
E41EB47D148D7BF50015DEDC /* CNSHockeyManager.h in Headers */ = {isa = PBXBuildFile; fileRef = E41EB465148D7BF50015DEDC /* CNSHockeyManager.h */; };
E41EB47E148D7BF50015DEDC /* CNSHockeyManager.m in Sources */ = {isa = PBXBuildFile; fileRef = E41EB466148D7BF50015DEDC /* CNSHockeyManager.m */; };
E41EB47F148D7BF50015DEDC /* NSString+HockeyAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = E41EB467148D7BF50015DEDC /* NSString+HockeyAdditions.h */; };
E41EB480148D7BF50015DEDC /* NSString+HockeyAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = E41EB468148D7BF50015DEDC /* NSString+HockeyAdditions.m */; };
E41EB481148D7BF50015DEDC /* PSAppStoreHeader.h in Headers */ = {isa = PBXBuildFile; fileRef = E41EB469148D7BF50015DEDC /* PSAppStoreHeader.h */; };
E41EB482148D7BF50015DEDC /* PSAppStoreHeader.m in Sources */ = {isa = PBXBuildFile; fileRef = E41EB46A148D7BF50015DEDC /* PSAppStoreHeader.m */; };
E41EB483148D7BF50015DEDC /* PSStoreButton.h in Headers */ = {isa = PBXBuildFile; fileRef = E41EB46B148D7BF50015DEDC /* PSStoreButton.h */; };
E41EB484148D7BF50015DEDC /* PSStoreButton.m in Sources */ = {isa = PBXBuildFile; fileRef = E41EB46C148D7BF50015DEDC /* PSStoreButton.m */; };
E41EB485148D7BF50015DEDC /* PSWebTableViewCell.h in Headers */ = {isa = PBXBuildFile; fileRef = E41EB46D148D7BF50015DEDC /* PSWebTableViewCell.h */; };
E41EB486148D7BF50015DEDC /* PSWebTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = E41EB46E148D7BF50015DEDC /* PSWebTableViewCell.m */; };
E41EB487148D7BF50015DEDC /* UIImage+HockeyAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = E41EB46F148D7BF50015DEDC /* UIImage+HockeyAdditions.h */; };
E41EB488148D7BF50015DEDC /* UIImage+HockeyAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = E41EB470148D7BF50015DEDC /* UIImage+HockeyAdditions.m */; };
E41EB48C148D7C4E0015DEDC /* CrashReporter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E41EB48B148D7C4E0015DEDC /* CrashReporter.framework */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
1E322DAC148FCE2100077977 /* CNSFixCategoryBug.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CNSFixCategoryBug.h; sourceTree = "<group>"; };
E400561A148D79B500EB22B9 /* libHockeySDK.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libHockeySDK.a; sourceTree = BUILT_PRODUCTS_DIR; };
E400561D148D79B500EB22B9 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
E400562B148D79B500EB22B9 /* SenTestingKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SenTestingKit.framework; path = Library/Frameworks/SenTestingKit.framework; sourceTree = DEVELOPER_DIR; };
E400562D148D79B500EB22B9 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; };
E4005649148D7A3000EB22B9 /* Hockey.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = Hockey.bundle; sourceTree = "<group>"; };
E400564A148D7A3000EB22B9 /* Quincy.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = Quincy.bundle; sourceTree = "<group>"; };
E41EB459148D7BF50015DEDC /* BWApp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BWApp.h; sourceTree = "<group>"; };
E41EB45A148D7BF50015DEDC /* BWApp.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BWApp.m; sourceTree = "<group>"; };
E41EB45B148D7BF50015DEDC /* BWGlobal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BWGlobal.h; sourceTree = "<group>"; };
E41EB45C148D7BF50015DEDC /* BWGlobal.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BWGlobal.m; sourceTree = "<group>"; };
E41EB45D148D7BF50015DEDC /* BWHockeyManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BWHockeyManager.h; sourceTree = "<group>"; };
E41EB45E148D7BF50015DEDC /* BWHockeyManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BWHockeyManager.m; sourceTree = "<group>"; };
E41EB45F148D7BF50015DEDC /* BWHockeySettingsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BWHockeySettingsViewController.h; sourceTree = "<group>"; };
E41EB460148D7BF50015DEDC /* BWHockeySettingsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BWHockeySettingsViewController.m; sourceTree = "<group>"; };
E41EB461148D7BF50015DEDC /* BWHockeyViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BWHockeyViewController.h; sourceTree = "<group>"; };
E41EB462148D7BF50015DEDC /* BWHockeyViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BWHockeyViewController.m; sourceTree = "<group>"; };
E41EB463148D7BF50015DEDC /* BWQuincyManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BWQuincyManager.h; sourceTree = "<group>"; };
E41EB464148D7BF50015DEDC /* BWQuincyManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BWQuincyManager.m; sourceTree = "<group>"; };
E41EB465148D7BF50015DEDC /* CNSHockeyManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CNSHockeyManager.h; sourceTree = "<group>"; };
E41EB466148D7BF50015DEDC /* CNSHockeyManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CNSHockeyManager.m; sourceTree = "<group>"; };
E41EB467148D7BF50015DEDC /* NSString+HockeyAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+HockeyAdditions.h"; sourceTree = "<group>"; };
E41EB468148D7BF50015DEDC /* NSString+HockeyAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+HockeyAdditions.m"; sourceTree = "<group>"; };
E41EB469148D7BF50015DEDC /* PSAppStoreHeader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PSAppStoreHeader.h; sourceTree = "<group>"; };
E41EB46A148D7BF50015DEDC /* PSAppStoreHeader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PSAppStoreHeader.m; sourceTree = "<group>"; };
E41EB46B148D7BF50015DEDC /* PSStoreButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PSStoreButton.h; sourceTree = "<group>"; };
E41EB46C148D7BF50015DEDC /* PSStoreButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PSStoreButton.m; sourceTree = "<group>"; };
E41EB46D148D7BF50015DEDC /* PSWebTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PSWebTableViewCell.h; sourceTree = "<group>"; };
E41EB46E148D7BF50015DEDC /* PSWebTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PSWebTableViewCell.m; sourceTree = "<group>"; };
E41EB46F148D7BF50015DEDC /* UIImage+HockeyAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImage+HockeyAdditions.h"; sourceTree = "<group>"; };
E41EB470148D7BF50015DEDC /* UIImage+HockeyAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImage+HockeyAdditions.m"; sourceTree = "<group>"; };
E41EB48B148D7C4E0015DEDC /* CrashReporter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CrashReporter.framework; path = ../Vendor/CrashReporter.framework; sourceTree = "<group>"; };
E4E7335A148D7A5A00763A39 /* LICENSE.txt */ = {isa = PBXFileReference; lastKnownFileType = text; name = LICENSE.txt; path = ../LICENSE.txt; sourceTree = "<group>"; };
E4E7335B148D7A5A00763A39 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = text; name = README.md; path = ../README.md; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
E4005617148D79B500EB22B9 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
E400561E148D79B500EB22B9 /* Foundation.framework in Frameworks */,
E41EB48C148D7C4E0015DEDC /* CrashReporter.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
E400560F148D79B500EB22B9 = {
isa = PBXGroup;
children = (
E41EB489148D7BF90015DEDC /* HockeySDK */,
E400561C148D79B500EB22B9 /* Frameworks */,
E4005648148D7A3000EB22B9 /* Resources */,
E400561B148D79B500EB22B9 /* Products */,
E4E7335A148D7A5A00763A39 /* LICENSE.txt */,
E4E7335B148D7A5A00763A39 /* README.md */,
);
sourceTree = "<group>";
};
E400561B148D79B500EB22B9 /* Products */ = {
isa = PBXGroup;
children = (
E400561A148D79B500EB22B9 /* libHockeySDK.a */,
);
name = Products;
sourceTree = "<group>";
};
E400561C148D79B500EB22B9 /* Frameworks */ = {
isa = PBXGroup;
children = (
E41EB48B148D7C4E0015DEDC /* CrashReporter.framework */,
E400561D148D79B500EB22B9 /* Foundation.framework */,
E400562B148D79B500EB22B9 /* SenTestingKit.framework */,
E400562D148D79B500EB22B9 /* UIKit.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
E4005648148D7A3000EB22B9 /* Resources */ = {
isa = PBXGroup;
children = (
E4005649148D7A3000EB22B9 /* Hockey.bundle */,
E400564A148D7A3000EB22B9 /* Quincy.bundle */,
);
name = Resources;
path = ../Resources;
sourceTree = "<group>";
};
E41EB458148D7BF50015DEDC /* Classes */ = {
isa = PBXGroup;
children = (
E41EB48A148D7C150015DEDC /* Helper */,
E41EB459148D7BF50015DEDC /* BWApp.h */,
E41EB45A148D7BF50015DEDC /* BWApp.m */,
E41EB45B148D7BF50015DEDC /* BWGlobal.h */,
E41EB45C148D7BF50015DEDC /* BWGlobal.m */,
E41EB45D148D7BF50015DEDC /* BWHockeyManager.h */,
E41EB45E148D7BF50015DEDC /* BWHockeyManager.m */,
E41EB45F148D7BF50015DEDC /* BWHockeySettingsViewController.h */,
E41EB460148D7BF50015DEDC /* BWHockeySettingsViewController.m */,
E41EB461148D7BF50015DEDC /* BWHockeyViewController.h */,
E41EB462148D7BF50015DEDC /* BWHockeyViewController.m */,
E41EB463148D7BF50015DEDC /* BWQuincyManager.h */,
E41EB464148D7BF50015DEDC /* BWQuincyManager.m */,
E41EB465148D7BF50015DEDC /* CNSHockeyManager.h */,
E41EB466148D7BF50015DEDC /* CNSHockeyManager.m */,
);
name = Classes;
path = ../Classes;
sourceTree = "<group>";
};
E41EB489148D7BF90015DEDC /* HockeySDK */ = {
isa = PBXGroup;
children = (
E41EB458148D7BF50015DEDC /* Classes */,
);
name = HockeySDK;
sourceTree = "<group>";
};
E41EB48A148D7C150015DEDC /* Helper */ = {
isa = PBXGroup;
children = (
E41EB467148D7BF50015DEDC /* NSString+HockeyAdditions.h */,
E41EB468148D7BF50015DEDC /* NSString+HockeyAdditions.m */,
E41EB469148D7BF50015DEDC /* PSAppStoreHeader.h */,
E41EB46A148D7BF50015DEDC /* PSAppStoreHeader.m */,
E41EB46B148D7BF50015DEDC /* PSStoreButton.h */,
E41EB46C148D7BF50015DEDC /* PSStoreButton.m */,
E41EB46D148D7BF50015DEDC /* PSWebTableViewCell.h */,
E41EB46E148D7BF50015DEDC /* PSWebTableViewCell.m */,
E41EB46F148D7BF50015DEDC /* UIImage+HockeyAdditions.h */,
E41EB470148D7BF50015DEDC /* UIImage+HockeyAdditions.m */,
1E322DAC148FCE2100077977 /* CNSFixCategoryBug.h */,
);
name = Helper;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
E4005618148D79B500EB22B9 /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
E41EB471148D7BF50015DEDC /* BWApp.h in Headers */,
E41EB473148D7BF50015DEDC /* BWGlobal.h in Headers */,
E41EB475148D7BF50015DEDC /* BWHockeyManager.h in Headers */,
E41EB477148D7BF50015DEDC /* BWHockeySettingsViewController.h in Headers */,
E41EB479148D7BF50015DEDC /* BWHockeyViewController.h in Headers */,
E41EB47B148D7BF50015DEDC /* BWQuincyManager.h in Headers */,
E41EB47D148D7BF50015DEDC /* CNSHockeyManager.h in Headers */,
E41EB47F148D7BF50015DEDC /* NSString+HockeyAdditions.h in Headers */,
E41EB481148D7BF50015DEDC /* PSAppStoreHeader.h in Headers */,
E41EB483148D7BF50015DEDC /* PSStoreButton.h in Headers */,
E41EB485148D7BF50015DEDC /* PSWebTableViewCell.h in Headers */,
E41EB487148D7BF50015DEDC /* UIImage+HockeyAdditions.h in Headers */,
1E322DAD148FCE2100077977 /* CNSFixCategoryBug.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXHeadersBuildPhase section */
/* Begin PBXNativeTarget section */
E4005619148D79B500EB22B9 /* HockeySDK */ = {
isa = PBXNativeTarget;
buildConfigurationList = E400563E148D79B500EB22B9 /* Build configuration list for PBXNativeTarget "HockeySDK" */;
buildPhases = (
E4005616148D79B500EB22B9 /* Sources */,
E4005617148D79B500EB22B9 /* Frameworks */,
E4005618148D79B500EB22B9 /* Headers */,
);
buildRules = (
);
dependencies = (
);
name = HockeySDK;
productName = HockeySDK;
productReference = E400561A148D79B500EB22B9 /* libHockeySDK.a */;
productType = "com.apple.product-type.library.static";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
E4005611148D79B500EB22B9 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0420;
};
buildConfigurationList = E4005614148D79B500EB22B9 /* Build configuration list for PBXProject "HockeySDK" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
);
mainGroup = E400560F148D79B500EB22B9;
productRefGroup = E400561B148D79B500EB22B9 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
E4005619148D79B500EB22B9 /* HockeySDK */,
);
};
/* End PBXProject section */
/* Begin PBXSourcesBuildPhase section */
E4005616148D79B500EB22B9 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
E41EB472148D7BF50015DEDC /* BWApp.m in Sources */,
E41EB474148D7BF50015DEDC /* BWGlobal.m in Sources */,
E41EB476148D7BF50015DEDC /* BWHockeyManager.m in Sources */,
E41EB478148D7BF50015DEDC /* BWHockeySettingsViewController.m in Sources */,
E41EB47A148D7BF50015DEDC /* BWHockeyViewController.m in Sources */,
E41EB47C148D7BF50015DEDC /* BWQuincyManager.m in Sources */,
E41EB47E148D7BF50015DEDC /* CNSHockeyManager.m in Sources */,
E41EB480148D7BF50015DEDC /* NSString+HockeyAdditions.m in Sources */,
E41EB482148D7BF50015DEDC /* PSAppStoreHeader.m in Sources */,
E41EB484148D7BF50015DEDC /* PSStoreButton.m in Sources */,
E41EB486148D7BF50015DEDC /* PSWebTableViewCell.m in Sources */,
E41EB488148D7BF50015DEDC /* UIImage+HockeyAdditions.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
E400563C148D79B500EB22B9 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ARCHS = (
armv7,
armv6,
);
COPY_PHASE_STRIP = NO;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
HOCKEYLIB_STATIC_LIBRARY,
"DEBUG=1",
"$(inherited)",
);
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
GCC_VERSION = "";
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 3.0;
OTHER_CFLAGS = "";
SDKROOT = iphoneos;
};
name = Debug;
};
E400563D148D79B500EB22B9 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ARCHS = (
armv7,
armv6,
);
COPY_PHASE_STRIP = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_PREPROCESSOR_DEFINITIONS = HOCKEYLIB_STATIC_LIBRARY;
GCC_VERSION = "";
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 3.0;
OTHER_CFLAGS = "";
SDKROOT = iphoneos;
VALIDATE_PRODUCT = YES;
};
name = Release;
};
E400563F148D79B500EB22B9 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
DSTROOT = /tmp/HockeySDK.dst;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"\"$(SRCROOT)/../Vendor\"",
);
OTHER_LDFLAGS = "";
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
};
name = Debug;
};
E4005640148D79B500EB22B9 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
DSTROOT = /tmp/HockeySDK.dst;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"\"$(SRCROOT)/../Vendor\"",
);
OTHER_LDFLAGS = "";
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
E4005614148D79B500EB22B9 /* Build configuration list for PBXProject "HockeySDK" */ = {
isa = XCConfigurationList;
buildConfigurations = (
E400563C148D79B500EB22B9 /* Debug */,
E400563D148D79B500EB22B9 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
E400563E148D79B500EB22B9 /* Build configuration list for PBXNativeTarget "HockeySDK" */ = {
isa = XCConfigurationList;
buildConfigurations = (
E400563F148D79B500EB22B9 /* Debug */,
E4005640148D79B500EB22B9 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = E4005611148D79B500EB22B9 /* Project object */;
}

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:HockeySDK.xcodeproj">
</FileRef>
</Workspace>