| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 |
- import Flutter
- import UIKit
- import CoreMotion
- public class SwiftPedometerPlugin: NSObject, FlutterPlugin {
- // Register Plugin
- public static func register(with registrar: FlutterPluginRegistrar) {
- let stepDetectionHandler = StepDetector()
- let stepDetectionChannel = FlutterEventChannel.init(name: "step_detection", binaryMessenger: registrar.messenger())
- stepDetectionChannel.setStreamHandler(stepDetectionHandler)
- let stepCountHandler = StepCounter()
- let stepCountChannel = FlutterEventChannel.init(name: "step_count", binaryMessenger: registrar.messenger())
- stepCountChannel.setStreamHandler(stepCountHandler)
- }
- }
- /// StepDetector, handles pedestrian status streaming
- public class StepDetector: NSObject, FlutterStreamHandler {
- private let pedometer = CMPedometer()
- private var running = false
- private var eventSink: FlutterEventSink?
- private func handleEvent(status: Int) {
- // If no eventSink to emit events to, do nothing (wait)
- if (eventSink == nil) {
- return
- }
- // Emit pedestrian status event to Flutter
- eventSink!(status)
- }
- public func onListen(withArguments arguments: Any?, eventSink: @escaping FlutterEventSink) -> FlutterError? {
- self.eventSink = eventSink
- if #available(iOS 10.0, *) {
- if (!CMPedometer.isPedometerEventTrackingAvailable()) {
- eventSink(FlutterError(code: "2", message: "Step Detection is not available", details: nil))
- }
- else if (!running) {
- running = true
- pedometer.startEventUpdates() {
- pedometerData, error in
- guard let pedometerData = pedometerData, error == nil else { return }
- DispatchQueue.main.async {
- self.handleEvent(status: pedometerData.type.rawValue)
- }
- }
- }
- } else {
- eventSink(FlutterError(code: "1", message: "Requires iOS 10.0 minimum", details: nil))
- }
- return nil
- }
- public func onCancel(withArguments arguments: Any?) -> FlutterError? {
- NotificationCenter.default.removeObserver(self)
- eventSink = nil
- if (running) {
- pedometer.stopUpdates()
- running = false
- }
- return nil
- }
- }
- /// StepCounter, handles step count streaming
- public class StepCounter: NSObject, FlutterStreamHandler {
- private let pedometer = CMPedometer()
- private var running = false
- private var eventSink: FlutterEventSink?
- private func handleEvent(count: Int) {
- // If no eventSink to emit events to, do nothing (wait)
- if (eventSink == nil) {
- return
- }
- // Emit step count event to Flutter
- eventSink!(count)
- }
- public func onListen(withArguments arguments: Any?, eventSink: @escaping FlutterEventSink) -> FlutterError? {
- self.eventSink = eventSink
- if #available(iOS 10.0, *) {
- if (!CMPedometer.isStepCountingAvailable()) {
- eventSink(FlutterError(code: "3", message: "Step Count is not available", details: nil))
- }
- else if (!running) {
- let systemUptime = ProcessInfo.processInfo.systemUptime;
- let timeNow = Date().timeIntervalSince1970
- let dateOfLastReboot = Date(timeIntervalSince1970: timeNow - systemUptime)
- running = true
- pedometer.startUpdates(from: dateOfLastReboot) {
- pedometerData, error in
- guard let pedometerData = pedometerData, error == nil else { return }
- DispatchQueue.main.async {
- self.handleEvent(count: pedometerData.numberOfSteps.intValue)
- }
- }
- }
- } else {
- eventSink(FlutterError(code: "1", message: "Requires iOS 10.0 minimum", details: nil))
- }
- return nil
- }
- public func onCancel(withArguments arguments: Any?) -> FlutterError? {
- NotificationCenter.default.removeObserver(self)
- eventSink = nil
- if (running) {
- pedometer.stopUpdates()
- running = false
- }
- return nil
- }
- }
|