How to use CMBatchedSensorManager

"for try await dataArray in bsm.deviceMotionUpdates()" generate error: Error Domain=CMErrorDomain Code=109 "(null)"

Environment

  • iOS 17.0 (21A5277j)
  • watchOS 10.0 (21R5295g)
  • XCode 15.0 beta 4 (15A5195m)
  • Mac Studio 2022, macOS 13.4.1 (22F82)

Details

I create a swift project with code:

File 1:

  let healthStore = HKHealthStore()
  var workoutSession: HKWorkoutSession!

  func workoutSession(_ workoutSession: HKWorkoutSession, didChangeTo toState: HKWorkoutSessionState, from fromState: HKWorkoutSessionState, date: Date) {
    
  }
  
  func workoutSession(_ workoutSession: HKWorkoutSession, didFailWithError error: Error) {
    
  }

  func requestAuthorization() {
    // The quantity type to write to the health store.
    let typesToShare: Set = [
      HKQuantityType.workoutType()
    ]
    
    // The quantity types to read from the health store.
    let typesToRead: Set = [
      HKQuantityType.quantityType(forIdentifier: .heartRate)!,
      HKQuantityType.quantityType(forIdentifier: .activeEnergyBurned)!,
      HKQuantityType.quantityType(forIdentifier: .distanceWalkingRunning)!
    ]
    
    // Request authorization for those quantity types
    healthStore.requestAuthorization(toShare: typesToShare, read: typesToRead) { success, error in
      // Handle error.
    }
  }

  // before call startWatch(), will request authorization to access Healthkit
  func startWatch(_ startWatchFor:Int) -> MotionManager? {
    let configuration = HKWorkoutConfiguration()
    let motionMgr: MotionManager?
    
    configuration.activityType = .golf
    configuration.locationType = .outdoor
    do {
      workoutSession = try HKWorkoutSession(healthStore: healthStore, configuration: configuration)
      workoutSession.startActivity(with: Date())
    } catch {
      // Handle any exceptions.
      return nil
    }
    workoutSession.delegate = self

    ... // in turn, a func startUpdates() in another swift file will be called.
  }

File 2:

  var batchedSensorManager: Any?
  
  @available(watchOSApplicationExtension 6.0.0, *)
  func batchedSensorUpdates() async {
    if #available(watchOSApplicationExtension 10.0, *),
       let bsm = batchedSensorManager as? CMBatchedSensorManager {
      bsm.startDeviceMotionUpdates()
      do {
        for try await dataArray in bsm.deviceMotionUpdates() {
          if !processDMEntry {
            break
          }
          ... // process data
        }
      } catch let error as NSError {
        print("batchedSensorManager.deviceMotionUpdates() fail", error.description)
      }
    }
  }
  • It becomes work on iOS 17.0 (21A5319a) (beta 7) and watchOS 10.0 (21R5349b) (beta 7). So it is only bug on beta version.

Add a Comment