How to Monitor Battery Level and State Changes Using Swift

How to monitor battery level and state changes using swift

You can use the battery state notification UIDeviceBatteryStateDidChangeNotification and UIDeviceBatteryLevelDidChangeNotification to be notified when its state changed:

override func viewDidLoad() {
super.viewDidLoad()
NSNotificationCenter.defaultCenter().addObserver(self, selector: "batteryStateDidChange:", name: UIDeviceBatteryStateDidChangeNotification, object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: "batteryLevelDidChange:", name: UIDeviceBatteryLevelDidChangeNotification, object: nil)

// Stuff...
}

func batteryStateDidChange(notification: NSNotification){
// The stage did change: plugged, unplugged, full charge...
}

func batteryLevelDidChange(notification: NSNotification){
// The battery's level did change (98%, 99%, ...)
}

Check if battery charging status changes in real time Swift

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.

Check Battery Level iOS Swift

Xcode 11 • Swift 5.1

First just enable battery monitoring:

UIDevice.current.isBatteryMonitoringEnabled = true

Then you can create a computed property to return the battery level:

Battery level ranges from 0.0 (fully discharged) to 1.0 (100%
charged). Before accessing this property, ensure that battery
monitoring is enabled. If battery monitoring is not enabled, battery
state is UIDevice.BatteryState.unknown and the value of this property
is –1.0.

var batteryLevel: Float { UIDevice.current.batteryLevel }

To monitor your device battery level you can add an observer for the UIDevice.batteryLevelDidChangeNotification:

NotificationCenter.default.addObserver(self, selector: #selector(batteryLevelDidChange), name: UIDevice.batteryLevelDidChangeNotification, object: nil)


Battery level ranges from 0.0 (fully discharged) to 1.0 (100% charged). Before accessing this property, ensure that battery monitoring is enabled.

If battery monitoring is not enabled, battery state is UIDevice.BatteryState.unknown and the value of this property is –1.0.



@objc func batteryLevelDidChange(_ notification: Notification) {
print(batteryLevel)
}

You can also verify the battery state:

var batteryState: UIDevice.BatteryState { UIDevice.current.batteryState }


case .unknown   //  "The battery state for the device cannot be determined."
case .unplugged // "The device is not plugged into power; the battery is discharging"
case .charging // "The device is plugged into power and the battery is less than 100% charged."
case .full // "The device is plugged into power and the battery is 100% charged."

and add an observer for UIDevice.batteryStateDidChangeNotification:

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


@objc func batteryStateDidChange(_ notification: Notification) {
switch batteryState {
case .unplugged, .unknown:
print("not charging")
case .charging, .full:
print("charging or full")
}
}

Swift 3 Xcode: How to display battery levels as an integer?

Try this instead:

func someFunction() {
self.infoLabel.text = String(format: "%.0f%%", batteryLevel * 100)
}

For future reference, all string format specifiers are listed here.

how to access device battery level from lock screen

I went through this this tutorial

and this seems to be working perfectly. I made only one change, that is, in info.plist file I added a new property Application does not run in background & gave it a value YES.

What is the most concise way to display a changing value with Combine and SwiftUI?

Minimal working example to be pasted inside iPadOS Swift playground.

Basically it’s the give code aligned with the latest changes from SwiftUI and Combine.

  • use the @Published property wrapper for any properties you want to observe in your view (Docs: By default an ObservableObject synthesizes an objectWillChange publisher that emits the changed value before any of its @Published properties changes.). This avoids the usage of custom setters and objectWillChange.

  • the cancellable is the output from Publishers.Assign, it can be used to cancel the subscription manually and for best practice, it will be stored in a “CancellableBag” thus cancel the subscription on deinit. This practice is inspired by other reactive frameworks such as RxSwift and ReactiveUI.

  • I found without turning on the battery level notifications the KVO publisher for battery level will emit just once -1.0.

// iPadOS playground
import SwiftUI
import Combine
import PlaygroundSupport

class BatteryModel : ObservableObject {
@Published var level = UIDevice.current.batteryLevel
private var cancellableSet: Set<AnyCancellable> = []

init () {
UIDevice.current.isBatteryMonitoringEnabled = true
assignLevelPublisher()
}

private func assignLevelPublisher() {
_ = UIDevice.current
.publisher(for: \.batteryLevel)
.assign(to: \.level, on: self)
.store(in: &self.cancellableSet)
}
}
struct ContentView: View {

@ObservedObject var batteryModel = BatteryModel()

var body: some View {
Text("\(Int(round(batteryModel.level * 100)))%")
}
}

let host = UIHostingController(rootView: ContentView())
PlaygroundPage.current.liveView = host

Battery state and level thanks to the background fetch?

Based on the accepted answer, it looks like it wasn't the case, but often these types of questions boil down to trying to defer/cancel intensive, but otherwise discretionary work. If that happens to be the case, I've had great luck with using the NSProcessInfo low power APIs. There's even a notification for when it becomes enabled, which is particularly useful for cancellation.



Related Topics



Leave a reply



Submit