@@ -51,7 +51,8 @@ @interface ModulesAnalytics()
5151
5252@property (nonatomic , strong ) NSOperationQueue * analyticsOperationQueue;
5353@property (nonatomic , strong ) CrashOpsController* crashOpsController;
54- @property (nonatomic , strong ) NSString *historyPath;
54+ @property (nonatomic , strong ) NSString *uploadedHistoryPath;
55+ @property (nonatomic , strong ) NSString *sentHistoryPath;
5556
5657@end
5758
@@ -84,7 +85,12 @@ - (instancetype)initWithCoder:(NSCoder *) coder {
8485 return self;
8586}
8687
87- + (NSData *) doSha256 : (NSData *)dataIn {
88+ +(NSString *) encode : (NSString *) original {
89+ NSData *sha256Data = [ModulesAnalytics doSha256: [original dataUsingEncoding: NSUTF8StringEncoding]];
90+ return [sha256Data md5String ];
91+ }
92+
93+ +(NSData *) doSha256 : (NSData *)dataIn {
8894 NSMutableData *macOut = [NSMutableData dataWithLength: CC_SHA256_DIGEST_LENGTH];
8995 unsigned char *result = CC_SHA256 (dataIn.bytes , dataIn.length , macOut.mutableBytes );
9096 CODebugLog ([NSString stringWithCharacters: result length: dataIn.length]);
@@ -98,7 +104,7 @@ +(BOOL) isDebugModeEnabled {
98104
99105+ (void )initiateWithController : (CrashOpsController *) controller {
100106 [ModulesAnalytics shared ].crashOpsController = controller;
101- [ModulesAnalytics aggregateAvailableFrameworks : ^(NSDictionary *binaryImages) {
107+ [ModulesAnalytics aggregateNewAvailableFrameworks : ^(NSDictionary *binaryImages) {
102108 [[[ModulesAnalytics shared ] analyticsOperationQueue ] addOperationWithBlock: ^{
103109 NSMutableArray *binaryImagesArray = [NSMutableArray new ];
104110
@@ -115,6 +121,8 @@ + (void)initiateWithController:(CrashOpsController *) controller {
115121
116122 NSData *sha256Data;
117123 NSFileManager *fileManager = [NSFileManager defaultManager ];
124+
125+
118126 for (NSDictionary *pathAndSize in requestedBinaryImages) {
119127 NSString *path = [pathAndSize[@" name" ] description ];
120128 if (![pathAndSize[@" size" ] isKindOfClass: [NSNumber class ]]) {
@@ -126,7 +134,7 @@ + (void)initiateWithController:(CrashOpsController *) controller {
126134 if ([actualSize isKindOfClass: [NSNumber class ]] && actualSize.integerValue == sizeInBytes) {
127135 NSString *pathAndSizeString = [NSString stringWithFormat: @" %@ +%ld " , path, (long )sizeInBytes];
128136 sha256Data = [ModulesAnalytics doSha256: [pathAndSizeString dataUsingEncoding: NSUTF8StringEncoding]];
129- NSString *uploadRecordPath = [[[ModulesAnalytics shared ] historyPath ] stringByAppendingPathComponent: [sha256Data md5String ]];
137+ NSString *uploadRecordPath = [[[ModulesAnalytics shared ] uploadedHistoryPath ] stringByAppendingPathComponent: [sha256Data md5String ]];
130138
131139 BOOL isDir = YES ;
132140 if (![fileManager fileExistsAtPath: uploadRecordPath isDirectory: &isDir]) {
@@ -135,9 +143,11 @@ + (void)initiateWithController:(CrashOpsController *) controller {
135143 [filteredImages addObject: @{@" name" : path, @" size" :[NSNumber numberWithInteger: sizeInBytes]}];
136144 }
137145 }
146+
147+
148+ CODebugLogArgs (@" Sending requested binary images: %@ " , [filteredImages description ]);
149+
138150 }
139-
140- CODebugLogArgs (@" Sending requested binary images: %@ " , [filteredImages description ]);
141151
142152 if ([filteredImages count ]) {
143153 [[ModulesAnalytics shared ] uploadBinaryImages: filteredImages callback: ^(NSArray *responses) {
@@ -155,7 +165,7 @@ + (void)initiateWithController:(CrashOpsController *) controller {
155165
156166 if (wasRequestSuccessful) {
157167 NSData *sha256Data = hashes[idx];
158- NSString *uploadRecordPath = [[[ModulesAnalytics shared ] historyPath ] stringByAppendingPathComponent: [sha256Data md5String ]];
168+ NSString *uploadRecordPath = [[[ModulesAnalytics shared ] uploadedHistoryPath ] stringByAppendingPathComponent: [sha256Data md5String ]];
159169
160170 BOOL isDir = YES ;
161171 BOOL isCreated = NO ;
@@ -183,14 +193,21 @@ + (void)initiateWithController:(CrashOpsController *) controller {
183193 }];
184194}
185195
186- + (BOOL ) doesExist : (NSData *) hash {
187- NSString *uploadRecordPath = [[[ModulesAnalytics shared ] historyPath ] stringByAppendingPathComponent: [hash md5String ]];
196+ + (BOOL ) didAlreadySend : (NSString *) encoded {
197+ NSString *sentImageRecordPath = [[[ModulesAnalytics shared ] sentHistoryPath ] stringByAppendingPathComponent: encoded];
198+
199+ BOOL isDir = YES ;
200+ return [[NSFileManager defaultManager ] fileExistsAtPath: sentImageRecordPath isDirectory: &isDir];
201+ }
202+
203+ + (BOOL ) didAlreadyUpload : (NSData *) hash {
204+ NSString *uploadRecordPath = [[[ModulesAnalytics shared ] uploadedHistoryPath ] stringByAppendingPathComponent: [hash md5String ]];
188205
189206 BOOL isDir = YES ;
190207 return [[NSFileManager defaultManager ] fileExistsAtPath: uploadRecordPath isDirectory: &isDir];
191208}
192209
193- +(void ) aggregateAvailableFrameworks : (void (^)(NSDictionary * binaryImages)) completion {
210+ +(void ) aggregateNewAvailableFrameworks : (void (^)(NSDictionary * binaryImages)) completion {
194211 if (!completion) { return ; }
195212
196213 NSFileManager *fileManager = [NSFileManager defaultManager ];
@@ -204,7 +221,14 @@ +(void) aggregateAvailableFrameworks:(void(^)(NSDictionary * binaryImages)) comp
204221 if (!moduleName) continue ;
205222
206223 NSInteger frameworkSize = [fileManager totalSizeOfFolder: framework.bundlePath];
207- binaryImages[framework.resourcePath] = [NSNumber numberWithInteger: frameworkSize];
224+ // Check if it was already sent, before adding
225+ NSString *pathAndSizeString = [NSString stringWithFormat: @" %@ +%ld " , framework.resourcePath, (long ) frameworkSize];
226+ NSString *encoded = [ModulesAnalytics encode: pathAndSizeString];
227+
228+ BOOL isNew = ![self didAlreadySend: encoded];
229+ if (isNew) {
230+ binaryImages[framework.resourcePath] = [NSNumber numberWithInteger: frameworkSize];
231+ }
208232 }
209233
210234 [[NSOperationQueue mainQueue ] addOperationWithBlock: ^{
@@ -231,28 +255,55 @@ + (NSMutableURLRequest *) prepareRequestWithEndpoint:(NSString *) apiEndpoint {
231255}
232256
233257+ (NSMutableURLRequest *) prepareRequestWithEndpoint : (NSString *) apiEndpoint contentType : (NSString *) contentType {
234- // NSString *serverUrlString = [NSString stringWithFormat: @"https://crashops.com/api/%@", apiEndpoint];
235- NSString *serverUrlString = [NSString stringWithFormat: @" https://unity1.zcps.co/crashops/%@ " , apiEndpoint];
236-
258+ NSString *serverUrlString = [NSString stringWithFormat: @" https://crashops.com/api/%@ " , apiEndpoint];
259+
237260 NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL: [NSURL URLWithString: serverUrlString]];
238-
261+
239262 [request setCachePolicy: NSURLRequestReloadIgnoringLocalCacheData];
240263 [request setHTTPShouldHandleCookies: NO ];
241264 [request setTimeoutInterval: 60 ];
242265 [request setHTTPMethod: @" POST" ];
243266 [request setValue: @" gzip" forHTTPHeaderField: @" Accept-Encoding" ];
244-
267+
245268 [request setValue: contentType forHTTPHeaderField: @" Content-Type" ];
246-
269+
247270 return request;
248271}
249272
250- -(NSString *) historyPath {
251- if (_historyPath != nil ) {
252- return _historyPath;
273+ -(NSString *) sentHistoryPath {
274+ if (_sentHistoryPath != nil ) {
275+ return _sentHistoryPath;
276+ }
277+
278+ NSString *path = [crashOpsController.crashOpsLibraryPath stringByAppendingPathComponent: @" Sent" ];
279+
280+ BOOL isDir = YES ;
281+ BOOL isCreated = NO ;
282+
283+ NSFileManager *fileManager = [NSFileManager defaultManager ];
284+ if (![fileManager fileExistsAtPath: path isDirectory: &isDir]) {
285+ if (![fileManager createDirectoryAtPath: path withIntermediateDirectories: YES attributes: nil error: NULL ]) {
286+ CODebugLogArgs (@" Error: Failed to create folder %@ " , path);
287+ } else {
288+ isCreated = YES ;
289+ }
290+ } else {
291+ isCreated = YES ;
292+ }
293+
294+ if (isCreated) {
295+ _sentHistoryPath = path;
296+ }
297+
298+ return _sentHistoryPath;
299+ }
300+
301+ -(NSString *) uploadedHistoryPath {
302+ if (_uploadedHistoryPath != nil ) {
303+ return _uploadedHistoryPath;
253304 }
254305
255- NSString *path = [crashOpsController.crashOpsLibraryPath stringByAppendingPathComponent: @" HistoryPath " ];
306+ NSString *path = [crashOpsController.crashOpsLibraryPath stringByAppendingPathComponent: @" Uploaded " ];
256307
257308 BOOL isDir = YES ;
258309 BOOL isCreated = NO ;
@@ -269,10 +320,10 @@ -(NSString *) historyPath {
269320 }
270321
271322 if (isCreated) {
272- _historyPath = path;
323+ _uploadedHistoryPath = path;
273324 }
274325
275- return _historyPath ;
326+ return _uploadedHistoryPath ;
276327}
277328
278329-(void ) sendBinaryInfo : (NSArray *) binaryImages callback : (void (^)(NSArray * requestedBinaryImages)) callback {
@@ -310,6 +361,30 @@ -(void) sendBinaryInfo:(NSArray *) binaryImages callback: (void(^)(NSArray * req
310361 requestedBinaryImages = @[];
311362 }
312363
364+ NSFileManager *fileManager = [NSFileManager defaultManager ];
365+
366+ for (NSDictionary *sentDetails in binaryImages) {
367+ NSString *path = sentDetails[@" name" ];
368+ NSInteger frameworkSize = [sentDetails[@" size" ] integerValue ];
369+ NSString *pathAndSizeString = [NSString stringWithFormat: @" %@ +%ld " , path, (long ) frameworkSize];
370+
371+ BOOL isDir = YES ;
372+ BOOL isCreated = NO ;
373+
374+ NSString *encoded = [ModulesAnalytics encode: pathAndSizeString];
375+ NSString *sentRecordPath = [[[ModulesAnalytics shared ] sentHistoryPath ] stringByAppendingPathComponent: encoded];
376+
377+ if (![fileManager fileExistsAtPath: sentRecordPath isDirectory: &isDir]) {
378+ if (![fileManager createDirectoryAtPath: sentRecordPath withIntermediateDirectories: YES attributes: nil error: NULL ]) {
379+ CODebugLogArgs (@" Error in saving sent record: Failed to create folder %@ " , sentRecordPath);
380+ } else {
381+ isCreated = YES ;
382+ }
383+ } else {
384+ isCreated = YES ;
385+ }
386+ }
387+
313388 callback (requestedBinaryImages);
314389 } else {
315390 callback (@[]);
@@ -387,9 +462,8 @@ -(void) uploadRequestMultipartDataWithFiles:(NSArray *)filePaths andParameters:
387462 NSString *boundary = [ModulesAnalytics generateBoundaryString ];
388463
389464 NSString *apiEndpoint = @" binaryImages/upload" ;
390-
391- // NSString *serverUrlString = [NSString stringWithFormat: @"https://crashops.com/api/%@", apiEndpoint];
392- NSString *serverUrlString = [NSString stringWithFormat: @" https://unity1.zcps.co/crashops/%@ " , apiEndpoint];
465+ NSString *serverUrlString = [NSString stringWithFormat: @" https://crashops.com/api/%@ " , apiEndpoint];
466+
393467 NSURL *url = [NSURL URLWithString: serverUrlString];
394468
395469 // configure the request
0 commit comments