diff --git a/Classes/BITAuthenticator.m b/Classes/BITAuthenticator.m index 4c53eab6eb..6ccc33bea4 100644 --- a/Classes/BITAuthenticator.m +++ b/Classes/BITAuthenticator.m @@ -108,19 +108,19 @@ static unsigned char kBITPNGEndChunk[4] = {0x49, 0x45, 0x4e, 0x44}; // make sure this is called after startManager so all modules are fully setup if (!_isSetup) { + [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(authenticateInstallation) object:nil]; [self performSelector:@selector(authenticateInstallation) withObject:nil afterDelay:0.1]; + } else { + switch ([[UIApplication sharedApplication] applicationState]) { + case UIApplicationStateActive: + [self authenticate]; + break; + case UIApplicationStateBackground: + case UIApplicationStateInactive: + // do nothing, wait for active state + break; + } } - - switch ([[UIApplication sharedApplication] applicationState]) { - case UIApplicationStateActive: - [self authenticate]; - break; - case UIApplicationStateBackground: - case UIApplicationStateInactive: - // do nothing, wait for active state - break; - } - [self registerObservers]; } @@ -156,6 +156,10 @@ static unsigned char kBITPNGEndChunk[4] = {0x49, 0x45, 0x4e, 0x44}; } - (void)alertOnFailureStoringTokenInKeychain { + if ([[UIApplication sharedApplication] applicationState] != UIApplicationStateActive) { + return; + } + UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:nil message:BITHockeyLocalizedString(@"HockeyAuthenticationViewControllerStorageError") delegate:self @@ -607,7 +611,6 @@ static unsigned char kBITPNGEndChunk[4] = {0x49, 0x45, 0x4e, 0x44}; case BITAuthenticatorIdentificationTypeHockeyAppEmail: case BITAuthenticatorIdentificationTypeAnonymous: case BITAuthenticatorIdentificationTypeHockeyAppUser: - NSAssert(NO, @"Should only be called for Device and WebAuth identificationType"); return NO; } diff --git a/Classes/BITCrashAttachment.h b/Classes/BITCrashAttachment.h new file mode 100644 index 0000000000..482e0c004c --- /dev/null +++ b/Classes/BITCrashAttachment.h @@ -0,0 +1,66 @@ +/* + * Author: Andreas Linde + * + * Copyright (c) 2014 HockeyApp, Bit Stadium GmbH. + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#import + +/** + * Provides support to add binary attachments to crash reports + * + * This is used by `[BITCrashManagerDelegate attachmentForCrashManager:]` + */ +@interface BITCrashAttachment : NSObject + +/** + * The filename the attachment should get + */ +@property (nonatomic, readonly, strong) NSString *filename; + +/** + * The attachment data as NSData object + */ +@property (nonatomic, readonly, strong) NSData *attachmentData; + +/** + * The content type of your data as MIME type + */ +@property (nonatomic, readonly, strong) NSString *contentType; + +/** + * Create an BITCrashAttachment instance with a given filename and NSData object + * + * @param filename The filename the attachment should get + * @param attachmentData The attachment data as NSData + * @param contentType The content type of your data as MIME type + * + * @return An instsance of BITCrashAttachment + */ +- (instancetype)initWithFilename:(NSString *)filename + attachmentData:(NSData *)attachmentData + contentType:(NSString *)contentType; + +@end diff --git a/Classes/BITCrashAttachment.m b/Classes/BITCrashAttachment.m new file mode 100644 index 0000000000..def32d2583 --- /dev/null +++ b/Classes/BITCrashAttachment.m @@ -0,0 +1,64 @@ +/* + * Author: Andreas Linde + * + * Copyright (c) 2014 HockeyApp, Bit Stadium GmbH. + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#import "BITCrashAttachment.h" + +@implementation BITCrashAttachment + +- (instancetype)initWithFilename:(NSString *)filename + attachmentData:(NSData *)attachmentData + contentType:(NSString *)contentType +{ + if (self = [super init]) { + _filename = filename; + _attachmentData = attachmentData; + _contentType = contentType; + } + + return self; +} + + +#pragma mark - NSCoder + +- (void)encodeWithCoder:(NSCoder *)encoder { + [encoder encodeObject:self.filename forKey:@"filename"]; + [encoder encodeObject:self.attachmentData forKey:@"data"]; + [encoder encodeObject:self.contentType forKey:@"contentType"]; +} + +- (id)initWithCoder:(NSCoder *)decoder { + if ((self = [super init])) { + _filename = [decoder decodeObjectForKey:@"filename"]; + _attachmentData = [decoder decodeObjectForKey:@"data"]; + _contentType = [decoder decodeObjectForKey:@"contentType"]; + } + return self; +} + +@end diff --git a/Classes/BITCrashManager.m b/Classes/BITCrashManager.m index fca13fc4bf..18b3aaf270 100644 --- a/Classes/BITCrashManager.m +++ b/Classes/BITCrashManager.m @@ -37,7 +37,9 @@ #import "HockeySDKPrivate.h" #import "BITHockeyHelper.h" +#import "BITHockeyAppClient.h" +#import "BITCrashAttachment.h" #import "BITHockeyBaseManagerPrivate.h" #import "BITCrashManagerPrivate.h" #import "BITCrashReportTextFormatter.h" @@ -52,6 +54,11 @@ #define kBITCrashMetaUserEmail @"BITCrashMetaUserEmail" #define kBITCrashMetaUserID @"BITCrashMetaUserID" #define kBITCrashMetaApplicationLog @"BITCrashMetaApplicationLog" +#define kBITCrashMetaAttachment @"BITCrashMetaAttachment" + +// internal keys +NSString *const KBITAttachmentDictIndex = @"index"; +NSString *const KBITAttachmentDictAttachment = @"attachment"; NSString *const kBITCrashManagerStatus = @"BITCrashManagerStatus"; @@ -215,6 +222,7 @@ NSString *const kBITCrashManagerStatus = @"BITCrashManagerStatus"; for (NSUInteger i=0; i < [_crashFiles count]; i++) { [_fileManager removeItemAtPath:[_crashFiles objectAtIndex:i] error:&error]; + [_fileManager removeItemAtPath:[[_crashFiles objectAtIndex:i] stringByAppendingString:@".data"] error:&error]; [_fileManager removeItemAtPath:[[_crashFiles objectAtIndex:i] stringByAppendingString:@".meta"] error:&error]; NSString *cacheFilename = [[_crashFiles objectAtIndex:i] lastPathComponent]; @@ -228,9 +236,57 @@ NSString *const kBITCrashManagerStatus = @"BITCrashManagerStatus"; [self saveSettings]; } + +- (void)persistAttachment:(BITCrashAttachment *)attachment withFilename:(NSString *)filename { + NSString *attachmentFilename = [filename stringByAppendingString:@".data"]; + NSMutableData *data = [[NSMutableData alloc] init]; + NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data]; + + [archiver encodeObject:attachment forKey:kBITCrashMetaAttachment]; + + [archiver finishEncoding]; + + [data writeToFile:attachmentFilename atomically:YES]; +} + +/** + * Read the attachment data from the stored file + * + * @param filename The crash report id + * + * @return an BITCrashAttachment instance or nil + */ +- (BITCrashAttachment *)attachmentForCrashReport:(NSString *)filename { + NSString *attachmentFilename = [filename stringByAppendingString:@".data"]; + + if (![_fileManager fileExistsAtPath:attachmentFilename]) + return nil; + + + NSData *codedData = [[NSData alloc] initWithContentsOfFile:attachmentFilename]; + if (!codedData) + return nil; + + NSKeyedUnarchiver *unarchiver = nil; + + @try { + unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:codedData]; + } + @catch (NSException *exception) { + return nil; + } + + if ([unarchiver containsValueForKey:kBITCrashMetaAttachment]) { + BITCrashAttachment *attachment = [unarchiver decodeObjectForKey:kBITCrashMetaAttachment]; + return attachment; + } + + return nil; +} + /** * Extract all app sepcific UUIDs from the crash reports - * + * * This allows us to send the UUIDs in the XML construct to the server, so the server does not need to parse the crash report for this data. * The app specific UUIDs help to identify which dSYMs are needed to symbolicate this crash report. * @@ -357,7 +413,8 @@ NSString *const kBITCrashManagerStatus = @"BITCrashManagerStatus"; // if we have an identification from BITAuthenticator, use this as a default. if (( self.installationIdentificationType == BITAuthenticatorIdentificationTypeHockeyAppEmail || - self.installationIdentificationType == BITAuthenticatorIdentificationTypeHockeyAppUser + self.installationIdentificationType == BITAuthenticatorIdentificationTypeHockeyAppUser || + self.installationIdentificationType == BITAuthenticatorIdentificationTypeWebAuth ) && self.installationIdentification) { useremail = self.installationIdentification; @@ -488,6 +545,14 @@ NSString *const kBITCrashManagerStatus = @"BITCrashManagerStatus"; } [metaDict setObject:applicationLog forKey:kBITCrashMetaApplicationLog]; + if (self.delegate != nil && [self.delegate respondsToSelector:@selector(attachmentForCrashManager:)]) { + BITCrashAttachment *attachment = [self.delegate attachmentForCrashManager:self]; + + if (attachment) { + [self persistAttachment:attachment withFilename:[_crashesDir stringByAppendingPathComponent: cacheFilename]]; + } + } + NSData *plist = [NSPropertyListSerialization dataFromPropertyList:(id)metaDict format:NSPropertyListBinaryFormat_v1_0 errorDescription:&errorString]; @@ -548,6 +613,7 @@ NSString *const kBITCrashManagerStatus = @"BITCrashManagerStatus"; ![file hasSuffix:@".DS_Store"] && ![file hasSuffix:@".analyzer"] && ![file hasSuffix:@".plist"] && + ![file hasSuffix:@".data"] && ![file hasSuffix:@".meta"]) { [_crashFiles addObject:[_crashesDir stringByAppendingPathComponent: file]]; } @@ -746,6 +812,7 @@ NSString *const kBITCrashManagerStatus = @"BITCrashManagerStatus"; NSError *error = NULL; NSMutableString *crashes = nil; + NSMutableArray *attachments = [NSMutableArray array]; _crashIdenticalCurrentVersion = NO; for (NSUInteger i=0; i < [_crashFiles count]; i++) { @@ -760,6 +827,7 @@ NSString *const kBITCrashManagerStatus = @"BITCrashManagerStatus"; BITHockeyLog(@"WARNING: Could not parse crash report"); // we cannot do anything with this report, so delete it [_fileManager removeItemAtPath:filename error:&error]; + [_fileManager removeItemAtPath:[NSString stringWithFormat:@"%@.data", filename] error:&error]; [_fileManager removeItemAtPath:[NSString stringWithFormat:@"%@.meta", filename] error:&error]; [self removeKeyFromKeychain:[NSString stringWithFormat:@"%@.%@", cacheFilename, kBITCrashMetaUserName]]; @@ -804,6 +872,13 @@ NSString *const kBITCrashManagerStatus = @"BITCrashManagerStatus"; useremail = [self stringValueFromKeychainForKey:[NSString stringWithFormat:@"%@.%@", cacheFilename, kBITCrashMetaUserEmail]] ?: @""; userid = [self stringValueFromKeychainForKey:[NSString stringWithFormat:@"%@.%@", cacheFilename, kBITCrashMetaUserID]] ?: @""; applicationLog = [metaDict objectForKey:kBITCrashMetaApplicationLog] ?: @""; + + BITCrashAttachment *attachment = [self attachmentForCrashReport:filename]; + if (attachment) { + NSDictionary *attachmentDict = @{KBITAttachmentDictIndex: @(i), + KBITAttachmentDictAttachment: attachment}; + [attachments addObject:attachmentDict]; + } } else { BITHockeyLog(@"ERROR: Reading crash meta data. %@", error); } @@ -834,6 +909,7 @@ NSString *const kBITCrashManagerStatus = @"BITCrashManagerStatus"; } else { // we cannot do anything with this report, so delete it [_fileManager removeItemAtPath:filename error:&error]; + [_fileManager removeItemAtPath:[NSString stringWithFormat:@"%@.data", filename] error:&error]; [_fileManager removeItemAtPath:[NSString stringWithFormat:@"%@.meta", filename] error:&error]; [self removeKeyFromKeychain:[NSString stringWithFormat:@"%@.%@", cacheFilename, kBITCrashMetaUserName]]; @@ -846,7 +922,7 @@ NSString *const kBITCrashManagerStatus = @"BITCrashManagerStatus"; if (crashes != nil) { BITHockeyLog(@"INFO: Sending crash reports:\n%@", crashes); - [self postXML:[NSString stringWithFormat:@"%@", crashes]]; + [self postXML:[NSString stringWithFormat:@"%@", crashes] attachments:attachments]; } } @@ -894,7 +970,7 @@ NSString *const kBITCrashManagerStatus = @"BITCrashManagerStatus"; * * @param xml The XML data that needs to be send to the server */ -- (void)postXML:(NSString*)xml { +- (void)postXML:(NSString*)xml attachments:(NSArray *)attachments { NSMutableURLRequest *request = nil; NSString *boundary = @"----FOO"; @@ -916,12 +992,28 @@ NSString *const kBITCrashManagerStatus = @"BITCrashManagerStatus"; [request setValue:contentType forHTTPHeaderField:@"Content-type"]; NSMutableData *postBody = [NSMutableData data]; - [postBody appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]]; - [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]]; - [postBody appendData:[xml dataUsingEncoding:NSUTF8StringEncoding]]; - [postBody appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]]; + [postBody appendData:[BITHockeyAppClient dataWithPostValue:[xml dataUsingEncoding:NSUTF8StringEncoding] + forKey:@"xml" + contentType:@"text/xml" + boundary:boundary + filename:@"crash.xml"]]; + + for (NSDictionary *dict in attachments) { + NSInteger index = [(NSNumber *)dict[KBITAttachmentDictIndex] integerValue]; + NSString *key = [NSString stringWithFormat:@"attachment%ld", (long)index]; + + BITCrashAttachment *attachment = (BITCrashAttachment *)dict[KBITAttachmentDictAttachment]; + + [postBody appendData:[BITHockeyAppClient dataWithPostValue:attachment.attachmentData + forKey:key + contentType:attachment.contentType + boundary:boundary + filename:attachment.filename]]; + } + + [postBody appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]]; + [request setHTTPBody:postBody]; _statusCode = 200; diff --git a/Classes/BITCrashManagerDelegate.h b/Classes/BITCrashManagerDelegate.h index e2792b5ce4..c88aef2c93 100644 --- a/Classes/BITCrashManagerDelegate.h +++ b/Classes/BITCrashManagerDelegate.h @@ -29,6 +29,7 @@ #import @class BITCrashManager; +@class BITCrashAttachment; /** The `BITCrashManagerDelegate` formal protocol defines methods further configuring @@ -47,17 +48,43 @@ /** Return any log string based data the crash report being processed should contain @param crashManager The `BITCrashManager` instance invoking this delegate + @see attachmentForCrashManager: @see userNameForCrashManager: @see userEmailForCrashManager: */ -(NSString *)applicationLogForCrashManager:(BITCrashManager *)crashManager; +/** Return a BITCrashAttachment object providing an NSData object the crash report + being processed should contain + + Please limit your attachments to reasonable files to avoid high traffic costs for your users. + + Example implementation: + + - (BITCrashAttachment *)attachmentForCrashManager:(BITCrashManager *)crashManager { + NSData *data = [NSData dataWithContentsOfURL:@"mydatafile"]; + + BITCrashAttachment *attachment = [[BITCrashAttachment alloc] initWithFilename:@"myfile.data" + attachmentData:data + contentType:@"'application/octet-stream"]; + return attachment; + } + + @param crashManager The `BITCrashManager` instance invoking this delegate + @see applicationLogForCrashManager: + @see userNameForCrashManager: + @see userEmailForCrashManager: + */ +-(BITCrashAttachment *)attachmentForCrashManager:(BITCrashManager *)crashManager; + + /** Return the user name or userid that should be send along each crash report @param crashManager The `BITCrashManager` instance invoking this delegate @see applicationLogForCrashManager: + @see attachmentForCrashManager: @see userEmailForCrashManager: @deprecated Please use `BITHockeyManagerDelegate userNameForHockeyManager:componentManager:` instead @warning When returning a non nil value, crash reports are not anonymous any @@ -71,6 +98,7 @@ @param crashManager The `BITCrashManager` instance invoking this delegate @see applicationLogForCrashManager: + @see attachmentForCrashManager: @see userNameForCrashManager: @deprecated Please use `BITHockeyManagerDelegate userEmailForHockeyManager:componentManager:` instead @warning When returning a non nil value, crash reports are not anonymous any diff --git a/Classes/BITFeedbackManagerPrivate.h b/Classes/BITFeedbackManagerPrivate.h index dd5f03a13f..0da30ca52e 100644 --- a/Classes/BITFeedbackManagerPrivate.h +++ b/Classes/BITFeedbackManagerPrivate.h @@ -56,6 +56,11 @@ @property (nonatomic, copy) NSString *userEmail; +// Fetch user meta data +- (BOOL)updateUserIDUsingKeychainAndDelegate; +- (BOOL)updateUserNameUsingKeychainAndDelegate; +- (BOOL)updateUserEmailUsingKeychainAndDelegate; + // load new messages from the server - (void)updateMessagesList; diff --git a/Classes/BITHockeyAppClient.h b/Classes/BITHockeyAppClient.h index a8d5fdbd15..4de7fa24e7 100644 --- a/Classes/BITHockeyAppClient.h +++ b/Classes/BITHockeyAppClient.h @@ -118,8 +118,8 @@ #pragma mark - Helpers /** - * create a post body from the given value, key and boundary - * c/p from HockeyBaseManager + * create a post body from the given value, key and boundary. This is a convenience call to + * dataWithPostValue:forKey:contentType:boundary and aimed at NSString-content. * * @param value - * @param key - @@ -128,4 +128,18 @@ * @return NSData instance configured to be attached on a (post) URLRequest */ + (NSData *)dataWithPostValue:(NSString *)value forKey:(NSString *)key boundary:(NSString *) boundary; + +/** + * create a post body from the given value, key and boundary and content type. + * + * @param value - + * @param key - + *@param contentType - + * @param boundary - + * @param filename - + * + * @return NSData instance configured to be attached on a (post) URLRequest + */ ++ (NSData *)dataWithPostValue:(NSData *)value forKey:(NSString *)key contentType:(NSString *)contentType boundary:(NSString *) boundary filename:(NSString *)filename; + @end diff --git a/Classes/BITHockeyAppClient.m b/Classes/BITHockeyAppClient.m index 168162b47c..37a22b6407 100644 --- a/Classes/BITHockeyAppClient.m +++ b/Classes/BITHockeyAppClient.m @@ -85,12 +85,25 @@ } + (NSData *)dataWithPostValue:(NSString *)value forKey:(NSString *)key boundary:(NSString *) boundary { + return [self dataWithPostValue:[value dataUsingEncoding:NSUTF8StringEncoding] forKey:key contentType:@"text" boundary:boundary filename:nil]; +} + ++ (NSData *)dataWithPostValue:(NSData *)value forKey:(NSString *)key contentType:(NSString *)contentType boundary:(NSString *) boundary filename:(NSString *)filename { NSMutableData *postBody = [NSMutableData data]; [postBody appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]]; - [postBody appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\";\r\n", key] dataUsingEncoding:NSUTF8StringEncoding]]; - [postBody appendData:[[NSString stringWithFormat:@"Content-Type: text\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]]; - [postBody appendData:[value dataUsingEncoding:NSUTF8StringEncoding]]; + + // There's certainly a better way to check if we are supposed to send binary data here. + if (filename){ + [postBody appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"%@\"\r\n", key, filename] dataUsingEncoding:NSUTF8StringEncoding]]; + [postBody appendData:[[NSString stringWithFormat:@"Content-Type: %@\r\n", contentType] dataUsingEncoding:NSUTF8StringEncoding]]; + [postBody appendData:[[NSString stringWithFormat:@"Content-Transfer-Encoding: binary\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]]; + } else { + [postBody appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n", key] dataUsingEncoding:NSUTF8StringEncoding]]; + [postBody appendData:[[NSString stringWithFormat:@"Content-Type: %@\r\n\r\n", contentType] dataUsingEncoding:NSUTF8StringEncoding]]; + } + + [postBody appendData:value]; [postBody appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]]; return postBody; diff --git a/Classes/BITHockeyBaseManager.m b/Classes/BITHockeyBaseManager.m index 434a596c85..a81f9cc373 100644 --- a/Classes/BITHockeyBaseManager.m +++ b/Classes/BITHockeyBaseManager.m @@ -38,9 +38,8 @@ #import "BITKeychainUtils.h" #import -#if !TARGET_IPHONE_SIMULATOR -#import -#endif +#import +#import #ifndef __IPHONE_6_1 #define __IPHONE_6_1 60100 @@ -134,29 +133,35 @@ } - (NSString *)executableUUID { - // This now requires the testing of this feature to be done on an actual device, since it returns always empty strings on the simulator - // Once there is a better solution to get unit test targets build without problems this should be changed again, so testing of this - // feature is also possible using the simulator - // See: http://support.hockeyapp.net/discussions/problems/2306-integrating-hockeyapp-with-test-bundle-target-i386-issues - // http://support.hockeyapp.net/discussions/problems/4113-linking-hockeysdk-to-test-bundle-target -#if !TARGET_IPHONE_SIMULATOR - const uint8_t *command = (const uint8_t *)(&_mh_execute_header + 1); - for (uint32_t idx = 0; idx < _mh_execute_header.ncmds; ++idx) { - const struct load_command *load_command = (const struct load_command *)command; - if (load_command->cmd == LC_UUID) { - const struct uuid_command *uuid_command = (const struct uuid_command *)command; - const uint8_t *uuid = uuid_command->uuid; + const struct mach_header *executableHeader = NULL; + for (uint32_t i = 0; i < _dyld_image_count(); i++) { + const struct mach_header *header = _dyld_get_image_header(i); + if (header->filetype == MH_EXECUTE) { + executableHeader = header; + break; + } + } + + if (!executableHeader) + return @""; + + BOOL is64bit = executableHeader->magic == MH_MAGIC_64 || executableHeader->magic == MH_CIGAM_64; + uintptr_t cursor = (uintptr_t)executableHeader + (is64bit ? sizeof(struct mach_header_64) : sizeof(struct mach_header)); + const struct segment_command *segmentCommand = NULL; + for (uint32_t i = 0; i < executableHeader->ncmds; i++, cursor += segmentCommand->cmdsize) { + segmentCommand = (struct segment_command *)cursor; + if (segmentCommand->cmd == LC_UUID) { + const struct uuid_command *uuidCommand = (const struct uuid_command *)segmentCommand; + const uint8_t *uuid = uuidCommand->uuid; return [[NSString stringWithFormat:@"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X", uuid[0], uuid[1], uuid[2], uuid[3], uuid[4], uuid[5], uuid[6], uuid[7], uuid[8], uuid[9], uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15]] lowercaseString]; - } else { - command += load_command->cmdsize; } } -#endif + return @""; } diff --git a/Classes/BITHockeyHelper.m b/Classes/BITHockeyHelper.m index 11b29ad849..4ea63f165d 100644 --- a/Classes/BITHockeyHelper.m +++ b/Classes/BITHockeyHelper.m @@ -458,10 +458,7 @@ UIImage *bit_newWithContentsOfResolutionIndependentFile(NSString * path) { UIImage *bit_imageWithContentsOfResolutionIndependentFile(NSString *path) { -#ifndef __clang_analyzer__ - // clang alayzer in 4.2b3 thinks here's a leak, which is not the case. return bit_newWithContentsOfResolutionIndependentFile(path); -#endif } diff --git a/Classes/BITHockeyManager.m b/Classes/BITHockeyManager.m index f72a907df1..baa1a7e81c 100644 --- a/Classes/BITHockeyManager.m +++ b/Classes/BITHockeyManager.m @@ -36,6 +36,20 @@ #import "BITHockeyAppClient.h" #import "BITKeychainUtils.h" +#include + +typedef struct { + uint8_t info_version; + const char hockey_version[16]; + const char hockey_build[16]; +} bitstadium_info_t; + +bitstadium_info_t bitstadium_library_info __attribute__((section("__TEXT,__bit_hockey,regular,no_dead_strip"))) = { + .info_version = 1, + .hockey_version = BITHOCKEY_C_VERSION, + .hockey_build = BITHOCKEY_C_BUILD +}; + #if HOCKEYSDK_FEATURE_CRASH_REPORTER #import "BITCrashManagerPrivate.h" @@ -417,11 +431,11 @@ - (NSString *)version { - return BITHOCKEY_VERSION; + return [NSString stringWithUTF8String:bitstadium_library_info.hockey_version]; } - (NSString *)build { - return BITHOCKEY_BUILD; + return [NSString stringWithUTF8String:bitstadium_library_info.hockey_build]; } diff --git a/Classes/BITStoreUpdateManager.m b/Classes/BITStoreUpdateManager.m index 0536f17830..78a0bcef1d 100644 --- a/Classes/BITStoreUpdateManager.m +++ b/Classes/BITStoreUpdateManager.m @@ -155,7 +155,7 @@ if ([self.userDefaults objectForKey:kBITStoreUpdateLastUUID]) { lastSavedUUID = [self.userDefaults objectForKey:kBITStoreUpdateLastUUID]; - if (lastSavedUUID && ![lastSavedUUID isEqualToString:_currentUUID]) { + if (lastSavedUUID && [lastSavedUUID length] > 0 && ![lastSavedUUID isEqualToString:_currentUUID]) { // the UUIDs don't match, store the new one [self.userDefaults setObject:_currentUUID forKey:kBITStoreUpdateLastUUID]; diff --git a/Classes/BITUpdateManager.m b/Classes/BITUpdateManager.m index 3df6c72383..597e35a4eb 100644 --- a/Classes/BITUpdateManager.m +++ b/Classes/BITUpdateManager.m @@ -669,7 +669,7 @@ typedef NS_ENUM(NSInteger, BITUpdateAlertViewTag) { self.checkInProgress = YES; // do we need to update? - if (![self checkForTracker] && ![self shouldCheckForUpdates] && !_currentHockeyViewController) { + if (![self checkForTracker] && !_currentHockeyViewController && ![self shouldCheckForUpdates] && _updateSetting != BITUpdateCheckManually) { BITHockeyLog(@"INFO: Update not needed right now"); self.checkInProgress = NO; return; diff --git a/Classes/HockeySDK.h b/Classes/HockeySDK.h index aa1c4da3ff..c364d4eace 100644 --- a/Classes/HockeySDK.h +++ b/Classes/HockeySDK.h @@ -37,6 +37,7 @@ #if HOCKEYSDK_FEATURE_CRASH_REPORTER #import "BITCrashManager.h" +#import "BITCrashAttachment.h" #import "BITCrashManagerDelegate.h" #endif /* HOCKEYSDK_FEATURE_CRASH_REPORTER */ diff --git a/HockeySDK.podspec b/HockeySDK.podspec index 4c52b919ee..568fb3b3bd 100644 --- a/HockeySDK.podspec +++ b/HockeySDK.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'HockeySDK' - s.version = '3.5.4' + s.version = '3.5.5' s.summary = 'Collect live crash reports, get feedback from your users, distribute your betas, and analyze your test coverage with HockeyApp.' s.description = <<-DESC @@ -12,7 +12,7 @@ Pod::Spec.new do |s| DESC s.homepage = 'http://hockeyapp.net/' - s.documentation_url = 'http://hockeyapp.net/help/sdk/ios/3.5.4/' + s.documentation_url = 'http://hockeyapp.net/help/sdk/ios/3.5.5/' s.license = 'MIT' s.author = { 'Andreas Linde' => 'mail@andreaslinde.de', 'Thomas Dohmke' => "thomas@dohmke.de" } @@ -24,7 +24,7 @@ Pod::Spec.new do |s| s.frameworks = 'CoreText', 'QuartzCore', 'SystemConfiguration', 'CoreGraphics', 'UIKit', 'Security' s.ios.vendored_frameworks = 'Vendor/CrashReporter.framework' - s.xcconfig = {'GCC_PREPROCESSOR_DEFINITIONS' => %{$(inherited) BITHOCKEY_VERSION="@\\"#{s.version}\\"" BITHOCKEY_BUILD="@\\"27\\""} } + s.xcconfig = {'GCC_PREPROCESSOR_DEFINITIONS' => %{$(inherited) BITHOCKEY_VERSION="@\\"#{s.version}\\"" BITHOCKEY_C_VERSION="\\"#{s.version}\\"" BITHOCKEY_BUILD="@\\"28\\"" BITHOCKEY_C_BUILD="\\"28\\""} } s.resource_bundle = { 'HockeySDKResources' => ['Resources/*.png', 'Resources/*.lproj'] } s.preserve_paths = 'Resources', 'Support' diff --git a/README.md b/README.md index 1fc4f8f554..31833fb692 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -## Version 3.5.4 +## Version 3.5.5 -- [Changelog](http://www.hockeyapp.net/help/sdk/ios/3.5.4/docs/docs/Changelog.html) +- [Changelog](http://www.hockeyapp.net/help/sdk/ios/3.5.5/docs/docs/Changelog.html) ## Introduction @@ -31,10 +31,10 @@ The main SDK class is `BITHockeyManager`. It initializes all modules and provide ## Installation & Setup -- [Installation & Setup](http://www.hockeyapp.net/help/sdk/ios/3.5.4/docs/docs/Guide-Installation-Setup.html) (Recommended) -- [Installation & Setup Advanced](http://www.hockeyapp.net/help/sdk/ios/3.5.4/docs/docs/Guide-Installation-Setup-Advanced.html) (Using Git submodule and Xcode sub-project) -- [Identify and authenticate users of Ad-Hoc or Enterprise builds](http://www.hockeyapp.net/help/sdk/ios/3.5.4/docs/docs/HowTo-Authenticating-Users-on-iOS.html) -- [Migration from previous SDK Versions](http://www.hockeyapp.net/help/sdk/ios/3.5.4/docs/docs/Guide-Migration-Kits.html) +- [Installation & Setup](http://www.hockeyapp.net/help/sdk/ios/3.5.5/docs/docs/Guide-Installation-Setup.html) (Recommended) +- [Installation & Setup Advanced](http://www.hockeyapp.net/help/sdk/ios/3.5.5/docs/docs/Guide-Installation-Setup-Advanced.html) (Using Git submodule and Xcode sub-project) +- [Identify and authenticate users of Ad-Hoc or Enterprise builds](http://www.hockeyapp.net/help/sdk/ios/3.5.5/docs/docs/HowTo-Authenticating-Users-on-iOS.html) +- [Migration from previous SDK Versions](http://www.hockeyapp.net/help/sdk/ios/3.5.5/docs/docs/Guide-Migration-Kits.html) - [Mac Desktop Uploader](http://support.hockeyapp.net/kb/how-tos/how-to-upload-to-hockeyapp-on-a-mac) @@ -48,4 +48,4 @@ This documentation provides integrated help in Xcode for all public APIs and a s 3. Copy the content into ~`/Library/Developer/Shared/Documentation/DocSets` -The documentation is also available via the following URL: [http://hockeyapp.net/help/sdk/ios/3.5.4/](http://hockeyapp.net/help/sdk/ios/3.5.4/) +The documentation is also available via the following URL: [http://hockeyapp.net/help/sdk/ios/3.5.5/](http://hockeyapp.net/help/sdk/ios/3.5.5/) diff --git a/Resources/nl.lproj/HockeySDK.strings b/Resources/nl.lproj/HockeySDK.strings old mode 100755 new mode 100644 diff --git a/Resources/ro.lproj/HockeySDK.strings b/Resources/ro.lproj/HockeySDK.strings old mode 100755 new mode 100644 diff --git a/Support/HockeySDK.xcodeproj/project.pbxproj b/Support/HockeySDK.xcodeproj/project.pbxproj index 910428df15..efd12187f7 100644 --- a/Support/HockeySDK.xcodeproj/project.pbxproj +++ b/Support/HockeySDK.xcodeproj/project.pbxproj @@ -95,10 +95,10 @@ 1E5955D015B71C8600A03429 /* IconGradient@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 1E5955C515B71C8600A03429 /* IconGradient@2x.png */; }; 1E5955FD15B7877B00A03429 /* BITHockeyManagerDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 1E5955FA15B7877A00A03429 /* BITHockeyManagerDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; }; 1E5A459216F0DFC200B55C04 /* SenTestingKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1E5A459116F0DFC200B55C04 /* SenTestingKit.framework */; }; - 1E5A459416F0DFC200B55C04 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1E5A459316F0DFC200B55C04 /* UIKit.framework */; }; 1E5A459516F0DFC200B55C04 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E400561D148D79B500EB22B9 /* Foundation.framework */; }; 1E5A459B16F0DFC200B55C04 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 1E5A459916F0DFC200B55C04 /* InfoPlist.strings */; }; 1E5A459E16F0DFC200B55C04 /* BITStoreUpdateManagerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E5A459D16F0DFC200B55C04 /* BITStoreUpdateManagerTests.m */; }; + 1E61CCAF18E0585A00A5E38E /* BITFeedbackManagerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E61CCAE18E0585A00A5E38E /* BITFeedbackManagerTests.m */; }; 1E70A23217F2F982001BB32D /* live_report_empty.plcrash in Resources */ = {isa = PBXBuildFile; fileRef = 1E70A22F17F2F982001BB32D /* live_report_empty.plcrash */; }; 1E70A23317F2F982001BB32D /* live_report_exception.plcrash in Resources */ = {isa = PBXBuildFile; fileRef = 1E70A23017F2F982001BB32D /* live_report_exception.plcrash */; }; 1E70A23417F2F982001BB32D /* live_report_signal.plcrash in Resources */ = {isa = PBXBuildFile; fileRef = 1E70A23117F2F982001BB32D /* live_report_signal.plcrash */; }; @@ -127,6 +127,8 @@ 1EAF20AA162DC0F600957B1D /* feedbackActiviy.png in Resources */ = {isa = PBXBuildFile; fileRef = 1EAF20A6162DC0F600957B1D /* feedbackActiviy.png */; }; 1EAF20AB162DC0F600957B1D /* feedbackActiviy@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 1EAF20A7162DC0F600957B1D /* feedbackActiviy@2x.png */; }; 1EB52FD5167B766100C801D5 /* HockeySDK.strings in Resources */ = {isa = PBXBuildFile; fileRef = 1E59555F15B6F80E00A03429 /* HockeySDK.strings */; }; + 1ED570C718BF878C00AB3350 /* BITCrashAttachment.h in Headers */ = {isa = PBXBuildFile; fileRef = 1ED570C518BF878C00AB3350 /* BITCrashAttachment.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1ED570C818BF878C00AB3350 /* BITCrashAttachment.m in Sources */ = {isa = PBXBuildFile; fileRef = 1ED570C618BF878C00AB3350 /* BITCrashAttachment.m */; }; 1EF95CA6162CB037000AE3AD /* BITFeedbackActivity.h in Headers */ = {isa = PBXBuildFile; fileRef = 1EF95CA4162CB036000AE3AD /* BITFeedbackActivity.h */; settings = {ATTRIBUTES = (Public, ); }; }; 1EF95CA7162CB037000AE3AD /* BITFeedbackActivity.m in Sources */ = {isa = PBXBuildFile; fileRef = 1EF95CA5162CB036000AE3AD /* BITFeedbackActivity.m */; }; 1EF95CAA162CB314000AE3AD /* BITFeedbackComposeViewControllerDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 1EF95CA9162CB313000AE3AD /* BITFeedbackComposeViewControllerDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -246,11 +248,11 @@ 1E5955FA15B7877A00A03429 /* BITHockeyManagerDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BITHockeyManagerDelegate.h; sourceTree = ""; }; 1E5A459016F0DFC200B55C04 /* HockeySDKTests.octest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = HockeySDKTests.octest; sourceTree = BUILT_PRODUCTS_DIR; }; 1E5A459116F0DFC200B55C04 /* SenTestingKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SenTestingKit.framework; path = Library/Frameworks/SenTestingKit.framework; sourceTree = DEVELOPER_DIR; }; - 1E5A459316F0DFC200B55C04 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; }; 1E5A459816F0DFC200B55C04 /* HockeySDKTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "HockeySDKTests-Info.plist"; sourceTree = ""; }; 1E5A459A16F0DFC200B55C04 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 1E5A459D16F0DFC200B55C04 /* BITStoreUpdateManagerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BITStoreUpdateManagerTests.m; sourceTree = ""; }; 1E5A459F16F0DFC200B55C04 /* HockeySDKTests-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "HockeySDKTests-Prefix.pch"; sourceTree = ""; }; + 1E61CCAE18E0585A00A5E38E /* BITFeedbackManagerTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BITFeedbackManagerTests.m; sourceTree = ""; }; 1E66CA9115D4100500F35BED /* buildnumber.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = buildnumber.xcconfig; sourceTree = ""; }; 1E6DDCEE169E290C0076C65D /* ro */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ro; path = ro.lproj/HockeySDK.strings; sourceTree = ""; }; 1E6F0450167B5E5600ED1C86 /* pt-PT */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-PT"; path = "pt-PT.lproj/HockeySDK.strings"; sourceTree = ""; }; @@ -283,6 +285,8 @@ 1EAF20A6162DC0F600957B1D /* feedbackActiviy.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = feedbackActiviy.png; sourceTree = ""; }; 1EAF20A7162DC0F600957B1D /* feedbackActiviy@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "feedbackActiviy@2x.png"; sourceTree = ""; }; 1EB52FC3167B73D400C801D5 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/HockeySDK.strings; sourceTree = ""; }; + 1ED570C518BF878C00AB3350 /* BITCrashAttachment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BITCrashAttachment.h; sourceTree = ""; }; + 1ED570C618BF878C00AB3350 /* BITCrashAttachment.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BITCrashAttachment.m; sourceTree = ""; }; 1EDA60CF15C2C1450032D10B /* HockeySDK-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "HockeySDK-Info.plist"; sourceTree = ""; }; 1EF95CA4162CB036000AE3AD /* BITFeedbackActivity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BITFeedbackActivity.h; sourceTree = ""; }; 1EF95CA5162CB036000AE3AD /* BITFeedbackActivity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BITFeedbackActivity.m; sourceTree = ""; }; @@ -332,7 +336,6 @@ files = ( 1EA1170016F4D32C001C015C /* libHockeySDK.a in Frameworks */, 1E5A459216F0DFC200B55C04 /* SenTestingKit.framework in Frameworks */, - 1E5A459416F0DFC200B55C04 /* UIKit.framework in Frameworks */, 1EA1170116F4D354001C015C /* CrashReporter.framework in Frameworks */, 1E5A459516F0DFC200B55C04 /* Foundation.framework in Frameworks */, 1E7A45FC16F54FB5005B08F1 /* OCHamcrestIOS.framework in Frameworks */, @@ -377,6 +380,7 @@ 1E5A459D16F0DFC200B55C04 /* BITStoreUpdateManagerTests.m */, E48A3DEE17B3EFF100924C3D /* BITAuthenticatorTests.m */, 1EFF03E417F2485500A5F13C /* BITCrashManagerTests.m */, + 1E61CCAE18E0585A00A5E38E /* BITFeedbackManagerTests.m */, E40E0B0817DA19DC005E38C1 /* BITHockeyAppClientTests.m */, E4507E4217F0658F00171A0D /* BITKeychainUtilsTests.m */, 1E70A23517F31B82001BB32D /* BITHockeyHelperTests.m */, @@ -480,6 +484,8 @@ 1E754E571621FBB70070AB92 /* BITCrashManager.m */, 1EFF03D717F20F8300A5F13C /* BITCrashManagerPrivate.h */, 1E754E581621FBB70070AB92 /* BITCrashManagerDelegate.h */, + 1ED570C518BF878C00AB3350 /* BITCrashAttachment.h */, + 1ED570C618BF878C00AB3350 /* BITCrashAttachment.m */, 1E754E5A1621FBB70070AB92 /* BITCrashReportTextFormatter.h */, 1E754E5B1621FBB70070AB92 /* BITCrashReportTextFormatter.m */, ); @@ -560,7 +566,6 @@ E41EB48B148D7C4E0015DEDC /* CrashReporter.framework */, E400561D148D79B500EB22B9 /* Foundation.framework */, 1E5A459116F0DFC200B55C04 /* SenTestingKit.framework */, - 1E5A459316F0DFC200B55C04 /* UIKit.framework */, ); name = Frameworks; sourceTree = ""; @@ -648,6 +653,7 @@ 1E49A4AF161222B900463151 /* BITHockeyBaseManager.h in Headers */, 1E49A4B8161222B900463151 /* BITHockeyBaseViewController.h in Headers */, 1E94F9E116E91330006570AD /* BITStoreUpdateManager.h in Headers */, + 1ED570C718BF878C00AB3350 /* BITCrashAttachment.h in Headers */, 1E0829001708F69A0073050E /* BITStoreUpdateManagerDelegate.h in Headers */, 1E49A4421612223B00463151 /* BITFeedbackListViewCell.h in Headers */, 1E49A4541612223B00463151 /* BITFeedbackManagerPrivate.h in Headers */, @@ -737,7 +743,7 @@ E4005611148D79B500EB22B9 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0500; + LastUpgradeCheck = 0510; }; buildConfigurationList = E4005614148D79B500EB22B9 /* Build configuration list for PBXProject "HockeySDK" */; compatibilityVersion = "Xcode 3.2"; @@ -833,7 +839,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "# Sets the target folders and the final framework product.\nFMK_NAME=HockeySDK\nFMK_VERSION=A\nFMK_RESOURCE_BUNDLE=HockeySDKResources\n\n# Documentation\nHOCKEYSDK_DOCSET_VERSION_NAME=\"de.bitstadium.${HOCKEYSDK_DOCSET_NAME}-${VERSION_STRING}\"\n\n# Install dir will be the final output to the framework.\n# The following line create it in the root folder of the current project.\nPRODUCTS_DIR=${SRCROOT}/../Products\nPLCR_DIR=${SRCROOT}/../Vendor/CrashReporter.framework\nZIP_FOLDER=HockeySDK-iOS\nTEMP_DIR=${PRODUCTS_DIR}/${ZIP_FOLDER}\nINSTALL_DIR=${TEMP_DIR}/${FMK_NAME}.framework\n\n# Working dir will be deleted after the framework creation.\nWRK_DIR=build\nDEVICE_DIR=${WRK_DIR}/Release-iphoneos\nSIMULATOR_DIR=${WRK_DIR}/Release-iphonesimulator\nHEADERS_DIR=${WRK_DIR}/Release-iphoneos/usr/local/include\n\n# Building both architectures.\nxcodebuild -project \"HockeySDK.xcodeproj\" -configuration \"Release\" -target \"${FMK_NAME}\" -sdk iphoneos\nxcodebuild -project \"HockeySDK.xcodeproj\" -configuration \"Release\" -target \"${FMK_NAME}\" -sdk iphonesimulator\n\n# Cleaning the oldest.\nif [ -d \"${TEMP_DIR}\" ]\nthen\nrm -rf \"${TEMP_DIR}\"\nfi\n\n# Creates and renews the final product folder.\nmkdir -p \"${INSTALL_DIR}\"\nmkdir -p \"${INSTALL_DIR}/Versions\"\nmkdir -p \"${INSTALL_DIR}/Versions/${FMK_VERSION}\"\nmkdir -p \"${INSTALL_DIR}/Versions/${FMK_VERSION}/Resources\"\nmkdir -p \"${INSTALL_DIR}/Versions/${FMK_VERSION}/Headers\"\n\n# Creates the internal links.\n# It MUST uses relative path, otherwise will not work when the folder is copied/moved.\nln -s \"${FMK_VERSION}\" \"${INSTALL_DIR}/Versions/Current\"\nln -s \"Versions/Current/Headers\" \"${INSTALL_DIR}/Headers\"\nln -s \"Versions/Current/Resources\" \"${INSTALL_DIR}/Resources\"\nln -s \"Versions/Current/${FMK_NAME}\" \"${INSTALL_DIR}/${FMK_NAME}\"\n\n# Copies the headers and resources files to the final product folder.\ncp -R \"${SRCROOT}/build/Release-iphoneos/include/HockeySDK/\" \"${INSTALL_DIR}/Versions/${FMK_VERSION}/Headers/\"\ncp -R \"${PLCR_DIR}/Versions/A/Headers/\" \"${INSTALL_DIR}/Versions/${FMK_VERSION}/Headers/\"\ncp -R \"${DEVICE_DIR}/${FMK_RESOURCE_BUNDLE}.bundle\" \"${INSTALL_DIR}/Versions/${FMK_VERSION}/Resources/\"\ncp -f \"${SRCROOT}/${FMK_NAME}.xcconfig\" \"${INSTALL_DIR}/Versions/${FMK_VERSION}/Resources/\"\n\n# Uses the Lipo Tool to merge both binary files (i386 + armv6/armv7) into one Universal final product.\nlipo -create \"${DEVICE_DIR}/lib${FMK_NAME}.a\" \"${SIMULATOR_DIR}/lib${FMK_NAME}.a\" -output \"${INSTALL_DIR}/Versions/${FMK_VERSION}/${FMK_NAME}\"\n\n# Combine the CrashReporter static library into a new Hockey static library file if they are not already present and copy the public headers too\nif [ -z $(otool -L \"${INSTALL_DIR}/Versions/${FMK_VERSION}/${FMK_NAME}\" | grep 'libCrashReporter') ]\nthen\nlibtool -static -o \"${INSTALL_DIR}/Versions/${FMK_VERSION}/${FMK_NAME}\" \"${INSTALL_DIR}/Versions/${FMK_VERSION}/${FMK_NAME}\" \"${SRCROOT}/../Vendor/CrashReporter.framework/Versions/A/CrashReporter\"\nfi\n\nrm -r \"${WRK_DIR}\"\n\n# build embeddedframework folder and move framework into it\nmkdir \"${INSTALL_DIR}/../${FMK_NAME}.embeddedframework\"\nmv \"${INSTALL_DIR}\" \"${INSTALL_DIR}/../${FMK_NAME}.embeddedframework/${FMK_NAME}.framework\"\n\n# link Resources\nNEW_INSTALL_DIR=${TEMP_DIR}/${FMK_NAME}.embeddedframework\nmkdir \"${NEW_INSTALL_DIR}/Resources\"\nln -s \"../${FMK_NAME}.framework/Resources/${FMK_RESOURCE_BUNDLE}.bundle\" \"${NEW_INSTALL_DIR}/Resources/${FMK_RESOURCE_BUNDLE}.bundle\"\nln -s \"../${FMK_NAME}.framework/Resources/${FMK_NAME}.xcconfig\" \"${NEW_INSTALL_DIR}/Resources/${FMK_NAME}.xcconfig\"\n\n# copy license, changelog, documentation, integration json\ncp -f \"${SRCROOT}/../Docs/Changelog-template.md\" \"${TEMP_DIR}/CHANGELOG\"\ncp -f \"${SRCROOT}/../Docs/Guide-Installation-Setup-template.md\" \"${TEMP_DIR}/README.md\"\ncp -f \"${SRCROOT}/../LICENSE\" \"${TEMP_DIR}\"\nmkdir \"${TEMP_DIR}/${HOCKEYSDK_DOCSET_VERSION_NAME}.docset\"\ncp -R \"${SRCROOT}/../documentation/docset/Contents\" \"${TEMP_DIR}/${HOCKEYSDK_DOCSET_VERSION_NAME}.docset\"\n\n# build zip\ncd \"${PRODUCTS_DIR}\"\nrm -f \"${FMK_NAME}-iOS-${VERSION_STRING}.zip\"\nzip -yr \"${FMK_NAME}-iOS-${VERSION_STRING}.zip\" \"${ZIP_FOLDER}\" -x \\*/.*\n\n#copy to output dir on cisimple\nif [ $CISIMPLE ]; then\n if [ ! -d \"${CONFIGURATION_BUILD_DIR}\" ]; then\n mkdir \"${CONFIGURATION_BUILD_DIR}\"\n fi\n cd \"${PRODUCTS_DIR}\"\n cp \"${FMK_NAME}-iOS-${VERSION_STRING}.zip\" \"${CONFIGURATION_BUILD_DIR}/${FMK_NAME}-iOS-${VERSION_STRING}.zip\"\nfi"; + shellScript = "# Sets the target folders and the final framework product.\nFMK_NAME=HockeySDK\nFMK_VERSION=A\nFMK_RESOURCE_BUNDLE=HockeySDKResources\n\n# Documentation\nHOCKEYSDK_DOCSET_VERSION_NAME=\"de.bitstadium.${HOCKEYSDK_DOCSET_NAME}-${VERSION_STRING}\"\n\n# Install dir will be the final output to the framework.\n# The following line create it in the root folder of the current project.\nPRODUCTS_DIR=${SRCROOT}/../Products\nPLCR_DIR=${SRCROOT}/../Vendor/CrashReporter.framework\nZIP_FOLDER=HockeySDK-iOS\nTEMP_DIR=${PRODUCTS_DIR}/${ZIP_FOLDER}\nINSTALL_DIR=${TEMP_DIR}/${FMK_NAME}.framework\n\n# Working dir will be deleted after the framework creation.\nWRK_DIR=build\nDEVICE_DIR=${WRK_DIR}/Release-iphoneos\nSIMULATOR_DIR=${WRK_DIR}/Release-iphonesimulator\nHEADERS_DIR=${WRK_DIR}/Release-iphoneos/usr/local/include\n\n# Building both architectures.\nxcodebuild -project \"HockeySDK.xcodeproj\" -configuration \"Release\" -target \"${FMK_NAME}\" -sdk iphoneos\nxcodebuild -project \"HockeySDK.xcodeproj\" -configuration \"Release\" -target \"${FMK_NAME}\" -sdk iphonesimulator\n\n# Cleaning the oldest.\nif [ -d \"${TEMP_DIR}\" ]\nthen\nrm -rf \"${TEMP_DIR}\"\nfi\n\n# Creates and renews the final product folder.\nmkdir -p \"${INSTALL_DIR}\"\nmkdir -p \"${INSTALL_DIR}/Versions\"\nmkdir -p \"${INSTALL_DIR}/Versions/${FMK_VERSION}\"\nmkdir -p \"${INSTALL_DIR}/Versions/${FMK_VERSION}/Resources\"\nmkdir -p \"${INSTALL_DIR}/Versions/${FMK_VERSION}/Headers\"\n\n# Creates the internal links.\n# It MUST uses relative path, otherwise will not work when the folder is copied/moved.\nln -s \"${FMK_VERSION}\" \"${INSTALL_DIR}/Versions/Current\"\nln -s \"Versions/Current/Headers\" \"${INSTALL_DIR}/Headers\"\nln -s \"Versions/Current/Resources\" \"${INSTALL_DIR}/Resources\"\nln -s \"Versions/Current/${FMK_NAME}\" \"${INSTALL_DIR}/${FMK_NAME}\"\n\n# Copies the headers and resources files to the final product folder.\ncp -R \"${SRCROOT}/build/Release-iphoneos/include/HockeySDK/\" \"${INSTALL_DIR}/Versions/${FMK_VERSION}/Headers/\"\ncp -R \"${PLCR_DIR}/Versions/A/Headers/\" \"${INSTALL_DIR}/Versions/${FMK_VERSION}/Headers/\"\ncp -R \"${DEVICE_DIR}/${FMK_RESOURCE_BUNDLE}.bundle\" \"${INSTALL_DIR}/Versions/${FMK_VERSION}/Resources/\"\ncp -f \"${SRCROOT}/${FMK_NAME}.xcconfig\" \"${INSTALL_DIR}/Versions/${FMK_VERSION}/Resources/\"\n\n# Uses the Lipo Tool to merge both binary files (i386 + armv6/armv7) into one Universal final product.\nlipo -create \"${DEVICE_DIR}/lib${FMK_NAME}.a\" \"${SIMULATOR_DIR}/lib${FMK_NAME}.a\" -output \"${INSTALL_DIR}/Versions/${FMK_VERSION}/${FMK_NAME}\"\n\n# Combine the CrashReporter static library into a new Hockey static library file if they are not already present and copy the public headers too\nif [ -z $(otool -L \"${INSTALL_DIR}/Versions/${FMK_VERSION}/${FMK_NAME}\" | grep 'libCrashReporter') ]\nthen\nlibtool -static -o \"${INSTALL_DIR}/Versions/${FMK_VERSION}/${FMK_NAME}\" \"${INSTALL_DIR}/Versions/${FMK_VERSION}/${FMK_NAME}\" \"${SRCROOT}/../Vendor/CrashReporter.framework/Versions/A/CrashReporter\"\nfi\n\nrm -r \"${WRK_DIR}\"\n\n# build embeddedframework folder and move framework into it\nmkdir \"${INSTALL_DIR}/../${FMK_NAME}.embeddedframework\"\nmv \"${INSTALL_DIR}\" \"${INSTALL_DIR}/../${FMK_NAME}.embeddedframework/${FMK_NAME}.framework\"\n\n# link Resources\nNEW_INSTALL_DIR=${TEMP_DIR}/${FMK_NAME}.embeddedframework\nmkdir \"${NEW_INSTALL_DIR}/Resources\"\nln -s \"../${FMK_NAME}.framework/Resources/${FMK_RESOURCE_BUNDLE}.bundle\" \"${NEW_INSTALL_DIR}/Resources/${FMK_RESOURCE_BUNDLE}.bundle\"\nln -s \"../${FMK_NAME}.framework/Resources/${FMK_NAME}.xcconfig\" \"${NEW_INSTALL_DIR}/Resources/${FMK_NAME}.xcconfig\"\n\n# copy license, changelog, documentation, integration json\ncp -f \"${SRCROOT}/../Docs/Changelog-template.md\" \"${TEMP_DIR}/CHANGELOG\"\ncp -f \"${SRCROOT}/../Docs/Guide-Installation-Setup-template.md\" \"${TEMP_DIR}/README.md\"\ncp -f \"${SRCROOT}/../LICENSE\" \"${TEMP_DIR}\"\nmkdir \"${TEMP_DIR}/${HOCKEYSDK_DOCSET_VERSION_NAME}.docset\"\ncp -R \"${SRCROOT}/../documentation/docset/Contents\" \"${TEMP_DIR}/${HOCKEYSDK_DOCSET_VERSION_NAME}.docset\"\n\n# build zip\ncd \"${PRODUCTS_DIR}\"\nrm -f \"${FMK_NAME}-iOS-${VERSION_STRING}.zip\"\nzip -yr \"${FMK_NAME}-iOS-${VERSION_STRING}.zip\" \"${ZIP_FOLDER}\" -x \\*/.*\n"; }; 1E8E66B215BC3D8200632A2E /* ShellScript */ = { isa = PBXShellScriptBuildPhase; @@ -876,6 +882,7 @@ 1E49A4511612223B00463151 /* BITFeedbackManager.m in Sources */, E4933E8117B66CDA00B11ACC /* BITHTTPOperation.m in Sources */, 1E49A45A1612223B00463151 /* BITFeedbackMessage.m in Sources */, + 1ED570C818BF878C00AB3350 /* BITCrashAttachment.m in Sources */, 1E49A4601612223B00463151 /* BITFeedbackUserDataViewController.m in Sources */, 1E49A4701612226D00463151 /* BITAppVersionMetaInfo.m in Sources */, 1E49A4761612226D00463151 /* BITUpdateManager.m in Sources */, @@ -915,6 +922,7 @@ 1E70A23617F31B82001BB32D /* BITHockeyHelperTests.m in Sources */, E48A3DEF17B3EFF100924C3D /* BITAuthenticatorTests.m in Sources */, 1EA1170716F53B91001C015C /* BITTestHelper.m in Sources */, + 1E61CCAF18E0585A00A5E38E /* BITFeedbackManagerTests.m in Sources */, E4507E4317F0658F00171A0D /* BITKeychainUtilsTests.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/Support/HockeySDK.xcodeproj/xcshareddata/xcschemes/HockeySDK Documentation.xcscheme b/Support/HockeySDK.xcodeproj/xcshareddata/xcschemes/HockeySDK Documentation.xcscheme index c339433201..6d2f03a55f 100644 --- a/Support/HockeySDK.xcodeproj/xcshareddata/xcschemes/HockeySDK Documentation.xcscheme +++ b/Support/HockeySDK.xcodeproj/xcshareddata/xcschemes/HockeySDK Documentation.xcscheme @@ -1,6 +1,6 @@ + +#define HC_SHORTHAND +#import + +#define MOCKITO_SHORTHAND +#import + +#import "HockeySDK.h" +#import "HockeySDKPrivate.h" +#import "BITFeedbackManager.h" +#import "BITFeedbackManagerPrivate.h" +#import "BITHockeyBaseManager.h" +#import "BITHockeyBaseManagerPrivate.h" + +#import "BITTestHelper.h" + +@interface BITFeedbackManagerTests : SenTestCase + +@end + +@implementation BITFeedbackManagerTests { + BITFeedbackManager *_sut; +} + +- (void)setUp { + [super setUp]; + + BITHockeyManager *hm = [BITHockeyManager sharedHockeyManager]; + hm.delegate = nil; + _sut = [[BITFeedbackManager alloc] initWithAppIdentifier:nil isAppStoreEnvironment:NO]; + _sut.delegate = nil; +} + +- (void)tearDown { +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wimplicit" + __gcov_flush(); +# pragma clang diagnostic pop + + [_sut removeKeyFromKeychain:kBITHockeyMetaUserID]; + [_sut removeKeyFromKeychain:kBITHockeyMetaUserName]; + [_sut removeKeyFromKeychain:kBITHockeyMetaUserEmail]; + + _sut = nil; + + [super tearDown]; +} + +#pragma mark - Private + +- (void)startManager { + [_sut startManager]; +} + +#pragma mark - Setup Tests + + +#pragma mark - User Metadata + +- (void)testUpdateUserIDWithNoDataPresent { + BITHockeyManager *hm = [BITHockeyManager sharedHockeyManager]; + id delegateMock = mockProtocol(@protocol(BITHockeyManagerDelegate)); + hm.delegate = delegateMock; + _sut.delegate = delegateMock; + + BOOL dataAvailable = [_sut updateUserIDUsingKeychainAndDelegate]; + + assertThatBool(dataAvailable, equalToBool(NO)); + assertThat(_sut.userID, nilValue()); + + [verifyCount(delegateMock, times(1)) userIDForHockeyManager:hm componentManager:_sut]; +} + +- (void)testUpdateUserIDWithDelegateReturningData { + BITHockeyManager *hm = [BITHockeyManager sharedHockeyManager]; + NSObject *classMock = mockObjectAndProtocol([NSObject class], @protocol(BITHockeyManagerDelegate)); + [given([classMock userIDForHockeyManager:hm componentManager:_sut]) willReturn:@"test"]; + hm.delegate = classMock; + _sut.delegate = classMock; + + BOOL dataAvailable = [_sut updateUserIDUsingKeychainAndDelegate]; + + assertThatBool(dataAvailable, equalToBool(YES)); + assertThat(_sut.userID, equalTo(@"test")); + + [verifyCount(classMock, times(1)) userIDForHockeyManager:hm componentManager:_sut]; +} + +- (void)testUpdateUserIDWithValueInKeychain { + [_sut addStringValueToKeychain:@"test" forKey:kBITHockeyMetaUserID]; + + BOOL dataAvailable = [_sut updateUserIDUsingKeychainAndDelegate]; + + assertThatBool(dataAvailable, equalToBool(YES)); + assertThat(_sut.userID, equalTo(@"test")); +} + +- (void)testUpdateUserIDWithGlobalSetter { + BITHockeyManager *hm = [BITHockeyManager sharedHockeyManager]; + [hm setUserID:@"test"]; + + BOOL dataAvailable = [_sut updateUserIDUsingKeychainAndDelegate]; + + assertThatBool(dataAvailable, equalToBool(YES)); + assertThat(_sut.userID, equalTo(@"test")); +} + + +- (void)testUpdateUserNameWithNoDataPresent { + BITHockeyManager *hm = [BITHockeyManager sharedHockeyManager]; + id delegateMock = mockProtocol(@protocol(BITHockeyManagerDelegate)); + hm.delegate = delegateMock; + _sut.delegate = delegateMock; + + BOOL dataAvailable = [_sut updateUserNameUsingKeychainAndDelegate]; + + assertThatBool(dataAvailable, equalToBool(NO)); + assertThat(_sut.userName, nilValue()); + + [verifyCount(delegateMock, times(1)) userNameForHockeyManager:hm componentManager:_sut]; +} + +- (void)testUpdateUserNameWithDelegateReturningData { + BITHockeyManager *hm = [BITHockeyManager sharedHockeyManager]; + NSObject *classMock = mockObjectAndProtocol([NSObject class], @protocol(BITHockeyManagerDelegate)); + [given([classMock userNameForHockeyManager:hm componentManager:_sut]) willReturn:@"test"]; + hm.delegate = classMock; + _sut.delegate = classMock; + + BOOL dataAvailable = [_sut updateUserNameUsingKeychainAndDelegate]; + + assertThatBool(dataAvailable, equalToBool(YES)); + assertThat(_sut.userName, equalTo(@"test")); + + [verifyCount(classMock, times(1)) userNameForHockeyManager:hm componentManager:_sut]; +} + +- (void)testUpdateUserNameWithValueInKeychain { + [_sut addStringValueToKeychain:@"test" forKey:kBITHockeyMetaUserName]; + + BOOL dataAvailable = [_sut updateUserNameUsingKeychainAndDelegate]; + + assertThatBool(dataAvailable, equalToBool(YES)); + assertThat(_sut.userName, equalTo(@"test")); +} + +- (void)testUpdateUserNameWithGlobalSetter { + BITHockeyManager *hm = [BITHockeyManager sharedHockeyManager]; + [hm setUserName:@"test"]; + + BOOL dataAvailable = [_sut updateUserNameUsingKeychainAndDelegate]; + + assertThatBool(dataAvailable, equalToBool(YES)); + assertThat(_sut.userName, equalTo(@"test")); +} + + +- (void)testUpdateUserEmailWithNoDataPresent { + BITHockeyManager *hm = [BITHockeyManager sharedHockeyManager]; + id delegateMock = mockProtocol(@protocol(BITHockeyManagerDelegate)); + hm.delegate = delegateMock; + _sut.delegate = delegateMock; + + BOOL dataAvailable = [_sut updateUserEmailUsingKeychainAndDelegate]; + + assertThatBool(dataAvailable, equalToBool(NO)); + assertThat(_sut.userEmail, nilValue()); + + [verifyCount(delegateMock, times(1)) userEmailForHockeyManager:hm componentManager:_sut]; +} + +- (void)testUpdateUserEmailWithDelegateReturningData { + BITHockeyManager *hm = [BITHockeyManager sharedHockeyManager]; + NSObject *classMock = mockObjectAndProtocol([NSObject class], @protocol(BITHockeyManagerDelegate)); + [given([classMock userEmailForHockeyManager:hm componentManager:_sut]) willReturn:@"test"]; + hm.delegate = classMock; + _sut.delegate = classMock; + + BOOL dataAvailable = [_sut updateUserEmailUsingKeychainAndDelegate]; + + assertThatBool(dataAvailable, equalToBool(YES)); + assertThat(_sut.userEmail, equalTo(@"test")); + + [verifyCount(classMock, times(1)) userEmailForHockeyManager:hm componentManager:_sut]; +} + +- (void)testUpdateUserEmailWithValueInKeychain { + [_sut addStringValueToKeychain:@"test" forKey:kBITHockeyMetaUserEmail]; + + BOOL dataAvailable = [_sut updateUserEmailUsingKeychainAndDelegate]; + + assertThatBool(dataAvailable, equalToBool(YES)); + assertThat(_sut.userEmail, equalTo(@"test")); +} + +- (void)testUpdateUserEmailWithGlobalSetter { + BITHockeyManager *hm = [BITHockeyManager sharedHockeyManager]; + [hm setUserEmail:@"test"]; + + BOOL dataAvailable = [_sut updateUserEmailUsingKeychainAndDelegate]; + + assertThatBool(dataAvailable, equalToBool(YES)); + assertThat(_sut.userEmail, equalTo(@"test")); +} + + +@end diff --git a/Support/HockeySDKTests/BITHockeyHelperTests.m b/Support/HockeySDKTests/BITHockeyHelperTests.m index 9166d961cb..315a7c4238 100644 --- a/Support/HockeySDKTests/BITHockeyHelperTests.m +++ b/Support/HockeySDKTests/BITHockeyHelperTests.m @@ -32,7 +32,12 @@ } - (void)tearDown { - // Put teardown code here; it will be run once, after the last test case. + // Tear-down code here. +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wimplicit" + __gcov_flush(); +# pragma clang diagnostic pop + [super tearDown]; } diff --git a/Support/HockeySDKTests/BITStoreUpdateManagerTests.m b/Support/HockeySDKTests/BITStoreUpdateManagerTests.m index ffff07bfed..897ec761f1 100644 --- a/Support/HockeySDKTests/BITStoreUpdateManagerTests.m +++ b/Support/HockeySDKTests/BITStoreUpdateManagerTests.m @@ -300,7 +300,7 @@ STAssertFalse(result, @"The newer version is being ignored"); } -- (void)testReportedVersionIsNewerThanTHeIgnoredVersion { +- (void)testReportedVersionIsNewerThanTheIgnoredVersion { NSUserDefaults *mockUserDefaults = mock([NSUserDefaults class]); [given([mockUserDefaults objectForKey:@"BITStoreUpdateLastStoreVersion"]) willReturn:@"4.1.1"]; [given([mockUserDefaults objectForKey:@"BITStoreUpdateLastUUID"]) willReturn:@""]; diff --git a/Support/buildnumber.xcconfig b/Support/buildnumber.xcconfig index 39e6f651aa..b4f00c3b90 100644 --- a/Support/buildnumber.xcconfig +++ b/Support/buildnumber.xcconfig @@ -1,8 +1,8 @@ #include "HockeySDK.xcconfig" -BUILD_NUMBER = 27 -VERSION_STRING = 3.5.4 -GCC_PREPROCESSOR_DEFINITIONS = $(inherited) BITHOCKEY_VERSION="@\""$(VERSION_STRING)"\"" BITHOCKEY_BUILD="@\""$(BUILD_NUMBER)"\"" +BUILD_NUMBER = 28 +VERSION_STRING = 3.5.5 +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) BITHOCKEY_VERSION="@\""$(VERSION_STRING)"\"" BITHOCKEY_BUILD="@\""$(BUILD_NUMBER)"\"" BITHOCKEY_C_VERSION="\""$(VERSION_STRING)"\"" BITHOCKEY_C_BUILD="\""$(BUILD_NUMBER)"\"" BIT_ARM_ARCHS = armv7 armv7s arm64 BIT_SIM_ARCHS = x86_64 i386 ARCHS = $(BIT_ARM_ARCHS) diff --git a/Vendor/CrashReporter.framework/Versions/A/CrashReporter b/Vendor/CrashReporter.framework/Versions/A/CrashReporter index ef9fc8e724..3ee803a4c6 100644 Binary files a/Vendor/CrashReporter.framework/Versions/A/CrashReporter and b/Vendor/CrashReporter.framework/Versions/A/CrashReporter differ diff --git a/Vendor/CrashReporter.framework/Versions/A/Headers/PLCrashReportProcessInfo.h b/Vendor/CrashReporter.framework/Versions/A/Headers/PLCrashReportProcessInfo.h index f1bd05116d..ca683d50da 100644 --- a/Vendor/CrashReporter.framework/Versions/A/Headers/PLCrashReportProcessInfo.h +++ b/Vendor/CrashReporter.framework/Versions/A/Headers/PLCrashReportProcessInfo.h @@ -32,7 +32,7 @@ @interface PLCrashReportProcessInfo : NSObject { @private - /** Process name */ + /** Process name, or nil if unavailable. */ NSString *_processName; /** Process ID */ @@ -45,7 +45,7 @@ * will be nil. */ NSDate *_processStartTime; - /** Parent process name */ + /** Parent process name, or nil if unavailable. */ NSString *_parentProcessName; /** Parent process ID */ diff --git a/Vendor/CrashReporter.framework/Versions/A/Resources/Info.plist b/Vendor/CrashReporter.framework/Versions/A/Resources/Info.plist index c147c0f734..edca17c4d6 100644 --- a/Vendor/CrashReporter.framework/Versions/A/Resources/Info.plist +++ b/Vendor/CrashReporter.framework/Versions/A/Resources/Info.plist @@ -3,7 +3,7 @@ BuildMachineOSBuild - 13B42 + 13C64 CFBundleDevelopmentRegion English CFBundleExecutable @@ -23,16 +23,16 @@ DTCompiler com.apple.compilers.llvm.clang.1_0 DTPlatformBuild - 5A3005 + 5B1008 DTPlatformVersion GM DTSDKBuild - 13A595 + 13C64 DTSDKName macosx10.9 DTXcode - 0502 + 0511 DTXcodeBuild - 5A3005 + 5B1008 diff --git a/Vendor/XcodeCoverage/cleancov b/Vendor/XcodeCoverage/cleancov index 1130af9d13..948886b2a7 100755 --- a/Vendor/XcodeCoverage/cleancov +++ b/Vendor/XcodeCoverage/cleancov @@ -5,6 +5,7 @@ # Source: https://github.com/jonreid/XcodeCoverage # -source envcov.sh +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +source ${DIR}/envcov.sh -"${LCOV}" --zerocounters -d "${OBJ_DIR}" +"${LCOV}" --zerocounters -d "${OBJ_DIR}" \ No newline at end of file diff --git a/Vendor/XcodeCoverage/envcov.sh b/Vendor/XcodeCoverage/envcov.sh index b48d4b7e01..3a7b48efa3 100755 --- a/Vendor/XcodeCoverage/envcov.sh +++ b/Vendor/XcodeCoverage/envcov.sh @@ -4,11 +4,12 @@ # Source: https://github.com/jonreid/XcodeCoverage # -source env.sh +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +source ${DIR}/env.sh # Change the report name if you like: LCOV_INFO=Coverage.info LCOV_PATH=${SRCROOT}/../Vendor/XcodeCoverage/lcov-1.10/bin LCOV=${LCOV_PATH}/lcov -OBJ_DIR=${OBJECT_FILE_DIR_normal}/${CURRENT_ARCH} +OBJ_DIR=${OBJECT_FILE_DIR_normal}/${CURRENT_ARCH} \ No newline at end of file diff --git a/Vendor/XcodeCoverage/exportenv.sh b/Vendor/XcodeCoverage/exportenv.sh index 32455f9f48..bbde8108de 100755 --- a/Vendor/XcodeCoverage/exportenv.sh +++ b/Vendor/XcodeCoverage/exportenv.sh @@ -4,4 +4,5 @@ # Source: https://github.com/jonreid/XcodeCoverage # -export | egrep '( BUILT_PRODUCTS_DIR)|(CURRENT_ARCH)|(OBJECT_FILE_DIR_normal)|(SRCROOT)|(OBJROOT)' > ../Vendor/XcodeCoverage/env.sh +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +export | egrep '( BUILT_PRODUCTS_DIR)|(CURRENT_ARCH)|(OBJECT_FILE_DIR_normal)|(SRCROOT)|(OBJROOT)' > ${DIR}/env.sh \ No newline at end of file diff --git a/Vendor/XcodeCoverage/getcov b/Vendor/XcodeCoverage/getcov index 332aa8c053..e69e9e7ffd 100755 --- a/Vendor/XcodeCoverage/getcov +++ b/Vendor/XcodeCoverage/getcov @@ -5,7 +5,8 @@ # Source: https://github.com/jonreid/XcodeCoverage # -source envcov.sh +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +source ${DIR}/envcov.sh remove_old_report() { @@ -45,4 +46,4 @@ remove_old_report enter_lcov_dir gather_coverage exclude_data -generate_report +generate_report \ No newline at end of file diff --git a/Vendor/XcodeCoverage/lcov-1.10/bin/geninfo b/Vendor/XcodeCoverage/lcov-1.10/bin/geninfo index 9325f9d68c..a553e21347 100755 --- a/Vendor/XcodeCoverage/lcov-1.10/bin/geninfo +++ b/Vendor/XcodeCoverage/lcov-1.10/bin/geninfo @@ -1017,7 +1017,7 @@ sub process_dafile($$) warn("WARNING: GCOV failed for $da_filename!\n"); return; } - die("ERROR: GCOV failed for $da_filename!\n"); + warn("WARNING: GCOV failed for $da_filename!\n"); } # Collect data from resulting .gcov files and create .info file @@ -1861,33 +1861,37 @@ sub read_gcov_file($) sub get_gcov_version() { - local *HANDLE; - my $version_string; - my $result; + local *HANDLE; + my $version_string; + my $result; - open(GCOV_PIPE, "-|", "$gcov_tool -v") - or die("ERROR: cannot retrieve gcov version!\n"); - $version_string = ; - close(GCOV_PIPE); + open(GCOV_PIPE, "-|", "$gcov_tool --version") + or die("ERROR: cannot retrieve gcov version!\n"); + $version_string = ; + close(GCOV_PIPE); - $result = 0; - if ($version_string =~ /(\d+)\.(\d+)(\.(\d+))?/) - { - if (defined($4)) - { - info("Found gcov version: $1.$2.$4\n"); - $result = $1 << 16 | $2 << 8 | $4; - } - else - { - info("Found gcov version: $1.$2\n"); - $result = $1 << 16 | $2 << 8; - } - } - return ($result, $version_string); + $result = 0; + if ($version_string =~ m/LLVM/) + { + info("Found llvm-cov\n"); + $result = 0x40201; + } + elsif ($version_string =~ /(\d+)\.(\d+)(\.(\d+))?/) + { + if (defined($4)) + { + info("Found gcov version: $1.$2.$4\n"); + $result = $1 << 16 | $2 << 8 | $4; + } + else + { + info("Found gcov version: $1.$2\n"); + $result = $1 << 16 | $2 << 8; + } + } + return ($result, $version_string); } - # # info(printf_parameter) # diff --git a/docs/Changelog-template.md b/docs/Changelog-template.md index 5b804fb123..5cc2d0a700 100644 --- a/docs/Changelog-template.md +++ b/docs/Changelog-template.md @@ -1,3 +1,14 @@ +## Version 3.5.5 + +- [NEW] `BITCrashManager`: Added support for adding a binary attachment to crash reports +- [NEW] `BITCrashManager`: Integrated PLCrashReporter 1.2 RC5 (with 2 more fixes) +- [BUGFIX] `BITUpdateManager`: Fixed problem with `checkForUpdate` when `updateSetting` is set to `BITUpdateCheckManually` +- [BUGFIX] `BITAuthenticator`: Fixed keychain warning alert showing app on launch if keychain is locked +- [BUGFIX] `BITAuthenticator`: Fixed a possible assertion problem with auto-authentication (when using custom SDK builds without assertions being disabled) +- [BUGFIX] `BITAuthenticator`: Added user email to crash report for beta builds if BITAuthenticator is set to BITAuthenticatorIdentificationTypeWebAuth +- [BUGFIX] Fixed more analyzer warnings +

