Merged changes from HockeyKit repo.

This commit is contained in:
Thomas Dohmke 2011-12-03 15:24:04 +01:00
parent 3ce0f19bf2
commit 0e905a011b
7 changed files with 138 additions and 52 deletions

View File

@ -151,7 +151,7 @@
}
- (NSString *)sizeInMB {
if ([[size_ class] isKindOfClass: [NSNumber class]] && [size_ doubleValue] > 0) {
if ([size_ isKindOfClass: [NSNumber class]] && [size_ doubleValue] > 0) {
double appSizeInMB = [size_ doubleValue]/(1024*1024);
NSString *appSizeString = [NSString stringWithFormat:@"%.1f MB", appSizeInMB];
return appSizeString;

View File

@ -57,6 +57,8 @@ NSString *BWmd5(NSString *str);
// compatibility helper
#define BW_NATIVE_JSON_AVAILABLE __IPHONE_OS_VERSION_MIN_REQUIRED >= 50000
#ifndef kCFCoreFoundationVersionNumber_iPhoneOS_3_2
#define kCFCoreFoundationVersionNumber_iPhoneOS_3_2 478.61
#endif

View File

@ -70,6 +70,8 @@ typedef enum {
BOOL updateAlertShowing_;
BOOL lastCheckFailed_;
BOOL isAppStoreEnvironment_;
NSURLConnection *urlConnection_;
NSDate *lastCheck_;
NSDate *usageStartTimestamp_;
@ -171,6 +173,8 @@ typedef enum {
///////////////////////////////////////////////////////////////////////////////////////////////////
@property (nonatomic, readonly) BOOL isAppStoreEnvironment;
// is an update available?
- (BOOL)isUpdateAvailable;

View File

@ -49,7 +49,6 @@
- (void)startUsage;
- (void)stopUsage;
- (void)startManager;
- (void)wentOnline;
- (void)showAuthorizationScreen:(NSString *)message image:(NSString *)image;
- (BOOL)canSendUserData;
- (BOOL)canSendUsageTime;
@ -110,6 +109,7 @@ static NSString *kHockeyErrorDomain = @"HockeyErrorDomain";
@synthesize requireAuthorization = requireAuthorization_;
@synthesize authenticationSecret = authenticationSecret_;
@synthesize authorizeView = authorizeView_;
@synthesize isAppStoreEnvironment = isAppStoreEnvironment_;
///////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark -
@ -271,7 +271,7 @@ static NSString *kHockeyErrorDomain = @"HockeyErrorDomain";
- (void)checkUpdateAvailable_ {
// check if there is an update available
if (self.compareVersionType == HockeyComparisonResultGreater) {
self.updateAvailable = ([self.app.version compare:self.currentAppVersion options:NSNumericSearch] == NSOrderedDescending);
self.updateAvailable = ([self.app.version versionCompare:self.currentAppVersion] == NSOrderedDescending);
} else {
self.updateAvailable = ([self.app.version compare:self.currentAppVersion] != NSOrderedSame);
}
@ -362,6 +362,17 @@ static NSString *kHockeyErrorDomain = @"HockeyErrorDomain";
authenticationSecret_= nil;
loggingEnabled_ = NO;
// check if we are really not in an app store environment
if ([[NSBundle mainBundle] pathForResource:@"embedded" ofType:@"mobileprovision"]) {
isAppStoreEnvironment_ = NO;
} else {
isAppStoreEnvironment_ = YES;
}
#if TARGET_IPHONE_SIMULATOR
isAppStoreEnvironment_ = NO;
#endif
// set defaults
self.showDirectInstallOption = NO;
self.requireAuthorization = NO;
@ -392,6 +403,8 @@ static NSString *kHockeyErrorDomain = @"HockeyErrorDomain";
self.userAllowsSendUsageTime = YES;
}
if (!isAppStoreEnvironment_) {
[self loadAppCache_];
[self startUsage];
@ -406,10 +419,12 @@ static NSString *kHockeyErrorDomain = @"HockeyErrorDomain";
name:UIApplicationWillTerminateNotification
object:nil];
}
}
return self;
}
- (void)dealloc {
if (!isAppStoreEnvironment_) {
[[NSNotificationCenter defaultCenter] removeObserver:self name:BWHockeyNetworkBecomeReachable object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationWillTerminateNotification object:nil];
@ -417,6 +432,7 @@ static NSString *kHockeyErrorDomain = @"HockeyErrorDomain";
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidBecomeActiveNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationWillResignActiveNotification object:nil];
)
}
self.delegate = nil;
[urlConnection_ cancel];
@ -444,6 +460,11 @@ static NSString *kHockeyErrorDomain = @"HockeyErrorDomain";
}
- (void)showUpdateView {
if (isAppStoreEnvironment_) {
BWHockeyLog(@"this should not be called from an app store build.");
return;
}
if (currentHockeyViewController_) {
BWHockeyLog(@"update view already visible, aborting");
return;
@ -593,10 +614,27 @@ static NSString *kHockeyErrorDomain = @"HockeyErrorDomain";
NSError *error = nil;
id feedResult = nil;
#if BW_NATIVE_JSON_AVAILABLE
feedResult = [NSJSONSerialization JSONObjectWithData:[jsonString dataUsingEncoding:NSUTF8StringEncoding] options:kNilOptions error:&error];
#else
id nsjsonClass = NSClassFromString(@"NSJSONSerialization");
SEL nsjsonSelect = NSSelectorFromString(@"JSONObjectWithData:options:error:");
SEL sbJSONSelector = NSSelectorFromString(@"JSONValue");
SEL jsonKitSelector = NSSelectorFromString(@"objectFromJSONStringWithParseOptions:error:");
SEL yajlSelector = NSSelectorFromString(@"yajl_JSONWithOptions:error:");
if (jsonKitSelector && [jsonString respondsToSelector:jsonKitSelector]) {
if (nsjsonClass && [nsjsonClass respondsToSelector:nsjsonSelect]) {
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[nsjsonClass methodSignatureForSelector:nsjsonSelect]];
invocation.target = nsjsonClass;
invocation.selector = nsjsonSelect;
NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
[invocation setArgument:&jsonData atIndex:2]; // arguments 0 and 1 are self and _cmd respectively, automatically set by NSInvocation
NSUInteger readOptions = kNilOptions;
[invocation setArgument:&readOptions atIndex:3];
[invocation setArgument:&error atIndex:4];
[invocation invoke];
[invocation getReturnValue:&feedResult];
} else if (jsonKitSelector && [jsonString respondsToSelector:jsonKitSelector]) {
// first try JSONkit
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[jsonString methodSignatureForSelector:jsonKitSelector]];
invocation.target = jsonString;
@ -611,12 +649,25 @@ static NSString *kHockeyErrorDomain = @"HockeyErrorDomain";
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[jsonString methodSignatureForSelector:sbJSONSelector]];
invocation.target = jsonString;
invocation.selector = sbJSONSelector;
[invocation invoke];
[invocation getReturnValue:&feedResult];
} else if (yajlSelector && [jsonString respondsToSelector:yajlSelector]) {
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[jsonString methodSignatureForSelector:yajlSelector]];
invocation.target = jsonString;
invocation.selector = yajlSelector;
NSUInteger yajlParserOptions = 0;
[invocation setArgument:&yajlParserOptions atIndex:2]; // arguments 0 and 1 are self and _cmd respectively, automatically set by NSInvocation
[invocation setArgument:&error atIndex:3];
[invocation invoke];
[invocation getReturnValue:&feedResult];
} else {
BWHockeyLog(@"Error: You need a JSON Framework in your runtime!");
[self doesNotRecognizeSelector:_cmd];
}
#endif
if (error) {
BWHockeyLog(@"Error while parsing response feed: %@", [error localizedDescription]);
[self reportError_:error];
@ -631,6 +682,7 @@ static NSString *kHockeyErrorDomain = @"HockeyErrorDomain";
#pragma mark RequestComments
- (BOOL)shouldCheckForUpdates {
if (isAppStoreEnvironment_) return NO;
BOOL checkForUpdate = NO;
switch (self.updateSetting) {
case HockeyUpdateCheckStartup:
@ -720,6 +772,7 @@ static NSString *kHockeyErrorDomain = @"HockeyErrorDomain";
}
- (void)checkForUpdate {
if (isAppStoreEnvironment_) return;
if (self.requireAuthorization) return;
if (self.isUpdateAvailable && [self.app.mandatory boolValue]) {
[self showCheckForUpdateAlert_];
@ -729,6 +782,7 @@ static NSString *kHockeyErrorDomain = @"HockeyErrorDomain";
}
- (void)checkForUpdateShowFeedback:(BOOL)feedback {
if (isAppStoreEnvironment_) return;
if (self.isCheckInProgress) return;
showFeedback_ = feedback;
@ -845,6 +899,8 @@ static NSString *kHockeyErrorDomain = @"HockeyErrorDomain";
// begin the startup process
- (void)startManager {
if (isAppStoreEnvironment_) return;
if (![self appVersionIsAuthorized]) {
if ([self authorizationState] == HockeyAuthorizationPending) {
[self showAuthorizationScreen:BWHockeyLocalize(@"HockeyAuthorizationProgress") image:@"authorize_request.png"];
@ -859,19 +915,6 @@ static NSString *kHockeyErrorDomain = @"HockeyErrorDomain";
}
- (void)wentOnline {
if (![self appVersionIsAuthorized]) {
if ([self authorizationState] == HockeyAuthorizationPending) {
[self checkForAuthorization];
}
} else {
if (lastCheckFailed_) {
[self checkForUpdate];
}
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark -
#pragma mark NSURLRequest
@ -1011,6 +1054,7 @@ static NSString *kHockeyErrorDomain = @"HockeyErrorDomain";
}
BW_IF_IOS4_OR_GREATER(
if (!isAppStoreEnvironment_) {
// register/deregister logic
NSNotificationCenter *dnc = [NSNotificationCenter defaultCenter];
if (!updateURL_ && anUpdateURL) {
@ -1020,6 +1064,7 @@ static NSString *kHockeyErrorDomain = @"HockeyErrorDomain";
[dnc removeObserver:self name:UIApplicationDidBecomeActiveNotification object:nil];
[dnc removeObserver:self name:UIApplicationWillResignActiveNotification object:nil];
}
}
)
if (updateURL_ != anUpdateURL) {
@ -1027,7 +1072,9 @@ static NSString *kHockeyErrorDomain = @"HockeyErrorDomain";
updateURL_ = [anUpdateURL copy];
}
if (!isAppStoreEnvironment_) {
[self performSelector:@selector(startManager) withObject:nil afterDelay:0.0f];
}
}
- (void)setAppIdentifier:(NSString *)anAppIdentifier {
@ -1043,12 +1090,14 @@ static NSString *kHockeyErrorDomain = @"HockeyErrorDomain";
if (checkForUpdateOnLaunch_ != flag) {
checkForUpdateOnLaunch_ = flag;
BW_IF_IOS4_OR_GREATER(
if (!isAppStoreEnvironment_) {
NSNotificationCenter *dnc = [NSNotificationCenter defaultCenter];
if (flag) {
[dnc addObserver:self selector:@selector(checkForUpdate) name:UIApplicationDidBecomeActiveNotification object:nil];
} else {
[dnc removeObserver:self name:UIApplicationDidBecomeActiveNotification object:nil];
}
}
)
}
}

View File

@ -55,7 +55,9 @@
#pragma mark private
- (void)restoreStoreButtonStateAnimated_:(BOOL)animated {
if ([self.hockeyManager isUpdateAvailable]) {
if ([self.hockeyManager isAppStoreEnvironment]) {
[self setAppStoreButtonState:AppStoreButtonStateOffline animated:animated];
} else if ([self.hockeyManager isUpdateAvailable]) {
[self setAppStoreButtonState:AppStoreButtonStateUpdate animated:animated];
} else {
[self setAppStoreButtonState:AppStoreButtonStateCheck animated:animated];
@ -390,6 +392,8 @@
}
- (void)viewWillAppear:(BOOL)animated {
if ([self.hockeyManager isAppStoreEnvironment])
self.appStoreButtonState = AppStoreButtonStateOffline;
self.hockeyManager.currentHockeyViewController = self;
[super viewWillAppear:animated];
statusBarStyle_ = [[UIApplication sharedApplication] statusBarStyle];

2
Classes/NSString+HockeyAdditions.h Normal file → Executable file
View File

@ -30,4 +30,6 @@
- (NSString *)bw_URLEncodedString;
- (NSString *)bw_URLDecodedString;
- (NSComparisonResult)versionCompare:(NSString *)other;
@end

25
Classes/NSString+HockeyAdditions.m Normal file → Executable file
View File

@ -47,4 +47,29 @@
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];
// 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];
// If plain versions are equal, compare full versions
if (result == NSOrderedSame)
result = [self compare:other options:NSNumericSearch];
// Done
return result;
}
@end