iOS15で追加されたHealthKitのrequestAuthorizationを試す

開発環境

> xcodebuild -version
Xcode 13.3
Build version 13E113

モチベーション

  • Swift Concurrencyに入門したい
  • とりあえず個人開発中のサイクリングログViewerアプリ(tokizuoh/contrail)で実験

iOS15で追加されたHealthKitのrequestAuthorization

iOS15からHealthKitのAPIrequestAuthorization(toShare:read:)が追加された。
それまではワークアウトデータの取得前にrequestAuthorization(toShare:read:completion:)を使用してユーザーに認可リクエストを行う必要があり、認可処理が終わった後の処理をクロージャとして渡す必要があった。iOS15から追加されたAPIはSwift Concurrency対応がされており、非同期的にコードを書くことができる。

(特に大きな問題は無いが、iOS15から追加されたAPIは引数のSetがnil許容でなくなっている)

コード

コード全部書くと見にくいのでGitHubのPRを添付。

github.com

細かいコメントはPRページに書いてあるが、特にGoodなところを下記に記載。

ネストが減ってより分かりやすく見やすくなった

今までは非同期処理を同期的に書く際はクロージャを利用していたため、クロージャ宣言側のネストが深くなりコードの複雑性が上がるにつれて可読性が悪くなっていった。

import Foundation

func greet(_ something: String, completion: () -> Void){
  print("Hello, " + something + "!")
  completion()
}

greet("Soshina") {
  // このブロック
  print("いや誰やねん!")
}

Swift Concurrency対応のAPIを用いることで、よりスッキリ書くことができた。

Before

let readTypes = Set([
    HKObjectType.workoutType()
])
healthStore.requestAuthorization(toShare: nil, read: readTypes) { _, error in
    guard error == nil else {
        // エラー処理
        return
    }
}

After

let readTypes = Set([
    HKObjectType.workoutType()
])
do {
    try await healthStore.requestAuthorization(toShare: Set([]), read: readTypes)
} catch let error {
     // エラー処理
}

今回でSwift Concurrencyに入門したがまだ手に馴染んでいないので何か題材を見つけて書いていく。

参考