gpt4 book ai didi

ios - 事件指示器在异步查询结束前停止

转载 作者:行者123 更新时间:2023-11-28 19:53:53 25 4
gpt4 key购买 nike

我有一个 ViewController,它调用一个类 HKQueryWeight,它运行一个 HealthKit 查询(顺便说一句,非常非常慢)并将数据保存到 CoreData。如果用户在查询结束前离开 VC,应用程序就会崩溃。

fatal error: unexpectedly found nil while unwrapping an Optional value (lldb)

最初我认为我可以通过添加一个 activityIndi​​cator 来修补这个问题,它在 viewDidAppear 中开始动画并在 VC 中的最后一个函数结束时停止。有用。但是,我相信,由于 healthKit 查询的异步特性,动画会在实际 healthKit 查询完成之前停止。

  • 问题:如何创建动画仅在最后一个 healthKit 查询完成时停止的解决方案?

我不确定是否有必要提供代码,但我已经这样做了,以防有用

View Controller :

class ViewController: UIViewController {

@IBOutlet var activityIndicator: UIActivityIndicatorView!

override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)

activityIndicator.startAnimating()

setupArrays ()
}

func setupArrays (){
println("setting up arrays")

if NSUserDefaults.standardUserDefaults().boolForKey("hrSwitch") == true {
var hkQueryHeartRate = HKQueryHeartRate()
hkQueryHeartRate.performHKQuery()
}


if NSUserDefaults.standardUserDefaults().boolForKey("weightSwitch") == true {
var hkQueryWeight = HKQueryWeight()
hkQueryWeight.performHKQuery()
}

self.activityIndicator.stopAnimating()
}

HKQuery

import Foundation
import CoreData
import HealthKit


class HKQueryWeight: HKQueryProtocol {


func performHKQuery() {
var appDel:AppDelegate = UIApplication.sharedApplication().delegate as AppDelegate
var context = (UIApplication.sharedApplication().delegate as AppDelegate).managedObjectContext!

let healthKitManager = HealthKitManager.sharedInstance
let calendar = NSCalendar.currentCalendar()

let interval = NSDateComponents()
interval.day = 1

// Set the anchor date to Monday at 3:00 a.m.
let anchorComponents =
calendar.components(.CalendarUnitDay | .CalendarUnitMonth |
.CalendarUnitYear | .CalendarUnitWeekday, fromDate: NSDate())

let offset = (7 + anchorComponents.weekday - 2) % 7
anchorComponents.day -= offset
anchorComponents.hour = 3
//let now = NSDate()

let anchorDate = calendar.dateFromComponents(anchorComponents)

let quantityType = HKObjectType.quantityTypeForIdentifier(HKQuantityTypeIdentifierBodyMass)

// Create the query
let query = HKStatisticsCollectionQuery(quantityType: quantityType,
quantitySamplePredicate: nil,
options: .DiscreteAverage,
anchorDate: anchorDate,
intervalComponents: interval)

// Set the results handler
query.initialResultsHandler = {
query, results, error in

if error != nil {
// Perform proper error handling here
println("*** An error occurred while calculating the statistics: \(error.localizedDescription) ***")
abort()
}

let endDate = NSDate()
let startDate =
calendar.dateByAddingUnit(.MonthCalendarUnit,
value: -6, toDate: endDate, options: nil)

// Plot the weekly step counts over the past 6 months
results.enumerateStatisticsFromDate(startDate, toDate: endDate) {
statistics, stop in

if let quantity = statistics.averageQuantity() {
let date = statistics.startDate
let weight = quantity.doubleValueForUnit(HKUnit.gramUnitWithMetricPrefix(.Kilo))

println("weight date: \(date)")
println("weight value: \(weight)")


var weightData = NSEntityDescription.insertNewObjectForEntityForName("HKWeight", inManagedObjectContext: context) as HKWeight

//Saving to CoreData
weightData.setValue(weight, forKey: "weight_data")
weightData.setValue(date, forKey: "weight_date")

context.save(nil)

}
}
}

healthKitManager.healthStore.executeQuery(query)
}
}

最佳答案

现在,调用查询后立即调用 self.activityIndi​​cator.stopAnimating()。由于查询是异步的,它们在被调用后仍然可以在后台执行一段时间,因此如果您在查询被调用后立即删除事件指示器,查询可能还不会完成。如果您希望事件指示器在您的查询完成后停止动画,您必须在您的异步查询 block 内调用它停止动画。

由于您的查询在不同的类中,您可以发布通知以在每个查询结束时结束事件指示器的动画,然后在第二个查询完成和第二个查询后停止 UIActivityIndi​​catorView 的动画收到通知,例如:

var notificationCount:Int = 0
var totalQueries = 0

func setupArrays (){
println("setting up arrays")

notificationCount = 0
totalQueries = 0
NSNotificationCenter.defaultCenter().addObserver(self, selector: "removeActivityIndicator", name:"ActivityIndicatorNotification", object: nil)

if NSUserDefaults.standardUserDefaults().boolForKey("hrSwitch") == true {
totalQueries = totalQueries + 1
var hkQueryHeartRate = HKQueryHeartRate()
hkQueryHeartRate.performHKQuery()
}
if NSUserDefaults.standardUserDefaults().boolForKey("weightSwitch") == true {
totalQueries = totalQueries + 1
var hkQueryWeight = HKQueryWeight()
hkQueryWeight.performHKQuery()
}

if totalQueries == 0 {
self.activityIndicator.stopAnimating()
}
}

func removeActivityIndicator () {

notificationCount = notificationCount + 1

if notificationCount == totalQueries {

dispatch_async(dispatch_get_main_queue()) {
self.activityIndicator.stopAnimating()
NSNotificationCenter.defaultCenter().removeObserver(self, name:"ActivityIndicatorNotification", object:nil)
}
}
}

然后在HKQueryWeight中:

func performHKQuery() {

// ...All the code before the query...

// Set the results handler
query.initialResultsHandler = {
query, results, error in

//...All the code currently within your query...

NSNotificationCenter.defaultCenter().postNotificationName("ActivityIndicatorNotification", object: nil) // <-- post notification to stop animating the activity indicator once the query's complete
}

关于ios - 事件指示器在异步查询结束前停止,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27681144/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com