Tuesday, May 30, 2017

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

Leave a Comment

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?

1 Answers

Answers 1

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 
If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment