问题
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