I am using S3 bucket
to upload image from my swift
project, however, every now and then my upload pauses and gives me the following warning in console. However, I am not sure why but the upload appears to automatically restart and the second time almost always succeeds. And any upload after that is normally fine. (It is only when I have not interacted with the server for awhile
AWSiOSSDK v2.4.7 [Error] AWSURLSessionManager.m line:212 | -[AWSURLSessionManager URLSession:task:didCompleteWithError:] | Session task failed with error: Error Domain=NSURLErrorDomain Code=-1001 "The request timed out." UserInfo={NSUnderlyingError=0x13eba2b50 {Error Domain=kCFErrorDomainCFNetwork Code=-1001 "(null)" UserInfo={_kCFStreamErrorCodeKey=-2102, _kCFStreamErrorDomainKey=4}}, NSErrorFailingURLStringKey=https://s3.amazonaws.com/myBucketName/filename.jpg, NSErrorFailingURLKey=https://s3.amazonaws.com/myBucketName/filename.jpg, _kCFStreamErrorDomainKey=4, _kCFStreamErrorCodeKey=-2102, NSLocalizedDescription=The request timed out.}
Below is how I send file to S3
// 2. Create upload request
let uploadRequest = AWSS3TransferManagerUploadRequest()
uploadRequest.bucket = "myBucket"
uploadRequest.key = "FileName.jpg"
uploadRequest.ACL = AWSS3ObjectCannedACL.PublicRead
uploadRequest.contentType = "image/jpg"
uploadRequest.body = url
// Track progress through an AWSNetworkingUploadProgressBlock
uploadRequest?.uploadProgress = {[weak self](bytesSent:Int64, totalBytesSent:Int64, totalBytesExpectedToSend:Int64) in
dispatch_sync(dispatch_get_main_queue(), { () -> Void in
let progress = Float(totalBytesSent) / Float(totalBytesExpectedToSend)
print(" totalBytesSent \(totalBytesSent) / totalBytesExpectedToSend \(totalBytesExpectedToSend) progress = \(progress * 100 ) %")
circularProgressView.setProgress(progress, animated: true)
})
}
// 3. Upload to Amazone S3
let transferManager = AWSS3TransferManager.defaultS3TransferManager()
transferManager.upload(uploadRequest).continueWithExecutor(AWSExecutor.mainThreadExecutor(), withBlock: { (task: AWSTask) -> AnyObject? in
MRProgressOverlayView.dismissOverlayForView(self.view, animated: true)
self.enableUserInteraction()
if let error = task.error {
if error.domain == AWSS3TransferUtilityErrorDomain {
switch task.error?.code {
case AWSS3TransferManagerErrorType.Cancelled.rawValue?:
break
case AWSS3TransferManagerErrorType.Paused.rawValue?:
break
default:
self.showErrorAlert("Error uploading image #1", message: "\(error)")
}
} else {
self.showErrorAlert("Error uploading image #2", message: "\(error)")
}
} else {
if task.completed {
let imgLink = "https://s3.amazonaws.com/letzzeeamazones3bucket2/\(uploadRequest.key!)"
self.postToFirebase(imgLink, userCoordinate: userCoordinate)
} else {
self.showErrorAlert("Error uploading image #3", message: "Please try again later")
MRProgressOverlayView.dismissOverlayForView(self.view, animated: true)
self.enableUserInteraction()
}
}
To troubleshoot this error, check the following: Confirm that you're using the correct AWS Region and Amazon S3 endpoint. Verify that your network can connect to those Amazon S3 endpoints. Verify that your DNS can resolve to those Amazon S3 endpoints.
To check that your VPC Endpoint for S3 is working correctly, find the URL of your target bucket in the AWS console and use the hostname there as the target of a traceroute command on one of your virtual machines in your SDDC.
Each S3 operation is an API request with significant latency — tens to hundreds of milliseconds, which adds up to pretty much forever if you have millions of objects and try to work with them one at a time.
To troubleshoot the retry and timeout issues, first review the logs of the API call to find the problem. Then, change the retry count and timeout settings of the AWS SDK as needed for each use case. To allow enough time for a response to the API call, add time to the Lambda function timeout setting.
Whenever the Amazon AWS Mobile SDK displays an unclear warning in the console, turn on verbose logging to debug:
(Swift 4) AWSDDLog.sharedInstance.logLevel = .verbose
(Swift 3)
AWSLogger.default().logLevel = .verbose
(Swift 2) AWSLogger.defaultLogger().logLevel = .Verbose
…to reveal more information about what S3 buckets, regions, endpoints etc. are being used.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With