mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-08-29 09:01:05 +00:00
Send crash reports via NSURLSession when available
This commit is contained in:
parent
5305474388
commit
3094c0524c
@ -1464,23 +1464,10 @@ static void uncaught_cxx_exception_handler(const BITCrashUncaughtCXXExceptionInf
|
||||
|
||||
#pragma mark - Networking
|
||||
|
||||
- (NSURLRequest *)requestWithXML:(NSString*)xml attachment:(BITHockeyAttachment *)attachment {
|
||||
NSString *postCrashPath = [NSString stringWithFormat:@"api/2/apps/%@/crashes", self.encodedAppIdentifier];
|
||||
|
||||
NSMutableURLRequest *request = [self.hockeyAppClient requestWithMethod:@"POST"
|
||||
path:postCrashPath
|
||||
parameters:nil];
|
||||
|
||||
[request setCachePolicy: NSURLRequestReloadIgnoringLocalCacheData];
|
||||
[request setValue:@"HockeySDK/iOS" forHTTPHeaderField:@"User-Agent"];
|
||||
[request setValue:@"gzip" forHTTPHeaderField:@"Accept-Encoding"];
|
||||
|
||||
NSString *boundary = @"----FOO";
|
||||
NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary];
|
||||
[request setValue:contentType forHTTPHeaderField:@"Content-type"];
|
||||
|
||||
- (NSData *)postBodyWithXML:(NSString *)xml attachment:(BITHockeyAttachment *)attachment boundary:(NSString *)boundary {
|
||||
NSMutableData *postBody = [NSMutableData data];
|
||||
|
||||
// [postBody appendData:[[NSString stringWithFormat:@"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
|
||||
[postBody appendData:[BITHockeyAppClient dataWithPostValue:BITHOCKEY_NAME
|
||||
forKey:@"sdk"
|
||||
boundary:boundary]];
|
||||
@ -1513,11 +1500,88 @@ static void uncaught_cxx_exception_handler(const BITCrashUncaughtCXXExceptionInf
|
||||
|
||||
[postBody appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
|
||||
|
||||
[request setHTTPBody:postBody];
|
||||
return postBody;
|
||||
}
|
||||
|
||||
- (NSMutableURLRequest *)requestWithBoundary:(NSString *)boundary {
|
||||
NSString *postCrashPath = [NSString stringWithFormat:@"api/2/apps/%@/crashes", self.encodedAppIdentifier];
|
||||
|
||||
NSMutableURLRequest *request = [self.hockeyAppClient requestWithMethod:@"POST"
|
||||
path:postCrashPath
|
||||
parameters:nil];
|
||||
|
||||
[request setCachePolicy: NSURLRequestReloadIgnoringLocalCacheData];
|
||||
[request setValue:@"HockeySDK/iOS" forHTTPHeaderField:@"User-Agent"];
|
||||
[request setValue:@"gzip" forHTTPHeaderField:@"Accept-Encoding"];
|
||||
|
||||
NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary];
|
||||
[request setValue:contentType forHTTPHeaderField:@"Content-type"];
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
// process upload response
|
||||
- (void)processUploadResultWithFilename:(NSString *)filename responseData:(NSData *)responseData statusCode:(NSInteger)statusCode error:(NSError *)error {
|
||||
__block NSError *theError = error;
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
_sendingInProgress = NO;
|
||||
|
||||
if (nil == theError) {
|
||||
if (nil == responseData || [responseData length] == 0) {
|
||||
theError = [NSError errorWithDomain:kBITCrashErrorDomain
|
||||
code:BITCrashAPIReceivedEmptyResponse
|
||||
userInfo:@{
|
||||
NSLocalizedDescriptionKey: @"Sending failed with an empty response!"
|
||||
}
|
||||
];
|
||||
} else if (statusCode >= 200 && statusCode < 400) {
|
||||
[self cleanCrashReportWithFilename:filename];
|
||||
|
||||
// HockeyApp uses PList XML format
|
||||
NSMutableDictionary *response = [NSPropertyListSerialization propertyListWithData:responseData
|
||||
options:NSPropertyListMutableContainersAndLeaves
|
||||
format:nil
|
||||
error:&theError];
|
||||
BITHockeyLog(@"INFO: Received API response: %@", response);
|
||||
|
||||
if (self.delegate != nil &&
|
||||
[self.delegate respondsToSelector:@selector(crashManagerDidFinishSendingCrashReport:)]) {
|
||||
[self.delegate crashManagerDidFinishSendingCrashReport:self];
|
||||
}
|
||||
|
||||
// only if sending the crash report went successfully, continue with the next one (if there are more)
|
||||
[self sendNextCrashReport];
|
||||
} else if (statusCode == 400) {
|
||||
[self cleanCrashReportWithFilename:filename];
|
||||
|
||||
theError = [NSError errorWithDomain:kBITCrashErrorDomain
|
||||
code:BITCrashAPIAppVersionRejected
|
||||
userInfo:@{
|
||||
NSLocalizedDescriptionKey: @"The server rejected receiving crash reports for this app version!"
|
||||
}
|
||||
];
|
||||
} else {
|
||||
theError = [NSError errorWithDomain:kBITCrashErrorDomain
|
||||
code:BITCrashAPIErrorWithStatusCode
|
||||
userInfo:@{
|
||||
NSLocalizedDescriptionKey: [NSString stringWithFormat:@"Sending failed with status code: %li", (long)statusCode]
|
||||
}
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
if (theError) {
|
||||
if (self.delegate != nil &&
|
||||
[self.delegate respondsToSelector:@selector(crashManager:didFailWithError:)]) {
|
||||
[self.delegate crashManager:self didFailWithError:theError];
|
||||
}
|
||||
|
||||
BITHockeyLog(@"ERROR: %@", [theError localizedDescription]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the XML data to the server
|
||||
*
|
||||
@ -1526,81 +1590,51 @@ static void uncaught_cxx_exception_handler(const BITCrashUncaughtCXXExceptionInf
|
||||
* @param xml The XML data that needs to be send to the server
|
||||
*/
|
||||
- (void)sendCrashReportWithFilename:(NSString *)filename xml:(NSString*)xml attachment:(BITHockeyAttachment *)attachment {
|
||||
|
||||
NSURLRequest* request = [self requestWithXML:xml attachment:attachment];
|
||||
|
||||
__weak typeof (self) weakSelf = self;
|
||||
BITHTTPOperation *operation = [self.hockeyAppClient
|
||||
operationWithURLRequest:request
|
||||
completion:^(BITHTTPOperation *operation, NSData* responseData, NSError *error) {
|
||||
typeof (self) strongSelf = weakSelf;
|
||||
|
||||
_sendingInProgress = NO;
|
||||
|
||||
NSInteger statusCode = [operation.response statusCode];
|
||||
id nsurlsessionClass = NSClassFromString(@"NSURLSessionUploadTask");
|
||||
if (nsurlsessionClass && !bit_isRunningInAppExtension()) {
|
||||
NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
|
||||
NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfiguration];
|
||||
|
||||
NSURLRequest *request = [self requestWithBoundary:kBITHockeyAppClientBoundary];
|
||||
NSData *data = [self postBodyWithXML:xml attachment:attachment boundary:kBITHockeyAppClientBoundary];
|
||||
|
||||
if (nil == error) {
|
||||
if (nil == responseData || [responseData length] == 0) {
|
||||
error = [NSError errorWithDomain:kBITCrashErrorDomain
|
||||
code:BITCrashAPIReceivedEmptyResponse
|
||||
userInfo:@{
|
||||
NSLocalizedDescriptionKey: @"Sending failed with an empty response!"
|
||||
}
|
||||
];
|
||||
} else if (statusCode >= 200 && statusCode < 400) {
|
||||
[strongSelf cleanCrashReportWithFilename:filename];
|
||||
|
||||
// HockeyApp uses PList XML format
|
||||
NSMutableDictionary *response = [NSPropertyListSerialization propertyListWithData:responseData
|
||||
options:NSPropertyListMutableContainersAndLeaves
|
||||
format:nil
|
||||
error:&error];
|
||||
BITHockeyLog(@"INFO: Received API response: %@", response);
|
||||
|
||||
if (strongSelf.delegate != nil &&
|
||||
[strongSelf.delegate respondsToSelector:@selector(crashManagerDidFinishSendingCrashReport:)]) {
|
||||
[strongSelf.delegate crashManagerDidFinishSendingCrashReport:self];
|
||||
}
|
||||
|
||||
// only if sending the crash report went successfully, continue with the next one (if there are more)
|
||||
[strongSelf sendNextCrashReport];
|
||||
} else if (statusCode == 400) {
|
||||
[strongSelf cleanCrashReportWithFilename:filename];
|
||||
|
||||
error = [NSError errorWithDomain:kBITCrashErrorDomain
|
||||
code:BITCrashAPIAppVersionRejected
|
||||
userInfo:@{
|
||||
NSLocalizedDescriptionKey: @"The server rejected receiving crash reports for this app version!"
|
||||
}
|
||||
];
|
||||
} else {
|
||||
error = [NSError errorWithDomain:kBITCrashErrorDomain
|
||||
code:BITCrashAPIErrorWithStatusCode
|
||||
userInfo:@{
|
||||
NSLocalizedDescriptionKey: [NSString stringWithFormat:@"Sending failed with status code: %li", (long)statusCode]
|
||||
}
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
if (error) {
|
||||
if (strongSelf.delegate != nil &&
|
||||
[strongSelf.delegate respondsToSelector:@selector(crashManager:didFailWithError:)]) {
|
||||
[strongSelf.delegate crashManager:self didFailWithError:error];
|
||||
}
|
||||
__weak typeof (self) weakSelf = self;
|
||||
NSURLSessionUploadTask *uploadTask = [session uploadTaskWithRequest:request
|
||||
fromData:data
|
||||
completionHandler:^(NSData *responseData, NSURLResponse *response, NSError *error) {
|
||||
typeof (self) strongSelf = weakSelf;
|
||||
|
||||
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*) response;
|
||||
NSInteger statusCode = [httpResponse statusCode];
|
||||
[strongSelf processUploadResultWithFilename:filename responseData:responseData statusCode:statusCode error:error];
|
||||
}];
|
||||
|
||||
// 5
|
||||
[uploadTask resume];
|
||||
} else {
|
||||
NSMutableURLRequest *request = [self requestWithBoundary:kBITHockeyAppClientBoundary];
|
||||
|
||||
NSData *postBody = [self postBodyWithXML:xml attachment:attachment boundary:kBITHockeyAppClientBoundary];
|
||||
[request setHTTPBody:postBody];
|
||||
|
||||
__weak typeof (self) weakSelf = self;
|
||||
BITHTTPOperation *operation = [self.hockeyAppClient
|
||||
operationWithURLRequest:request
|
||||
completion:^(BITHTTPOperation *operation, NSData* responseData, NSError *error) {
|
||||
typeof (self) strongSelf = weakSelf;
|
||||
|
||||
BITHockeyLog(@"ERROR: %@", [error localizedDescription]);
|
||||
}
|
||||
|
||||
}];
|
||||
NSInteger statusCode = [operation.response statusCode];
|
||||
[strongSelf processUploadResultWithFilename:filename responseData:responseData statusCode:statusCode error:error];
|
||||
}];
|
||||
|
||||
[self.hockeyAppClient enqeueHTTPOperation:operation];
|
||||
}
|
||||
|
||||
if (self.delegate != nil && [self.delegate respondsToSelector:@selector(crashManagerWillSendCrashReport:)]) {
|
||||
[self.delegate crashManagerWillSendCrashReport:self];
|
||||
}
|
||||
|
||||
BITHockeyLog(@"INFO: Sending crash reports started.");
|
||||
|
||||
[self.hockeyAppClient enqeueHTTPOperation:operation];
|
||||
}
|
||||
|
||||
- (NSTimeInterval)timeintervalCrashInLastSessionOccured {
|
||||
|
@ -30,6 +30,8 @@
|
||||
|
||||
#import "BITHTTPOperation.h" //needed for typedef
|
||||
|
||||
extern NSString * const kBITHockeyAppClientBoundary;
|
||||
|
||||
/**
|
||||
* Generic Hockey API client
|
||||
*/
|
||||
|
@ -27,6 +27,8 @@
|
||||
*/
|
||||
#import "BITHockeyAppClient.h"
|
||||
|
||||
NSString * const kBITHockeyAppClientBoundary = @"----FOO";
|
||||
|
||||
@implementation BITHockeyAppClient
|
||||
- (void)dealloc {
|
||||
[self cancelOperationsWithPath:nil method:nil];
|
||||
@ -66,16 +68,15 @@
|
||||
} else {
|
||||
//TODO: this is crap. Boundary must be the same as the one in appendData
|
||||
//unify this!
|
||||
NSString *boundary = @"----FOO";
|
||||
NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary];
|
||||
NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", kBITHockeyAppClientBoundary];
|
||||
[request setValue:contentType forHTTPHeaderField:@"Content-type"];
|
||||
|
||||
NSMutableData *postBody = [NSMutableData data];
|
||||
[params enumerateKeysAndObjectsUsingBlock:^(NSString *key, NSString *value, BOOL *stop) {
|
||||
[postBody appendData:[[self class] dataWithPostValue:value forKey:key boundary:boundary]];
|
||||
[postBody appendData:[[self class] dataWithPostValue:value forKey:key boundary:kBITHockeyAppClientBoundary]];
|
||||
}];
|
||||
|
||||
[postBody appendData:[[NSString stringWithFormat:@"--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
|
||||
[postBody appendData:[[NSString stringWithFormat:@"--%@--\r\n", kBITHockeyAppClientBoundary] dataUsingEncoding:NSUTF8StringEncoding]];
|
||||
|
||||
[request setHTTPBody:postBody];
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user