Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> 如何借助 HealthKit 打造一款健身應用?

如何借助 HealthKit 打造一款健身應用?

編輯:關於Android編程

根據新聞報導,健康與健美在今時今日的重要程度比已往任何時候都高。說起來有點可笑,似乎就在幾天之前,筆者就見到過類似的新聞。或許,這是當人逐漸變老之後揮之不去的感覺吧——渴望保持健康以及健美的感覺。不管怎麼說,健康與健美是一個重要話題。技術的進步,尤其是移動應用與硬件世界的不斷提高,正為這個似乎日益成長的話題帶來全新的契機。

HealthKit 是蘋果公司推出的一款移動應用平台,旨在為重要、可追蹤的健康數據與注重健康、熱衷鍛煉的科技消費者搭起橋梁。這很酷。用戶可以輕松地追蹤一段時間內可測量的健身與健康數據。除了了解自身的健康數據,看到圖表中喜人的增長曲線也的確鼓舞人心。

正如人們想象的那樣,在管理健康信息時是非常重要的考慮因素。HealthKit 直截了當地將所有 HealthKit 信息的絕對控制權置於用戶的手中。用戶可以授權或拒絕任何應用對其健康數據發出的讀取請求。

作為開發者,我們需要征求許可才能從/向 HealthKit 讀取/寫入數據。實際上,我們需要明確地聲明打算讀取或改變的數據。此外,任何使用 HealthKit 的應用都必須包含隱私政策,這樣一來,用戶才能對其信息的處理感到更加放心。

關於 OneHourWalker

在本文中,我們將打造一個有趣的小應用,它會從 HealthKit 讀取數據,也會向其寫入新數據。來見一見 OneHourWalker 吧。

如何借助 HealthKit 打造一款健身應用?

OneHourWalker 是一款追蹤使用者在一個小時內行走或跑步之距離的健身應用。用戶可以將距離與 HealthKit 分享,之後就能在健康應用中讀取之。我知道,一個小時聽起來有點過於樂觀了(至少筆者本人可能無法堅持下去)。因此,用戶也可以提早中止計數,並分享距離。

額,到目前為止,似乎 OneHourWalker 只會向 HealthKit 寫入數據。我們需要讀取什麼數據呢?<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxwPrrDzsrM4qOh1NqyvdDQts3Btsqxo6zO0s+yu7bRodTxz+e85Lvywda85NChwreho7Ojs6OjrM7Su+HT9rW9yvfWprXNtLm1xMf40/Kho7b4ztLKx9K7zPXJ7bjfIDE5M2NtILXEurrX06Os1eLV5rXEyMPO0rrcv+DE1aGjveK+9rDst6jKx6O6tNMgSGVhbHRoS2l0ILbByKHTw7untcTJ7bjfyv2+3aOsvavWrrTy06HOqtOm08O1xNK7uPax6sepoaPV4rj2serHqb/J0tTX986qttTTw7untcTJxtLizOHQ0aOs1eLR+aOsy/vDx77NxNyx3MPi1NqyvdDQyrGxu8r31qa08rW9oaM8L3A+DQo8cD7K18/Io6w8YSBocmVmPQ=="https://github.com/appcoda/OneHourWalker/blob/master/OneHourWalker.zip?raw=true">點此下載 OneHourWalker 的初始項目。先試著跑起來,找找應用運行的感覺。計數器與地點追蹤功能已經在運行了,所以我們只需專注於 HealthKit 實現。注意,當到達 60 分鐘時間點時,計算器與追蹤都會停止。

啟用 HealthKit

首先,在我們的應用中啟用 HealthKit。在項目導航中,點擊 OneHourWalker,之後點擊 Targets 下面的 OneHourWalker,之後選擇屏幕頂部的 Capabilities 選項。

如何借助 HealthKit 打造一款健身應用?

查看 Capabilities 列表的底部,啟用 HealthKit。這一簡單的操作會將 HealthKit 權限添加到 App ID,將 HealthKit 鍵添加到 info plist 文件,將 HealthKit 權限添加到授權文件,並且與 HealthKit.framework 相連接。就是這麼簡單。

開始編程

接下來,跳轉到 TimerViewController.swift,開始將 HealthKit 引入 OneHourWalker。首先,創建一個 HealthKitManager 實例。

import UIKit
import CoreLocation
import HealthKit

class TimerViewController: UIViewController, CLLocationManagerDelegate {

    @IBOutlet weak var timerLabel: UILabel!
    @IBOutlet weak var milesLabel: UILabel!
    @IBOutlet weak var heightLabel: UILabel!    

    var zeroTime = NSTimeInterval()    
    var timer : NSTimer = NSTimer()

    let locationManager = CLLocationManager()    
    var startLocation: CLLocation!    
    var lastLocation: CLLocation!    
    var distanceTraveled = 0.0

