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

Uploading files when the app is teminated state #5481

Open
ecr334 opened this issue Dec 19, 2024 · 7 comments
Open

Uploading files when the app is teminated state #5481

ecr334 opened this issue Dec 19, 2024 · 7 comments
Labels
question General question s3 Issues related to S3

Comments

@ecr334
Copy link

ecr334 commented Dec 19, 2024

State your question
Hi, this question has been discussed many times before, but I faced a situation when dropbox mobile app performs file upload when the app is in terminated state (completely manually closed by the user from the application manager), maybe there is some solution that I did not notice in AWS S3, so that it is also possible to upload created tasks to upload when the app is closed manually ?

I tested dropbox application in such a case:

  1. selected 50 files (photos and videos) for uploading
  2. I waited for the first objects to start uploading.
  3. I closed the application manually through the dispatcher.
  4. opened dropbox desktop application and the website
  5. after a while all 50 files appeared in my account.
    all this time after the 3rd point I didn't open dropbox ios app

I need to achieve the same result with AWS S3 TransferUtility uploading

Which AWS Services are you utilizing?
AWSS3 iOS
Provide code snippets (if applicable)

let credentials = AWSBasicSessionCredentialsProvider(accessKey: accessKey,
                                                             secretKey: secretKey,
                                                             sessionToken: sessionToken)
        guard let configuration = AWSServiceConfiguration(region: .EUCentral1,
                                                          credentialsProvider: credentials)
        else {
            print(#function, #line); return
        }
        configuration.timeoutIntervalForRequest = 300
        configuration.timeoutIntervalForResource = 300
        
        let transferUtilityConfiguration = AWSS3TransferUtilityConfiguration()
        transferUtilityConfiguration.retryLimit = 10
        
        try await AWSS3TransferUtility.register(with: configuration,
                                                transferUtilityConfiguration: transferUtilityConfiguration,
                                                forKey: uploadingUUID)

 transferUtility = AWSS3TransferUtility.s3TransferUtility(forKey: uploadingUUID)
transferUtility.uploadUsingMultiPart(data: self.data,
                                             bucket: self.bucket,
                                             key: self.key,
                                             contentType: self.contentType,
                                             expression: self.expression,
                                             completionHandler: self.completionHandler)
        .continueWith { [weak self] (task) -> Any? in
            guard let self else { return }
            guard task.error == nil else {
                // debug print
                return
            }
            return nil
        }

Environment(please complete the following information):

  • SDK Version: 2.36.3
  • Dependency Manager: SPM
  • Swift Version : 5.0

Device Information (please complete the following information):

  • Device: iPhone 14 pro max
  • iOS Version: iOS 18.2
  • Specific to simulators:

If you need help with understanding how to implement something in particular then we suggest that you first look into our developer guide. You can also simplify your process of creating an application, as well as the associated backend setup by using the Amplify CLI.

@github-actions github-actions bot added pending-triage Issue is pending triage pending-maintainer-response Issue is pending response from an Amplify team member labels Dec 19, 2024
@ruisebas ruisebas added question General question s3 Issues related to S3 and removed pending-triage Issue is pending triage labels Dec 19, 2024
@ruisebas
Copy link
Member

Hi @ecr334, thanks for reaching out.

When an application is terminated by the user (i.e. they remove it from the App Switcher by swiping up), iOS is expected to terminate any background transfer. Having said that, we have no control on whether it actually does, or when it does it.

As a developer, there are some ways you can attempt to mitigate this, for example with a combination of Background Pushes, Background Sessions and/or Background Tasks. However, reliably achieving it using the TransferUtility might be tricky, as you'd probably need a tighter control of the involved instances.

Having said that, consider that a user manually terminating the app by removing it from the App Switcher typically indicates that they do not wish the application to keep running, even in the background.

@github-actions github-actions bot removed the pending-maintainer-response Issue is pending response from an Amplify team member label Dec 19, 2024
@ecr334
Copy link
Author

ecr334 commented Dec 20, 2024

@ruisebas Thanks for the quick response, I understand correctly that I don't need to manually initialize background sessions for TrasnferUtility instance ? everything is already working “under the hood” ?

@github-actions github-actions bot added the pending-maintainer-response Issue is pending response from an Amplify team member label Dec 20, 2024
@ruisebas
Copy link
Member

Yes, the AWSS3TransferUtility already creates background sessions and handles background transfers automatically, including resuming them when the app is reopened, if they were interrupted for some reason.

Depending of your use case, you might need to take care of some things. Please check the Background Transfers section in our documentation.

@github-actions github-actions bot removed the pending-maintainer-response Issue is pending response from an Amplify team member label Dec 20, 2024
@ecr334
Copy link
Author

ecr334 commented Dec 23, 2024

@ruisebas I am loading an array of photos, if data has been loaded in the background, how can I find out how many photos have been loaded before I refresh the progress bar? After a reboot, is there any method that checks the AWSS3TransferUtility for objects that have been previously loaded and skips them so that they are not loaded again? I have the work with the progress bar and start of loading is realized in an array loop, that is, it starts loading again every time and if the object has in the local base (already loaded) it skips, but if the loading was in the background, in the local base it will not update to the status of already loaded, how can I catch this moment ?

@github-actions github-actions bot added the pending-maintainer-response Issue is pending response from an Amplify team member label Dec 23, 2024
@ruisebas
Copy link
Member

Have you checked Managing Transfers When an App Restarts?
Following those instructions you'll be able to monitor resumed transfers and correctly report the appropriate progress.

@github-actions github-actions bot removed the pending-maintainer-response Issue is pending response from an Amplify team member label Dec 23, 2024
@ecr334
Copy link
Author

ecr334 commented Dec 24, 2024

@ruisebas , Yes, I have studied these methods, but I configure TransferUtility instance using configuration with accessKey, secretKey, sessionToken.
each time with different data before uploading:

let credentials = AWSBasicSessionCredentialsProvider(accessKey: accessKey,
                                                             secretKey: secretKey,
                                                             sessionToken: sessionToken)
        guard let configuration = AWSServiceConfiguration(region: .EUCentral1,
                                                          credentialsProvider: credentials)
        else {
            print(#function, #line); return
        }
        configuration.timeoutIntervalForRequest = 300
        configuration.timeoutIntervalForResource = 300
        
        let transferUtilityConfiguration = AWSS3TransferUtilityConfiguration()
        transferUtilityConfiguration.retryLimit = 10
        transferUtilityConfiguration.multiPartConcurrencyLimit = 5
        
        try await AWSS3TransferUtility.register(with: configuration,
                                                transferUtilityConfiguration: transferUtilityConfiguration,
                                                forKey: uploadingUUID)

        self.transferUtility = AWSS3TransferUtility.s3TransferUtility(forKey: uploadingUUID)

accordingly when initializing in AppDelegate.swift on application restart

 
        AWSS3TransferUtility.default(completionHandler: { error in
            if let error = error {
                print("Error: \{(error)")
                return
            }
// processing
        })

I got an error, crashing

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'The service configuration is `nil`. You need to configure `Info.plist` or set `defaultServiceConfiguration` before using this method.'
*** First throw call stack:
(0x193d395ec 0x1912b5244 0x101bc4134 0x10197a578 0x10197c100 0x101bc3ecc 0x104439344 0x104439c6c 0x1987b3a78 0x1969a7aa0 0x1969a4d64 0x1967c664c 0x1969781d4 0x196978104 0x196978104 0x19691a758 0x196540e64 0x1986d4660 0x1986d4590 0x1986d4474 0x104362444 0x104363230 0x1b9fa8de8)
libc++abi: terminating due to uncaught exception of type NSException

Since I have the accessToken/secretToken/secretKey data updated from our server every time, I can't assign it in the .json config file

@github-actions github-actions bot added the pending-maintainer-response Issue is pending response from an Amplify team member label Dec 24, 2024
@ruisebas
Copy link
Member

If you create and register your own AWSS3TransferUtility instance, then you should not use the AWSS3TransferUtility.default one.

Instead, you have to re-register the one you used before and call enumerateToAssign after:

try await AWSS3TransferUtility.register(with: 
    configuration,
    transferUtilityConfiguration: transferUtilityConfiguration,
    forKey: uploadingUUID
)

guard let transferUtility = AWSS3TransferUtility.s3TransferUtility(forKey: transferUtilityKey) else {
    print("Unable to retrieve Transfer Utility")
    return
}

let blocks = AWSS3TransferUtilityBlocks(
    // ...
)
transferUtility.enumerateToAssign(blocks: blocks)

@github-actions github-actions bot removed the pending-maintainer-response Issue is pending response from an Amplify team member label Dec 24, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question General question s3 Issues related to S3
Projects
None yet
Development

No branches or pull requests

2 participants