iosswiftbatterylevel

Check if battery charging status changes in real time Swift


I want to check if my iphone is charging or not and what percentage. Im able to get the percentage fine as well as knowing if its plugged in or not when i start the app, however im not able ot make it change status as i unplug the charger. Essentially i want to be able plug and unplug the phone and have my Charge.text field change status from "charging" to "unplugged" and vice versa.

i implemented an alert box but that also only pops up when i start the app. ive got the core location in there because ive got an idea on implementing a location feedback thing, but its not used now, please just ignore that.

when searching the forums i seemingly only get answers on on how to check it once, not continuous updates. i dont know if the "real time" description helps but i didnt really know how to describe it. please help :)

import UIKit
import CoreLocation
import Alamofire
import SwiftyJSON

class ViewController: UIViewController, CLLocationManagerDelegate {
        
    @IBOutlet weak var Charge: UILabel!
    @IBOutlet weak var resultsField: UILabel!
    
    var chargingVar = ""
    
    var batteryLevel: Float {
       return UIDevice.current.batteryLevel
   }

    func batteryStatus() {
        UIDevice.current.isBatteryMonitoringEnabled = true
        
        batteryStateChanged()
        
        switch UIDevice.current.batteryState {
        case .unknown:
          self.Charge.text = "BATTERY: UNKNOWN!"
        case .charging:
          self.Charge.text = "Charging..."
        case .full:
          self.Charge.text = "BATTERY full"
        case .unplugged:
          self.Charge.text = "unplugged"
        default:
            self.Charge.text = "nope"
        
    }
        
        
    }
    
    func batteryStateChanged(){
        if (UIDevice.current.batteryState == .charging) {                UIApplication.shared.isIdleTimerDisabled = true
            self.chargingVar = "is charging. \u{1F603}"
                 chargingAlaer()
          }else{
            self.chargingVar = "is not charging. \u{1F622} "
                 chargingAlaer()
        }


    }
    func chargingAlaer(){
        let alertController = UIAlertController(title: "Charging Status",
                                                message: "Your device \(chargingVar)",
            preferredStyle: UIAlertController.Style.alert)
        let ok = UIAlertAction(title: "OK",
                               style: UIAlertAction.Style.default,
                               handler: {(action) -> Void in
        })
        alertController.addAction(ok)
        self.present(alertController, animated: true, completion: nil)
    }
    

    @objc func displayBatteryCharge() {
       self.resultsField.text = "\(batteryLevel * 100)%"
   }
    
   override func viewDidLoad() {
       super.viewDidLoad()
       UIDevice.current.isBatteryMonitoringEnabled = true

            
    
   }

   override func didReceiveMemoryWarning() {
       super.didReceiveMemoryWarning()
   }
    
    override func viewDidAppear(_ animated: Bool) {
        displayBatteryCharge()
        batteryStatus()
    }
    


            


}

Solution

  • Basically you did everything to display the current status, now you need to add something that is notified, or checks regularly for said status. In this case, I believe the best way would be to register to the batteryStateDidChangeNotification notification, which is only sent by the system when isBatteryMonitoringEnabled is set to true, as you did in the viewDidLoad

    I think adding

    NotificationCenter.default.addObserver(
        self,
        selector: #selector(batteryStatus),
        name: UIDevice.batteryStateDidChangeNotification,
        object: nil
    )
    

    Should do the trick. In the viewDidLoad for instance.