美文网首页
如何使用Swift来学习HealthKit中的sleep ana

如何使用Swift来学习HealthKit中的sleep ana

作者: Iridescent330 | 来源:发表于2016-07-07 06:08 被阅读0次

    Source

    如何使用Swift来学习HealthKit中的sleep analysis

    如今,有关睡眠的问题变得流行起来,用户不仅对他们什么时候入睡感兴趣,更关心的是一段时间之后,应用根据收集的数据所得出的结果。随着硬件和手机技术的发展,有关科技与睡眠的话题变的极其受关注。

    苹果通过内建的Health应用,提供了一种简单酷炫的方式来安全的访问和存储用户的健康信息。你不仅可以用HealthKit来开发一个健康类应用,还可以利用framework来获取有关sleep analysis的数据。

    在这个教程里,我将带你快速了解HealthKit的框架,并且演示如何开发一个简单的sleep analysis应用。

    简介

    HealthKit框架提供了一种结构HealthKit store,利用它你可以把信息存储在一个加密的数据库里。你可以通过HKHealthStore这个类来访问数据库。iPhone和Apple Watch分别拥有自己的HealthKit store,并且里面的数据在iPhone和Apple Watch之间是同步的。但是有一点需要注意,在Apple Watch中,为了节省空间,旧的数据是会被清除的。而iPad是不支持Health Kit和Health应用的。

    你如果想开发一个iOS或者watchOS的应用,那么HealthKit是一个强大的工具。HealthKit就是被设计用来管理来自不同资源的数据,而且可以根据用户的设置来合并这些数据。应用还可以访问原始数据,并且合并他们。身体指标,健康指标以及营养指标,这些数据都可以被用来做sleep analysis。

    接下来,你将会了解如何使用HealthKit框架去保存和访问iOS中的sleep analysis数据。以下的内容同样适用于watchOS。这个教程是基于Swift 2.0 和 Xcode 7. 请确保你是用Xcode 7或者以上的版本。

    在这之前,下载初始工程文件并且解压缩。我已经为你创建了基本的界面。当你运行这个工程的时候,你会看到一个计时器的界面,点击开始按钮,计时器开始运行。

    学习HealthKit框架

    这个教程的目标是开发一个简单的应用,可以存储sleep analysis的数据,以及通过开始 & 停止按钮来获取数据。第一步,你必须获得HealthKit的许可。在你的工程文件中,选择Current Target选项,选择capabilities,并且打开对应的HealthKit。

    HealthKit-allowHealthKit-allow

    下一步,你需要在ViewController中创建一个HKHealthStore实例,下面是代码:

    let healthStore = HKHealthStore()
    

    接着,我们使用创建的HKHealthStore实例来访问HealthKit store。

    就像刚才提到的一样,HealthKit允许用户去选择是否其他程序可以获取他们的健康数据。所以在你访问(读/写)sleep analysis数据之前,你需要获取用户的许可。怎么做呢?第一步,导入内建的HealthKit框架,并且在viewDidLoad中添加以下代码:

    override func viewDidLoad() {
    
        super.viewDidLoad()    
    
        let typestoRead = Set([
    
            HKObjectType.categoryTypeForIdentifier(HKCategoryTypeIdentifierSleepAnalysis)!
    
            ])
    
        let typestoShare = Set([
    
            HKObjectType.categoryTypeForIdentifier(HKCategoryTypeIdentifierSleepAnalysis)!
    
            ])
    
      
        self.healthStore.requestAuthorizationToShareTypes(typestoShare, readTypes: typestoRead) { (success, error) -> Void in
    
            if success == false {
    
                NSLog(" Display not allowed")
            }
        }
    }
    

    以上的代码将会请求获取用户的HealthKit权限,用户可以选择允许或者拒绝。在完成闭包中,你可以做更多的处理,例如获取权限成功怎么办,出现错误应该怎么办。用户有可能拒绝你的访问权限,所以你必须要在完成闭包中小心的处理这些特殊情况。

    为了教程的顺利进行,你必须要选择允许选项来使应用获得你手机上的健康数据。

    Health-App-PermissionHealth-App-Permission

    写入sleep analysis数据

    首先,我们如何得到sleep analysis的数据呢?根据苹果的官方文档,每一个sleep analysis的样本只包含一个值。这个值表示了用户在床上的时间和睡眠的时间,HealthKit用了二个或者二个以上的样本,每一个样本都包含与其它样本重叠的时间。通过这些样本的开始时间和结束时间,我们能够计算出这样的一些数据:

    • 用户入睡用了多长时间
    • 用户睡眠时间与用户在床上时间的比例
    • 用户醒来后直到下床的时间
    • 用户在床上和用户睡眠的总共时间
    record_sleep_datarecord_sleep_data

    简单来说,根据以下方法,我们能够把sleep analysis数据存入到HealKit store中。

    1. 首先根据开始时间和结束时间,定义两个NSDate对象
    2. 利用HKCategoryTypeIdentifierSleepAnalysis创建HKObjectType实例
    3. 创建一个HKCategorySample实例。每一个样本代表了用户在床上或者睡眠的时间长度。所以我们创建一个在床上的样本和睡眠的样本,这两个样本有着冲重叠的时间。
      4.最后,我们用HKHealthStoresaveObject方法来保存这个对象。

    如果把上述的4步转化为Swift代码,就是下面的这些。把以下代码放在ViewController中。

    func saveSleepAnalysis() {
    
            // alarmTime and endTime are NSDate objects
    
            if let sleepType = HKObjectType.categoryTypeForIdentifier(HKCategoryTypeIdentifierSleepAnalysis) {
    
            // we create our new object we want to push in Health app
    
            let object = HKCategorySample(type:sleepType, value: HKCategoryValueSleepAnalysis.InBed.rawValue, startDate: self.alarmTime, endDate: self.endTime)
    
            // at the end, we save it
    
            healthStore.saveObject(object, withCompletion: { (success, error) -> Void in
    
                if error != nil {
    
                    // something happened
    
                    return
    
                }
                if success {
    
                    print("My new data was saved in HealthKit")
    
                } else {
    
                    // something happened again
    
                }
            })
    
            let object2 = HKCategorySample(type:sleepType, value: HKCategoryValueSleepAnalysis.Asleep.rawValue, startDate: self.alarmTime, endDate: self.endTime)
    
            healthStore.saveObject(object2, withCompletion: { (success, error) -> Void in
    
                if error != nil {
    
                    // something happened
    
                    return
    
                }
    
                if success {
    
                    print("My new data (2) was saved in HealthKit")
    
                } else {
    
                    // something happened again
    
                }
            })
    
        }
    
    }
    
    

    当想要存储sleep analysis数据到HealthKit的时候,我们可以调用这个方法。

    读取sleep analysis数据

    为了能够读取sleep analysis的数据,我们需要执行一个查询操作。首先,定义一个HKObjectType类别,指明类别是HKCategoryTypeIdentifierSleepAnalysis。接下来可以用predicate去过滤得到的数据,可以根据startDateendDate这两个NSDate类来得到你想要的时间区间。最后还创建一个sortDescriptor来根据你想得到的结果进行进一步的排序操作。

    下面是以上过程的代码:

    func retrieveSleepAnalysis() {
    
            // first, we define the object type we want
    
            if let sleepType = HKObjectType.categoryTypeForIdentifier(HKCategoryTypeIdentifierSleepAnalysis) {
    
            // Use a sortDescriptor to get the recent data first
    
            let sortDescriptor = NSSortDescriptor(key: HKSampleSortIdentifierEndDate, ascending: false)
    
            // we create our query with a block completion to execute
    
            let query = HKSampleQuery(sampleType: sleepType, predicate: nil, limit: 30, sortDescriptors: [sortDescriptor]) { (query, tmpResult, error) -> Void in
    
                if error != nil {
    
                    // something happened
    
                    return
    
                }
                if let result = tmpResult {
    
                    // do something with my data
    
                    for item in result {
    
                        if let sample = item as? HKCategorySample {
    
                            let value = (sample.value == HKCategoryValueSleepAnalysis.InBed.rawValue) ? "InBed" : "Asleep"
    
                            print("Healthkit sleep: (sample.startDate) (sample.endDate) \- value: (value)")
    
                        }
    
                    }
    
                }
    
            }
    
            // finally, we execute our query
    
            healthStore.executeQuery(query)
    
        }
    
    }
    
    

    这个方法用来查询HealthKit,并且得到所有的sleep analysis数据,并且把这些数据按照降序排序。接下来每一个查询都以startDate和endDate的形式被打印出来。例如In Bed 或者是 Asleep。 在创建query对象时,我在limit参数里传入了30,表示我想得到最后30条记录的样本。当然了,你可以用在predicate参数中,传入你自己定义的predicate对象,这样你就可以自定义startDate和endDate了。

    应用测试

    在这个Demo应用中,我用了一个NSTimer来模拟真实的时间,当你按下开始按钮后,计时器会运行。两个NSDate对象在开始和结束按钮被按下时分别被创建,这样我们就可以模拟记录sleep analysis数据了。在stop方法中,你可以调用saveSleepAnalysis()retrieveSleepAnalysis()方法来存储和读取睡眠数据。

    @IBAction func stop(sender: AnyObject) {
    
        endTime = NSDate()
    
        saveSleepAnalysis()
    
        retrieveSleepAnalysis()
    
        timer.invalidate()
    
    }
    
    

    在你的工程文件中,你不用完全遵循我的代码,你也可以自由的改变startDate和endDate这两个NSDate对象去存储用户在床上的时间和睡眠时间。

    好了,现在你可以运行你的程序,开始计时。让我们等上几分钟,然后点击停止按钮。之后,我们可以打开自带的Health应用。你会发现睡眠数据已经出现在界面中了。

    sleep-analysis-testsleep-analysis-test

    小贴士时间

    HealthKit是为开发者用来提供一个通用的平台,通过这个平台,我们可以轻松的共享,获取用户数据,同时并且避免了重复或者前后矛盾的数据。在Apple审核应用规则中明确规定了,必须要清楚明确的请求获取用户的Health权限,如果不这么做,很可能你的应用会被拒绝上架。

    如果一个应用试图在Health应用中存入虚假的或者不正确的数据,同样会被拒绝上架。这意味着,像本教程中使用非常简单的算法去计算不同的健康数据,这样也是不行的。你应该利用内建的传感器去获取数据,计算数据,这样,你获得的数据会更加真实有效。

    如果你想获得完全的Xcode工程,你可以从这里获取。

    相关文章

      网友评论

          本文标题:如何使用Swift来学习HealthKit中的sleep ana

          本文链接:https://www.haomeiwen.com/subject/aidkjttx.html