+ ## Version 3.5.4 - [BUGFIX] Fix a possible crash before sending the crash report when the selector could not be found diff --git a/docs/Guide-Installation-Setup-Advanced-template.md b/docs/Guide-Installation-Setup-Advanced-template.md index 5b8e1ee2b4..19b54a67b3 100644 --- a/docs/Guide-Installation-Setup-Advanced-template.md +++ b/docs/Guide-Installation-Setup-Advanced-template.md @@ -1,6 +1,6 @@ -## Version 3.5.4 +## Version 3.5.5 -- [Changelog](http://www.hockeyapp.net/help/sdk/ios/3.5.4/docs/docs/Changelog.html) +- [Changelog](http://www.hockeyapp.net/help/sdk/ios/3.5.5/docs/docs/Changelog.html) ## Introduction @@ -116,7 +116,7 @@ This documentation provides integrated help in Xcode for all public APIs and a s 3. Copy the content into ~`/Library/Developer/Shared/Documentation/DocSets` -The documentation is also available via the following URL: [http://hockeyapp.net/help/sdk/ios/3.5.4/](http://hockeyapp.net/help/sdk/ios/3.5.4/) +The documentation is also available via the following URL: [http://hockeyapp.net/help/sdk/ios/3.5.5/](http://hockeyapp.net/help/sdk/ios/3.5.5/) ### Set up with xcconfig diff --git a/docs/Guide-Installation-Setup-template.md b/docs/Guide-Installation-Setup-template.md index 91a7a5e130..68d8356f0c 100644 --- a/docs/Guide-Installation-Setup-template.md +++ b/docs/Guide-Installation-Setup-template.md @@ -1,6 +1,6 @@ -## Version 3.5.4 +## Version 3.5.5 -- [Changelog](http://www.hockeyapp.net/help/sdk/ios/3.5.4/docs/docs/Changelog.html) +- [Changelog](http://www.hockeyapp.net/help/sdk/ios/3.5.5/docs/docs/Changelog.html) ## Introduction @@ -90,9 +90,9 @@ The Mac Desktop Uploader can provide easy uploading of your app versions to Hock This documentation provides integrated help in Xcode for all public APIs and a set of additional tutorials and how-tos. -1. Copy `de.bitstadium.HockeySDK-iOS-3.5.1.docset` into ~`/Library/Developer/Shared/Documentation/DocSets` +1. Copy `de.bitstadium.HockeySDK-iOS-3.5.5.docset` into ~`/Library/Developer/Shared/Documentation/DocSets` -The documentation is also available via the following URL: [http://hockeyapp.net/help/sdk/ios/3.5.4/](http://hockeyapp.net/help/sdk/ios/3.5.4/) +The documentation is also available via the following URL: [http://hockeyapp.net/help/sdk/ios/3.5.5/](http://hockeyapp.net/help/sdk/ios/3.5.5/) ### Set up with xcconfig