    let healthManager:HealthKitManager = HealthKitManager()

所有 HealthKit 工作都會在 HealthKitManager.swift 中進行。它會包含重要的方法,我們很快就會談到。

正如在前文介紹部分所述,我們需要取得用戶的許可,才能讀取並修改他們的健康數據。在 viewDidLoad()中,我們就得這麼做。

    override func viewDidLoad() {
       super.viewDidLoad()

   locationManager.requestWhenInUseAuthorization()

    if CLLocationManager.locationServicesEnabled(){
        locationManager.delegate = self
        locationManager.desiredAccuracy = kCLLocationAccuracyBest
    } else {
        print("Need to Enable Location")
    }

    // We cannot access the user's HealthKit data without specific permission.
    getHealthKitPermission()
}

getHealthKitPermission() 方法會調用 manager 的 authorizeHealthKit()方法。如果一切順利,我們便能調用setHeight()方法。不過,我們很快會在後文中談到此方法。

func getHealthKitPermission() {        

    // Seek authorization in HealthKitManager.swift.
    healthManager.authorizeHealthKit { (authorized,  error) -> Void in                        if authorized {                

            // Get and set the user's height.
            self.setHeight()
        } else {                
                   if error != nil {                    
                        print(error)
            }                
            print("Permission denied.")
        }
    }
}

在 HealthKitManager.swift 中,我們會創建 authorizeHealthKit() 方法。然而,除此之外,我們需要創建 HealthKit 存儲,用於連接應用與 HealthKit 的數據。

let healthKitStore: HKHealthStore = HKHealthStore()

func authorizeHealthKit(completion: ((success: Bool, error: NSError!) -> Void)!) {

    // State the health data type(s) we want to read from HealthKit.        
    let healthDataToRead = Set(arrayLiteral: HKObjectType.quantityTypeForIdentifier(HKQuantityTypeIdentifierHeight)!)

    // State the health data type(s) we want to write from HealthKit.        
    let healthDataToWrite = Set(arrayLiteral: HKObjectType.quantityTypeForIdentifier(HKQuantityTypeIdentifierDistanceWalkingRunning)!)

    // Just in case OneHourWalker makes its way to an iPad...        
    if !HKHealthStore.isHealthDataAvailable() {            
        print("Can't access HealthKit.")
    }

    // Request authorization to read and/or write the specific data.        
    healthKitStore.requestAuthorizationToShareTypes(healthDataToWrite, readTypes: healthDataToRead) { (success, error) -> Void in            
    if( completion != nil ) {
            completion(success:success, error:error)
        }
    }
}

在請求獲取用戶健康數據的授權時,我們需要明確指定打算讀取以及修改的信息。對本例而言,我們需要讀取用戶的身高,從而幫助他們躲避有危險的低垂枝丫。我們希望 HealthKit 能提供一個可以轉化為可理解的身高的 HKObject 量。此外,我們還要獲得修改 HKObject 量的許可,以記錄用戶的行走及跑步距離。

在處理好 OneHourWalker 與 iPad 通信的可能性後,我們做出官方請求。

HealthKitManager.swift 中,創建從 HealthKit 讀取用戶身高數據的 getHeight() 方法。

func getHeight(sampleType: HKSampleType , completion: ((HKSample!, NSError!) -> Void)!) {

    // Predicate for the height query        
    let distantPastHeight = NSDate.distantPast() as NSDate        
    let currentDate = NSDate()        
    let lastHeightPredicate = HKQuery.predicateForSamplesWithStartDate(distantPastHeight, endDate: currentDate, options: .None)

    // Get the single most recent height        
    let sortDescriptor = NSSortDescriptor(key: HKSampleSortIdentifierStartDate, ascending: false)

    // Query HealthKit for the last Height entry.        
    let heightQuery = HKSampleQuery(sampleType: sampleType, predicate: lastHeightPredicate, limit: 1, sortDescriptors: [sortDescriptor]) { (sampleQuery, results, error ) -> Void in                

    if let queryError = error {
                completion(nil, queryError)                    
                return
            }                

            // Set the first HKQuantitySample in results as the most recent height.                let lastHeight = results!.first                

            if completion != nil {
                completion(lastHeight, nil)
            }
    }        

    // Time to execute the query.
    self.healthKitStore.executeQuery(heightQuery)
}

查詢身高數據的第一步是創建一個斷言以定義時間參數。我們是在請求一段時間內的所有身高數據——與當前日期相距甚遠的一個過去的日期。顯然,這會返回一個數組。然而,我們只想要最近期的身高,因此,我們請求數據時可以讓最新的數據排在數組的最前頭。

在構建這一查詢時,我們會把數組的長度限制為1。在考慮好出現錯誤的可能性後,我們會將結果中的首個也即唯一一個數組項目分配給 lastHeight。接下來,完善 getHeight() 方法。最後,針對用戶的健康數據執行查詢。

回到 TimerViewController.swift,在 app 真正投入使用之前,假設用戶授權了適當的許可,則 setHeight() 方法會被 getHealthKitPermission() 調用。

var height: HKQuantitySample?

首先,我們需要為 HKQuantitySample 實例聲明一個身高變量。

func setHeight() {        
     // Create the HKSample for Height.        
     let heightSample = HKSampleType.quantityTypeForIdentifier(HKQuantityTypeIdentifierHeight)        

     // Call HealthKitManager's getSample() method to get the user's height.              
     self.healthManager.getHeight(heightSample!, completion: { (userHeight, error) -> Void in            

     if( error != nil ) {
            print("Error: \(error.localizedDescription)")                
            return
        }            

        var heightString = ""            

        self.height = userHeight as? HKQuantitySample            

        // The height is formatted to the user's locale.            
        if let meters = self.height?.quantity.doubleValueForUnit(HKUnit.meterUnit()) {                
            let formatHeight = NSLengthFormatter()
            formatHeight.forPersonHeightUse = true
            heightString = formatHeight.stringFromMeters(meters)
        }            

        // Set the label to reflect the user's height.
        dispatch_async(dispatch_get_main_queue(), { () -> Void in                                self.heightLabel.text = heightString
        })
    })

}

share() 方法之上,我們會創建 setHeight() 方法。我們請求的身高數據樣本以 HKQuantity 返回,標識符 HKQuantityTypeIdentifierHeight 知道這一對象。

接下來,調用在 manager 中創建的 getHeight() 方法。有了身高樣本,我們還需要將之翻譯為恰當的字符串以展示在標簽中。與往常一樣,考慮所有可能的錯誤情況是很重要的。

到此,用戶就可以打開 app,查看他們的身高(如果他的健康應用中記錄著身高數據),開啟計時器,追蹤他跑步或行走的距離了。接下來,我們要處理將距離數據寫入健康應用的過程,這樣,用戶才能在同一個應用中保存其所有的健身數據。

在用戶結束外出鍛煉之後,不管有沒有到60分鐘,他可能會使用 Share(分享)按鈕將其辛苦賺得的運動距離發送到健康應用。所以,在 share() 方法中,我們需要調用 HealthKitManager.swiftsaveDistance() 方法來實現這一過程。在這個方法中,我們會發送運動距離以及取得該距離的日期。這樣,用戶便能在第二天爭取更好的成績。

@IBAction func share(sender: AnyObject) {    
      healthManager.saveDistance(distanceTraveled, date: NSDate())
}

接下來,回到 manager,我們要在此處創建 saveDistance() 方法。首先,我們要讓 HealthKit 知道我們打算寫入一個代表步行及跑步距離的量。之後,將度量單位設置為英裡,並賦值官方的樣本量。HealthKit 的 saveObject() 方法會將此數據寫入用戶的健康數據。

func saveDistance(distanceRecorded: Double, date: NSDate ) {        

    // Set the quantity type to the running/walking distance.
    let distanceType = HKQuantityType.quantityTypeForIdentifier(HKQuantityTypeIdentifierDistanceWalkingRunning)        

    // Set the unit of measurement to miles.
    let distanceQuantity = HKQuantity(unit: HKUnit.mileUnit(), doubleValue: distanceRecorded)        

    // Set the official Quantity Sample.
    let distance = HKQuantitySample(type: distanceType!, quantity: distanceQuantity, startDate: date, endDate: date)        

    // Save the distance quantity sample to the HealthKit Store.
    healthKitStore.saveObject(distance, withCompletion: { (success, error) -> Void in            
    if( error != nil ) {                
          print(error)
        } else {                
          print("The distance has been recorded! Better go check!")
        }
    })
}

跳轉到健康應用,所記錄的數據會出現在 Walking + Running Distance(行走+跑步距離)一行(如果已經啟用)。此外,依照下面的路徑,我們可以看到詳細的樣本數據:Health Data tab(健康數據選項卡) > Fitness(健身) > Walking + Running Distance(行走+跑步距離) > Show All Data(顯示所有數據)。我們的數據就在此列表中。輕擊一個單元,我們的圖標(目前還未設置)就會與距離一同出現。再次點擊此單元,就能看到完整的細節數據。

如何借助 HealthKit 打造一款健身應用?

借助 OneHourWalker,我們便能為全世界 iOS 用戶的身體健康貢獻一份力量。然而,這只是一個開始。在使用 HealthKit 讀取並修改健康數據的道路上,還有非常多的可能性。

當然,對用戶而言,擁有這些可追蹤數據的好處很多。人們可以輕松地按照日期、星期進行比較,從而激勵自己朝著目標努力。不過,真正的偉大之處在於,開發者可以提供全新的,富有創造力的有趣方法來獲取數據。

歡迎大家對 HealthKit 應用進行測試。點擊此處查看 OneHourWalker 的最終版本。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved