mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-11-28 19:05:49 +00:00
Add support for binary attachments to crash reports
This commit is contained in:
parent
ce9014f111
commit
1068bb119c
66
Classes/BITCrashAttachment.h
Normal file
66
Classes/BITCrashAttachment.h
Normal file
@ -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
Classes/BITCrashAttachment.m
Normal file
64
Classes/BITCrashAttachment.m
Normal file
@ -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
|
||||
@ -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.
|
||||
*
|
||||
@ -489,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];
|
||||
@ -549,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]];
|
||||
}
|
||||
@ -747,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++) {
|
||||
@ -761,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]];
|
||||
@ -805,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);
|
||||
}
|
||||
@ -835,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]];
|
||||
@ -847,7 +922,7 @@ NSString *const kBITCrashManagerStatus = @"BITCrashManagerStatus";
|
||||
|
||||
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];
|
||||
}
|
||||
}
|
||||
|
||||
@ -895,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";
|
||||
|
||||
@ -917,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;
|
||||
|
||||
@ -29,6 +29,7 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -37,6 +37,7 @@
|
||||
|
||||
#if HOCKEYSDK_FEATURE_CRASH_REPORTER
|
||||
#import "BITCrashManager.h"
|
||||
#import "BITCrashAttachment.h"
|
||||
#import "BITCrashManagerDelegate.h"
|
||||
#endif /* HOCKEYSDK_FEATURE_CRASH_REPORTER */
|
||||
|
||||
|
||||
@ -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 */; };
|
||||
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, ); }; };
|
||||
@ -283,6 +285,8 @@
|
||||
1EAF20A6162DC0F600957B1D /* feedbackActiviy.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = feedbackActiviy.png; sourceTree = "<group>"; };
|
||||
1EAF20A7162DC0F600957B1D /* feedbackActiviy@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "feedbackActiviy@2x.png"; sourceTree = "<group>"; };
|
||||
1EB52FC3167B73D400C801D5 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/HockeySDK.strings; sourceTree = "<group>"; };
|
||||
1ED570C518BF878C00AB3350 /* BITCrashAttachment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BITCrashAttachment.h; sourceTree = "<group>"; };
|
||||
1ED570C618BF878C00AB3350 /* BITCrashAttachment.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BITCrashAttachment.m; sourceTree = "<group>"; };
|
||||
1EDA60CF15C2C1450032D10B /* HockeySDK-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "HockeySDK-Info.plist"; sourceTree = "<group>"; };
|
||||
1EF95CA4162CB036000AE3AD /* BITFeedbackActivity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BITFeedbackActivity.h; sourceTree = "<group>"; };
|
||||
1EF95CA5162CB036000AE3AD /* BITFeedbackActivity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BITFeedbackActivity.m; sourceTree = "<group>"; };
|
||||
@ -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 */,
|
||||
);
|
||||
@ -633,6 +639,7 @@
|
||||
1E59559B15B6FDA500A03429 /* HockeySDK.h in Headers */,
|
||||
1E59559A15B6FDA500A03429 /* BITHockeyManager.h in Headers */,
|
||||
1E5955FD15B7877B00A03429 /* BITHockeyManagerDelegate.h in Headers */,
|
||||
1ED570C718BF878C00AB3350 /* BITCrashAttachment.h in Headers */,
|
||||
1E754E5C1621FBB70070AB92 /* BITCrashManager.h in Headers */,
|
||||
1E754E5E1621FBB70070AB92 /* BITCrashManagerDelegate.h in Headers */,
|
||||
1E49A4731612226D00463151 /* BITUpdateManager.h in Headers */,
|
||||
@ -876,6 +883,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 */,
|
||||
|
||||
@ -201,6 +201,7 @@
|
||||
[_sut handleCrashReport];
|
||||
|
||||
[verifyCount(delegateMock, times(1)) applicationLogForCrashManager:_sut];
|
||||
[verifyCount(delegateMock, times(1)) attachmentForCrashManager:_sut];
|
||||
|
||||
// we should have now 1 pending crash report
|
||||
assertThatBool([_sut hasPendingCrashReport], equalToBool(YES));
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user