CMMotionActivityManager queryActivityStarting data not available outside closure

我们两清 提交于 2021-01-29 05:18:12

问题


I have this code to get historical motion activity from using CoreMotionActivity.

func buildActivityArray() -> Array<Any> {

  let now = Date()
  let then = Date().addingTimeInterval(-3600)

  var motionManager: CMMotionActivityManager!
  motionManager = CMMotionActivityManager()

  var activityList: [Any] = []

  motionManager.queryActivityStarting(from: then, to: now, to: .main) { motionActivities, error in

      if let error = error {
          print("error: \(error.localizedDescription)")
          return
      }

      motionActivities?.forEach { activity in

          if activity.confidence == .medium || activity.confidence == .high {

              if activity.stationary {
                  activityList.append("stationary")
                  activityList.append(Int(activity.timestamp))
              } else if activity.walking {
                  activityList.append("walking")
                  activityList.append(Int(activity.timestamp))
              } else if activity.running {
                  activityList.append("running")
                  activityList.append(Int(activity.timestamp))
              }
          }
      }

      print("** activityList = ", activityList)
  }

  print("* activityList = ", activityList)

  return(activityList)

}

The first print statement returns the array with data, but the 2nd print statement is always empty. It looks like the 2nd print statement gets executed before the motionManager.queryActivityStarting closure completes executing, and therefore returns empty array.

How do I wait for the closure to finish before executing the 2nd print statement?

Thank you for your help


回答1:


Yes you're right, the second print gets executed first. This is because the method queryActivityStarting is async.

According to Apple's doc

This method runs asynchronously, returning immediately and delivering the results to the specified handler block. A delay of up to several minutes in reported activities is expected.

The handler block which is your "closure" is very similar to callback function in js.

So, you will need to write your business logic in this handler block. Of course, to keep your code clean, it's advisable to call another method instead of writing all in this block. Moreover, you can add observer on activityList if you wish to get notified (then invoke other functions) when its value gets changed.



来源:https://stackoverflow.com/questions/52987303/cmmotionactivitymanager-queryactivitystarting-data-not-available-outside-closure

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!