aws-amplify / aws-sdk-ios

AWS SDK for iOS. For more information, see our web site:
https://aws-amplify.github.io/docs
Other
1.67k stars 877 forks source link

No error message with Transfer Utility when loss network #3618

Closed Corgizzz closed 2 years ago

Corgizzz commented 3 years ago

State your question

I am using TransferUtility to upload my data to S3, When task in progressing I put my phone on airplane mode or close network , The task will be pause but I didn't get any error message or handler, I know that network become connection the task will automatically upload again, Is there any error response to tell me the task is paused ?

Which AWS Services are you utilizing? S3 Transfer Utility

Provide code snippets

        transferUtility.uploadData(
            data!,
            bucket: "ios-app-log-test",
            key: "\(username)/\(uploadTime).realm",
            contentType: "text/plain",
            expression: expression,
            completionHandler: completionHandler).continueWith { (task) -> AnyObject! in
                if let error = task.error {
                    print("Error: \(error.localizedDescription)")
                }
                if let uploadTask = task.result as? AWSS3TransferUtilityUploadTask
                {
                    let startTime = CommandBase.shareInstance.dateFormatter(format: "MM/dd HH:mm:ss", date: Date())
                    LocalDatabase.shared.addLogsData(Log: "\(startTime) Start Upload Log to S3 By User", time: startTime)
                }
                return nil;
            }

Environment :

Device Information :

In My Xcode Debug Console :

/* Start */
2021-06-03 12:15:38:332 myProject[1307:504094] Setting taskIdentifier to 3
2021-06-03 12:15:40:233 myProject[1307:504427] didSendBodyData called for task 3
2021-06-03 12:15:40:233 myProject[1307:504427] didSendBodyData called for task 3
2021-06-03 12:15:40:235 myProject[1307:504094] didSendBodyData called for task 3
2021-06-03 12:15:40:235 myProject[1307:504094] didSendBodyData called for task 3
2021-06-03 12:15:40:236 myProject[1307:504094] didSendBodyData called for task 3
/* airplane mode or loss network */
2021-06-03 12:15:42.335924+0800 myProject[1307:504104] Connection 26: encountered error(1:53)
2021-06-03 12:15:42.345081+0800 myProject[1307:504104] Connection 24: encountered error(1:53)
2021-06-03 12:15:42.358945+0800 myProject[1307:504104] Connection 27: encountered error(1:53)
palpatim commented 3 years ago

Hi @Corgizzz,

You are correct, the task won't report an error until the timeoutIntervalForResource expires. Behind the scenes, TransferUtility starts the transfer with an NSURLSession configured for background operation, and that task will automatically retry up to the configured timeout, so you won't see any failure notifications in the meantime.

Hope this helps.

Corgizzz commented 3 years ago

Hi @palpatim , I try add timeoutIntervalForResource and retryLimit but I still not receieve any error,
Will this issue be fixed in the future ? or Now is the final usecase , Thanks

Regards

palpatim commented 3 years ago

What values did you set each of those properties to?

Corgizzz commented 3 years ago

I set timeoutIntervalForResource = 20, retryLimit = 3

palpatim commented 3 years ago

We will need to investigate this further then. We've validated this behavior in the past, but perhaps there's something about a network connectivity loss that causes it to behave differently.

Corgizzz commented 3 years ago

Wait for good news , Thanks ~

ameter commented 2 years ago

When network connectivity is lost during upload, I confirmed that the completionHandler is called with an error as expected after timeoutIntervalForResource expires. However, it's important to note that timeoutIntervalForResource must be configured prior to instantiating the service client.

For example, you could create a customized AWSS3TransferUtility with something like the following:

// Create customized AWSS3TransferUtility if it doesn't already exist
if AWSS3TransferUtility.s3TransferUtility(forKey: "customTU") == nil {
    // Set custom options
    let tuConfig = AWSS3TransferUtilityConfiguration()
    tuConfig.timeoutIntervalForResource = 60

    // Read default service info from awsconfiguration.json
    guard let tuInfo = AWSInfo.default().defaultServiceInfo("S3TransferUtility"),
          let serviceConfig = AWSServiceConfiguration(region: tuInfo.region,
                                                      credentialsProvider: tuInfo.cognitoCredentialsProvider)
    else {
        print("Failed to create service configuration from settings in awsconfiguration.json.")
        return
    }

    // Register customized AWSS3TransferUtility
    AWSS3TransferUtility.register(with: serviceConfig,
                                  transferUtilityConfiguration: tuConfig,
                                  forKey: "customTU")
    { error in
        if let error = error {
            print("Error registering TransferUtility: \(error.localizedDescription)")
            return
        }
    }
}

And then retrieve it like this:

guard let transferUtility = AWSS3TransferUtility.s3TransferUtility(forKey: "customTU") else {
    print("Failed to get custom instance of AWSS3TransferUtility")
    return
}

In this example, the completion handler will be called with a timeout error if the upload does not complete within 60 seconds.

Hope this helps.