Skip to content
This repository has been archived by the owner on Feb 19, 2020. It is now read-only.

Commit

Permalink
Merge branch 'release/3.5.5'
Browse files Browse the repository at this point in the history
  • Loading branch information
DerAndereAndi committed Apr 21, 2014
2 parents 42f04ca + d12cc74 commit 97243cd
Show file tree
Hide file tree
Showing 39 changed files with 674 additions and 123 deletions.
27 changes: 15 additions & 12 deletions Classes/BITAuthenticator.m
Original file line number Diff line number Diff line change
Expand Up @@ -108,19 +108,19 @@ - (void)authenticateInstallation {

// 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];
}

Expand Down Expand Up @@ -156,6 +156,10 @@ - (BOOL) needsValidation {
}

- (void)alertOnFailureStoringTokenInKeychain {
if ([[UIApplication sharedApplication] applicationState] != UIApplicationStateActive) {
return;
}

UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:nil
message:BITHockeyLocalizedString(@"HockeyAuthenticationViewControllerStorageError")
delegate:self
Expand Down Expand Up @@ -607,7 +611,6 @@ - (BOOL) handleOpenURL:(NSURL *) url
case BITAuthenticatorIdentificationTypeHockeyAppEmail:
case BITAuthenticatorIdentificationTypeAnonymous:
case BITAuthenticatorIdentificationTypeHockeyAppUser:
NSAssert(NO, @"Should only be called for Device and WebAuth identificationType");
return NO;
}

Expand Down
66 changes: 66 additions & 0 deletions Classes/BITCrashAttachment.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* Author: Andreas Linde <mail@andreaslinde.de>
*
* 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 <Foundation/Foundation.h>

/**
* Provides support to add binary attachments to crash reports
*
* This is used by `[BITCrashManagerDelegate attachmentForCrashManager:]`
*/
@interface BITCrashAttachment : NSObject<NSCoding>

/**
* 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
64 changes: 64 additions & 0 deletions Classes/BITCrashAttachment.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* Author: Andreas Linde <mail@andreaslinde.de>
*
* 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
110 changes: 101 additions & 9 deletions Classes/BITCrashManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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";

Expand Down Expand Up @@ -215,6 +222,7 @@ - (void)cleanCrashReports {

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];
Expand All @@ -228,9 +236,57 @@ - (void)cleanCrashReports {
[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.
*
Expand Down Expand Up @@ -357,7 +413,8 @@ - (NSString *)userEmailForCrashReport {
// 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;
Expand Down Expand Up @@ -488,6 +545,14 @@ - (void) handleCrashReport {
}
[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];
Expand Down Expand Up @@ -548,6 +613,7 @@ - (BOOL)hasPendingCrashReport {
![file hasSuffix:@".DS_Store"] &&
![file hasSuffix:@".analyzer"] &&
![file hasSuffix:@".plist"] &&
![file hasSuffix:@".data"] &&
![file hasSuffix:@".meta"]) {
[_crashFiles addObject:[_crashesDir stringByAppendingPathComponent: file]];
}
Expand Down Expand Up @@ -746,6 +812,7 @@ - (void)sendCrashReports {
NSError *error = NULL;

NSMutableString *crashes = nil;
NSMutableArray *attachments = [NSMutableArray array];
_crashIdenticalCurrentVersion = NO;

for (NSUInteger i=0; i < [_crashFiles count]; i++) {
Expand All @@ -760,6 +827,7 @@ - (void)sendCrashReports {
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]];
Expand Down Expand Up @@ -804,6 +872,13 @@ - (void)sendCrashReports {
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);
}
Expand Down Expand Up @@ -834,6 +909,7 @@ - (void)sendCrashReports {
} 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]];
Expand All @@ -846,7 +922,7 @@ - (void)sendCrashReports {

if (crashes != nil) {
BITHockeyLog(@"INFO: Sending crash reports:\n%@", crashes);
[self postXML:[NSString stringWithFormat:@"<crashes>%@</crashes>", crashes]];
[self postXML:[NSString stringWithFormat:@"<crashes>%@</crashes>", crashes] attachments:attachments];
}
}

Expand Down Expand Up @@ -894,7 +970,7 @@ - (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)
*
* @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";

Expand All @@ -916,12 +992,28 @@ - (void)postXML:(NSString*)xml {
[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;
Expand Down
Loading

0 comments on commit 97243cd

Please sign in to comment.