Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

I'm uploading data from my Swift app to Amazon S3 and it drains battery like nothing else. How can this be avoided?

In my 'Swift' app I have a feature of uploading photos to my Amazon S3 bucket. When the user is connected to WiFi or LTE, there's no problem, but when the connection is a little slower (e.g. 3G), then the upload takes a lot of time (up to one minute) and iphone can lose 15-20% of battery! I resize photos down to around 200-300kb, so that should not be a problem. The code that I use for that is:

func awsS3PhotoUploader(_ ext: String, pathToFile: String, contentType: String, automaticUpload: Bool){

        let credentialsProvider = AWSCognitoCredentialsProvider(regionType:CognitoRegionType,
                                                                identityPoolId:CognitoIdentityPoolId)
        let configuration = AWSServiceConfiguration(region:CognitoRegionType, credentialsProvider:credentialsProvider)
        AWSServiceManager.default().defaultServiceConfiguration = configuration

        let uploadRequest = AWSS3TransferManagerUploadRequest()
        uploadRequest?.body = URL(string: "file://"+pathToFile)
        uploadRequest?.key = ProcessInfo.processInfo.globallyUniqueString + "." + ext
        uploadRequest?.bucket = S3BucketName
        uploadRequest?.contentType = contentType + ext

        uploadRequest?.uploadProgress = { (bytesSent, totalBytesSent, totalBytesExpectedToSend) -> Void in
            DispatchQueue.main.async(execute: { () -> Void in
                if totalBytesExpectedToSend > 1 {
                    print(totalBytesSent)
                    print(totalBytesExpectedToSend)
                }
            })
        }
        let transferManager = AWSS3TransferManager.default()
        transferManager?.upload(uploadRequest).continue({ (task) -> AnyObject! in

            if (task.isCompleted) {
                  print("task completed")
            }

            if let error = task.error {
                 print("Upload failed ❌ (\(error))")

            }
            if let exception = task.exception {
                 print("Upload failed ❌ (\(exception))")

            }
            if task.result != nil {
                let s3URL: String = "https://myAlias.cloudfront.net/\((uploadRequest?.key!)!)"
                print("Uploaded to:\n\(s3URL)")
            }
            else {
                print("Unexpected empty result.")
            }
            return nil
        }
        )

}

Is there anything that comes up to your mind of what am I doing wrong here and how could this huge battery consumption be avoided?

like image 882
user3766930 Avatar asked May 21 '17 14:05

user3766930


1 Answers

The following answer was inspired by https://stackoverflow.com/a/20690088/3549695

I believed what you need to do is the ability to detect the Type of the Radio Network. Be it WiFi, LTE, 3G, 2G, or No Network. Then the app will need to make the decision, based on the result.

I created a test Xcode project to test this concept on my iPhone 6. It seems to work, but I could only test 'Air Plane Mode', WiFi and LTE. I can't get myself into 2G or 3G network.

In case of either WiFi or LTE, I will get the value: 'CTRadioAccessTechnologyLTE'

While in 'Air Plane Mode', the Optional value will be nil. So it's up to me what text I replace it with. And I choose to output 'Not able to detect'

Here is what my ViewController.swift looks like:

import UIKit
import CoreTelephony

class ViewController: UIViewController {

    @IBOutlet weak var currentRAN: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

    }

    @IBAction func detect(_ sender: UIButton) {
        if case let telephonyInfo = CTTelephonyNetworkInfo(),
            let currentRadioAccessTech = telephonyInfo.currentRadioAccessTechnology {

            currentRAN.text = currentRadioAccessTech
            print("Current Radio Access Technology: \(currentRadioAccessTech)")

        } else {
            currentRAN.text = "Not able to detect"
            print("Not able to detect")
        }
    }
}

Where the possible values for .currentRadioAccessTechnology are:

/*
* Radio Access Technology values
*/
@available(iOS 7.0, *)
public let CTRadioAccessTechnologyGPRS: String
@available(iOS 7.0, *)
public let CTRadioAccessTechnologyEdge: String
@available(iOS 7.0, *)
public let CTRadioAccessTechnologyWCDMA: String
@available(iOS 7.0, *)
public let CTRadioAccessTechnologyHSDPA: String
@available(iOS 7.0, *)
public let CTRadioAccessTechnologyHSUPA: String
@available(iOS 7.0, *)
public let CTRadioAccessTechnologyCDMA1x: String
@available(iOS 7.0, *)
public let CTRadioAccessTechnologyCDMAEVDORev0: String
@available(iOS 7.0, *)
public let CTRadioAccessTechnologyCDMAEVDORevA: String
@available(iOS 7.0, *)
public let CTRadioAccessTechnologyCDMAEVDORevB: String
@available(iOS 7.0, *)
public let CTRadioAccessTechnologyeHRPD: String
@available(iOS 7.0, *)
public let CTRadioAccessTechnologyLTE: String
like image 94
Wismin Avatar answered Nov 02 '22 21:11

Wismin