Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[MC-1563] File downloading #339

Merged
merged 23 commits into from
Jun 25, 2024
Merged

[MC-1563] File downloading #339

merged 23 commits into from
Jun 25, 2024

Conversation

nishant-clevertap
Copy link
Contributor

Added class CTFileDownloadManager and CTFileDownloader to handle file downloading, their callback and expiry handling for all file types together.

- Added changes for CS InApps to use the new CTFileDownloader class for image preloading.
- Removed previous usage of CTInAppImagePrefetchManager class for image preloading.
Copy link
Contributor

@nzagorchev nzagorchev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Use custom timeout for the download requests. NSURLSession shared session uses default timeouts which are too long.
  2. Handle status code of the download request. Accept only 200 OK. In case of 404 or 500 status code, the error is nil and the code will continue to write the data from the response.
  3. Completion handler is set as nullable but there is no nil check.
  4. Completion handler is not called at all if URLs are empty array.
  5. UserDefaults data is not migrated to new keys and removed.
  6. Get methods should follow convention and not have get in name.
  7. Unit tests are not using the completion blocks but arbitrary dispatch time thus taking too much time to complete.

The active and inactive assets logic is correct and provides information where an asset is used from. However, this brings too much complexity for our use case. It is better to now use expiry timestamp for each file URL and update this accordingly.

@@ -140,6 +140,10 @@ extern NSString *CLTAP_PROFILE_IDENTITY_KEY;
#define CLTAP_PREFS_CS_INAPP_INACTIVE_ASSETS @"cs_inapp_inactive_assets"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Those are no longer used


-(void)downloadSingleFile:(NSURL *)url
completed:(void(^)(BOOL success))completedBlock {
NSURLSession *session = [NSURLSession sharedSession];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Configure the session timeout.

NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDownloadTask *downloadTask = [session downloadTaskWithURL:url
completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) {
if (error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check the response code to be 200 OK, otherwise call the completion and return.


// Save the file to a desired location
NSString *filePath = [self.documentsDirectory stringByAppendingPathComponent:[response suggestedFilename]];
[fileData writeToFile:filePath atomically:YES];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is more efficient to use [fileManager moveItemAtURL:location toURL:destinationURL error:&fileError];


- (void)deleteSingleFile:(NSURL *)url
completed:(void(^)(BOOL success))completedBlock {
NSString *filePath = [self.documentsDirectory stringByAppendingPathComponent:[url lastPathComponent]];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Validate the url. Otherwise, if there is an edge case and it is invalid, it will delete the documents folder.

// NSLog(@"All files downloaded with status: %@", status);
}];

dispatch_time_t delay = dispatch_time(DISPATCH_TIME_NOW, 2.0 * NSEC_PER_SEC);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The completionBlock can be used instead of unnecessary wait.


#pragma mark Private methods

- (void)addAllStubs {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Duplicate logic

[CTPreferences putInt:ts forKey:[self storageKeyWithSuffix:CLTAP_FILE_ASSETS_LAST_DELETED_TS]];
}

- (NSArray<NSString *> *)generateFileURLs:(int)count {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Throws an exception if count > 3

- (NSArray<NSURL *> *)generateFileURLs:(int)count {
NSMutableArray *arr = [NSMutableArray new];
for (int i = 0; i < count; i++) {
NSString *urlString = [[NSString alloc] initWithFormat:@"https://clevertap.com/%@.%@",fileURLMatch, fileURLTypes[i]];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Throws exception if count >= 3

#pragma mark Private methods

- (void)addAllStubs {
[HTTPStubs stubRequestsPassingTest:^BOOL(NSURLRequest *request) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No timeout and error testing of the requests.

@nzagorchev
Copy link
Contributor

  • Addressed the requested changes above and added more unit tests.
  • Save files to a directory inside documents (CleverTap_Files)
  • File name is changed to be _. This ensures URLs with equal last components will be written to different files ie. https://site.com/image.png and https://site-1.com/image.png. File name example: 1176188917138815486_ct_test_url_0.png
  • Clear all files method removes all files inside the directory and does not rely on the URLs expiry cache.
  • Added unit tests that mock NSFileManager operations and ensure correct behaviour of download and delete disk operations.

@nzagorchev nzagorchev merged commit 6a94ad3 into develop Jun 25, 2024
1 of 2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants