2017-05-21 26 views
7

W mojej aplikacji "Swift" mam funkcję przesyłania zdjęć do mojego wiadra Amazon S3. Gdy użytkownik jest podłączony do WiFi lub LTE, nie ma problemu, ale gdy połączenie jest nieco wolniejsze (np. 3G), przesyłanie zajmuje dużo czasu (do jednej minuty), a iPhone może stracić 15-20% bateria! Zmieniam rozmiar zdjęć do około 200-300 kb, więc nie powinno to stanowić problemu. Kod, który używam na to:Przesyłam dane z mojej aplikacji Swift do Amazon S3 i wyczerpuję baterię jak nic innego. Jak można tego uniknąć?

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 
     } 
     ) 

} 

Czy jest coś, co przychodzi na myśl, co robię źle tutaj i jak może to ogromne zużycie baterii należy unikać?

+0

tylko zgadywać. Jak często wywoływane jest wywołanie metody uploadProgress? Sądzę, że będzie to znacznie częściej dla wolniejszych przesyłek. Możesz więc planować wiele połączeń w DispatchQueue.main. Które mogą pochłaniać zasoby i z kolei spowolnić postęp, dodatkowo zaostrzając problem. Rzeczywiście, widziałem taki problem wiele lat temu (w innym, ale podobnym scenariuszu), gdy dodaliśmy "ładną i fantazyjną" animację postępu, tylko po to, by zobaczyć spadek prędkości sieci kilka razy, ponieważ nasza aplikacja była zajęta ponownym rysowaniem postęp i nie miał czasu na rzeczywistą współpracę sieciową :-). – Seva

+0

Łatwiejsze niż próby odgadnięcia, że ​​można zmierzyć, gdzie aplikacja zużywa większość procesorów przy użyciu narzędzia Time Profiler in Instruments. Jest film [wideo WWDC] (https://developer.apple.com/videos/play/wwdc2016/418/) wyjaśniający, jak to zrobić. –

Odpowiedz

5

Poniższa odpowiedź została zainspirowana https://stackoverflow.com/a/20690088/3549695

Wierzyłem, co trzeba zrobić, to zdolność do wykrywania typu Radio Network. Czy to WiFi, LTE, 3G, 2G lub bez sieci. Następnie aplikacja będzie musiała podjąć decyzję na podstawie wyniku.

Stworzyłem testowy projekt Xcode, aby przetestować tę koncepcję na moim iPhonie 6. Wydaje się działać, ale mogłem przetestować tylko "tryb samolotowy", WiFi i LTE. Nie mogę dostać się do sieci 2G lub 3G.

W przypadku obu WiFi lub LTE, będę uzyskać wartość: „CTRadioAccessTechnologyLTE”

Będąc w trybie Samolot „Air”, wartość Opcjonalnie będzie zerowe. Tak więc to do mnie należy tekst, który zastępuję. I wybrać do wyjścia 'nie stanie wykryć'

Oto co mój ViewController.swift wygląda następująco:

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") 
     } 
    } 
} 

Gdzie możliwe wartości dla .currentRadioAccessTechnology są:

/* 
* 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 
+0

Jeśli nie możesz zaakceptować tej odpowiedzi, uprzejmie poinformuj nas o przyczynie. Z tego wszyscy czerpią korzyści. – Wismin