開発環境
> xcodebuild -version Xcode 13.3 Build version 13E113
モチベーション
- Swift Concurrencyに入門したい
- とりあえず個人開発中のサイクリングログViewerアプリ(tokizuoh/contrail)で実験
iOS15で追加されたHealthKitのrequestAuthorization
iOS15からHealthKitのAPIにrequestAuthorization(toShare:read:)が追加された。
それまではワークアウトデータの取得前にrequestAuthorization(toShare:read:completion:)を使用してユーザーに認可リクエストを行う必要があり、認可処理が終わった後の処理をクロージャとして渡す必要があった。iOS15から追加されたAPIはSwift Concurrency対応がされており、非同期的にコードを書くことができる。
(特に大きな問題は無いが、iOS15から追加されたAPIは引数のSetがnil許容でなくなっている)
コード
コード全部書くと見にくいのでGitHubのPRを添付。
細かいコメントは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に入門したがまだ手に馴染んでいないので何か題材を見つけて書いていく。