CMMotionActivityManager queryActivityStarting数据在闭包之外不可用

时间:2018-10-25 10:39:48

标签: ios swift core-motion

我有这段代码,可以通过使用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)

}

第一个print语句返回包含数据的数组,但是第二个print语句始终为空。看起来第二个打印语句在motionManager.queryActivityStarting闭包完成执行之前已执行,因此返回空数组。

在执行第二个print语句之前,如何等待关闭完成?

谢谢您的帮助

1 个答案:

答案 0 :(得分:1)

是的,第二张打印将首先执行。这是因为方法 queryActivityStarting 是异步的。

根据Apple's doc

  

此方法异步运行,立即返回并将结果传递到指定的处理程序块。预计报告的活动可能会延迟几分钟。

作为您的“关闭”的处理程序块与js中的回调函数非常相似。

因此,您将需要在此处理程序块中编写业务逻辑。当然,为了保持代码的清洁,建议调用另一个方法,而不要在此块中全部编写代码。此外,如果希望在其值更改时得到通知(然后调用其他函数),可以在 activityList 上添加观察者。