SlideShare a Scribd company logo
1 of 78


2
3
4
5
6
7
8
9
11
12
13
14
15
16
17
18
20
21
import UIKit
import HealthStore
class ViewController: UIViewController {
private let healthStore = HealthStore()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
}
22
guard let healthStore = healthStore else { return }
guard let type = HKQuantityType.quantityType(forIdentifier: .stepCount) else { return }
let builder = DailyQueryBuilder(quantityType: type)
healthStore.requestSources(from: Date.startOfToday(), to: Date(), builder: builder) { (sources: [StepSource]?) in
if let sources = sources {
print("sources: (sources)”)
} else {
print("step sources are not found.”)
}
}
23
guard let healthStore = healthStore else { return }
guard let type = HKQuantityType.quantityType(forIdentifier: .stepCount) else { return }
let builder = DailyQueryBuilder(quantityType: type)
healthStore.requestSources(from: Date.startOfToday(), to: Date(), builder: builder) { (sources: [StepSource]?) in
if let sources = sources {
print("sources: (sources)”)
} else {
print("step sources are not found.”)
}
}
24
guard let healthStore = healthStore else { return }
guard let type = HKQuantityType.quantityType(forIdentifier: .stepCount) else { return }
let builder = DailyQueryBuilder(quantityType: type)
healthStore.requestSources(to: Date(), builder: builder) { (sources: [StepSource]?) in
if let sources = sources {
print("sources: (sources)”)
} else {
print("step sources are not found.”)
}
}
25
guard let healthStore = healthStore else { return }
guard let type = HKQuantityType.quantityType(forIdentifier: .stepCount) else { return }
let builder = DailyQueryBuilder(quantityType: type)
healthStore.observeSourceUpdates(from: Date(), builder: builder, handler: { (sources: [StepSource]?) in
if let sources = sources {
print("sources: (sources)")
} else {
print("step sources are not found.")
}
})
26
guard let healthStore = healthStore else { return }
guard let type = HKQuantityType.quantityType(forIdentifier: .stepCount) else { return }
let builder = RestrictedSourceQueryBuilder(quantityType: type)
healthStore.requestSources(from: Date.startOfToday(), to: Date(), builder: builder) { (sources: [StepSource]?) in
if let sources = sources {
print("sources: (sources)”)
} else {
print("step sources are not found.”)
}
}
27
28
import HealthKit
public protocol HealthStoreQueryBuildable {
var quantityType: HKQuantityType { get }
var typesToWrite: Set<HKSampleType>? { get }
var typesToRead: Set<HKObjectType>? { get }
var options: HKStatisticsOptions { get }
var anchorDate: Date { get }
var intervalComponents: DateComponents { get }
var predicates: [NSPredicate] { get }
func build() -> HKStatisticsCollectionQuery?
func build(completion: @escaping (HKStatisticsCollectionQuery?) -> Void)
}
29
public extension HealthStoreQueryBuildable {
var typesToWrite: Set<HKSampleType>? {
return nil
}
var typesToRead: Set<HKObjectType>? {
return nil
}
func build() -> HKStatisticsCollectionQuery? {
let predicate = NSCompoundPredicate(andPredicateWithSubpredicates: predicates)
return HKStatisticsCollectionQuery(
quantityType: quantityType,
quantitySamplePredicate: predicate,
options: options,
anchorDate: anchorDate,
intervalComponents: intervalComponents)
}
func build(completion: @escaping (HKStatisticsCollectionQuery?) -> Void) {
completion(build())
}
}
30
public struct DailyQueryBuilder: HealthStoreQueryBuildable {
public let quantityType: HKQuantityType
public var typesToRead: Set<HKObjectType>? {
return [quantityType]
}
public let options: HKStatisticsOptions = .cumulativeSum
public let anchorDate: Date
public let intervalComponents: DateComponents = DateComponents(day: 1)
public let predicates: [NSPredicate] = []
public init(quantityType: HKQuantityType, anchorDate: Date = Date.startOfToday()) {
self.quantityType = quantityType
self.anchorDate = anchorDate
}
}
31
public class RestrictedSourceQueryBuilder: HealthStoreQueryBuildable {
public func build(completion: @escaping (HKStatisticsCollectionQuery?) -> Void) {
guard let provider = HealthSourceProvider() else {
completion(nil)
return
}
provider.appleSources(sampleType: quantityType) { (sources, error) in
if let error = error {
print(error)
}
guard let sources = sources else {
completion(nil)
return
}
// update predicates
let metadataPredicate = HKQuery.predicateForObjects(withMetadataKey: HKMetadataKeyWasUserEntered,
operatorType: .notEqualTo,
value: true)
let sourcePredicate = HKQuery.predicateForObjects(from: sources)
self.predicates = [metadataPredicate, sourcePredicate]
// build query
completion(self.build())
}
}
}
32
33
34
35
36
38
39
🤖
🚀
40
💗
👀
41
42
43
44
45
46
47
var (
ErrNoSuchUser = errors.New("...")
)
type Repository interface {
Get(id string) (*User, error)
}
var NewRepository func(context.Context) Repository
domain/user/repository.go
48
49
type userRepository struct {
Ctx context.Context
}
func NewUserRepository(ctx context.Context) user.Repository {
return &userRepository{
Ctx: ctx,
}
}
func (r *userRepository) Get(id string) (*user.User, error) {
// ...
}
infrastructure/persistence/datastore/user_repository.go
50
func init() {
user.NewRepository = datastore.NewUserRepository
}
func main() {
repo := user.NewRepository(ctx) // datastore.userRepository
}
51
type userRepository struct {
Ctx context.Context
}
func NewUserRepository(ctx context.Context) user.Repository {
return &userRepository{
Ctx: ctx,
}
}
func (r *userRepository) Get(id string) (*user.User, error) {
// ...
}
infrastructure/persistence/mock/user_repository.go
52
func TestMain(m *testing.M) {
user.NewRepository = mock.NewUserRepository
m.Run()
}
53
👍
👍
👍
58
59
func Namespacer(h http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
// treat an error!
ctx, _ := appengine.Namespace(r.Context(), "Namespace-a")
h(w, r.WithContext(ctx))
}
}
Middleware
63
64
👍
👍
👍
BigQuery
App Engine
Datastore
Data Studio
BigQuery
App Engine
Datastore
Data Studio
App Engine
Task Queue
BigQuery
Access
Enqueue
BigQuery
App Engine
Datastore
Data Studio
Cron Export Backup
Load
71
Cron Export Backup
72
Create Load Job
Backup
Trigger
Load
Cron Export Backup
Load
BigQuery
App Engine
Datastore
Data Studio
BigQuery
Data Studio
76
77
👍
👍
👍
ヘルスケアサービスを実現する最新技術  〜HealthKit・GCP + Goの活用〜

More Related Content

What's hot

Amazing threesome, rrr... React. Redux. Real world / Ростислав Галкин (Babo)
Amazing threesome, rrr... React. Redux. Real world / Ростислав Галкин (Babo)Amazing threesome, rrr... React. Redux. Real world / Ростислав Галкин (Babo)
Amazing threesome, rrr... React. Redux. Real world / Ростислав Галкин (Babo)
Ontico
 
1403 app dev series - session 5 - analytics
1403   app dev series - session 5 - analytics1403   app dev series - session 5 - analytics
1403 app dev series - session 5 - analytics
MongoDB
 
ApplicationCoordinator для навигации между экранами / Павел Гуров (Avito)
ApplicationCoordinator для навигации между экранами / Павел Гуров (Avito)ApplicationCoordinator для навигации между экранами / Павел Гуров (Avito)
ApplicationCoordinator для навигации между экранами / Павел Гуров (Avito)
Ontico
 

What's hot (20)

662305 11
662305 11662305 11
662305 11
 
Amazing threesome, rrr... React. Redux. Real world / Ростислав Галкин (Babo)
Amazing threesome, rrr... React. Redux. Real world / Ростислав Галкин (Babo)Amazing threesome, rrr... React. Redux. Real world / Ростислав Галкин (Babo)
Amazing threesome, rrr... React. Redux. Real world / Ростислав Галкин (Babo)
 
React. Redux. Real world.
React. Redux. Real world.React. Redux. Real world.
React. Redux. Real world.
 
JavaScript Patterns to Cleanup your Code
JavaScript Patterns to Cleanup your CodeJavaScript Patterns to Cleanup your Code
JavaScript Patterns to Cleanup your Code
 
Query for json databases
Query for json databasesQuery for json databases
Query for json databases
 
CodiLime Tech Talk - Katarzyna Ziomek-Zdanowicz: RxJS main concepts and real ...
CodiLime Tech Talk - Katarzyna Ziomek-Zdanowicz: RxJS main concepts and real ...CodiLime Tech Talk - Katarzyna Ziomek-Zdanowicz: RxJS main concepts and real ...
CodiLime Tech Talk - Katarzyna Ziomek-Zdanowicz: RxJS main concepts and real ...
 
The Ring programming language version 1.8 book - Part 73 of 202
The Ring programming language version 1.8 book - Part 73 of 202The Ring programming language version 1.8 book - Part 73 of 202
The Ring programming language version 1.8 book - Part 73 of 202
 
Ken 20150306 心得分享
Ken 20150306 心得分享Ken 20150306 心得分享
Ken 20150306 心得分享
 
Goa tutorial
Goa tutorialGoa tutorial
Goa tutorial
 
Receipt processing with Google Cloud Platform and the Google Assistant
Receipt processing with Google Cloud Platform and the Google AssistantReceipt processing with Google Cloud Platform and the Google Assistant
Receipt processing with Google Cloud Platform and the Google Assistant
 
Do something in 5 with gas 9-copy between databases with oauth2
Do something in 5 with gas 9-copy between databases with oauth2Do something in 5 with gas 9-copy between databases with oauth2
Do something in 5 with gas 9-copy between databases with oauth2
 
1403 app dev series - session 5 - analytics
1403   app dev series - session 5 - analytics1403   app dev series - session 5 - analytics
1403 app dev series - session 5 - analytics
 
The Ring programming language version 1.5.2 book - Part 64 of 181
The Ring programming language version 1.5.2 book - Part 64 of 181The Ring programming language version 1.5.2 book - Part 64 of 181
The Ring programming language version 1.5.2 book - Part 64 of 181
 
I os 04
I os 04I os 04
I os 04
 
Event-Driven Systems With MongoDB
Event-Driven Systems With MongoDBEvent-Driven Systems With MongoDB
Event-Driven Systems With MongoDB
 
Cubes - Lightweight Python OLAP (EuroPython 2012 talk)
Cubes - Lightweight Python OLAP (EuroPython 2012 talk)Cubes - Lightweight Python OLAP (EuroPython 2012 talk)
Cubes - Lightweight Python OLAP (EuroPython 2012 talk)
 
Testowanie JavaScript
Testowanie JavaScriptTestowanie JavaScript
Testowanie JavaScript
 
如何「畫圖」寫測試 - RxJS Marble Test
如何「畫圖」寫測試 - RxJS Marble Test如何「畫圖」寫測試 - RxJS Marble Test
如何「畫圖」寫測試 - RxJS Marble Test
 
ApplicationCoordinator для навигации между экранами / Павел Гуров (Avito)
ApplicationCoordinator для навигации между экранами / Павел Гуров (Avito)ApplicationCoordinator для навигации между экранами / Павел Гуров (Avito)
ApplicationCoordinator для навигации между экранами / Павел Гуров (Avito)
 
Charting with Google
Charting with GoogleCharting with Google
Charting with Google
 

Similar to ヘルスケアサービスを実現する最新技術 〜HealthKit・GCP + Goの活用〜

Spca2014 hillier build your_own_rest_service
Spca2014 hillier build your_own_rest_serviceSpca2014 hillier build your_own_rest_service
Spca2014 hillier build your_own_rest_service
NCCOMMS
 

Similar to ヘルスケアサービスを実現する最新技術 〜HealthKit・GCP + Goの活用〜 (20)

Android Design Patterns
Android Design PatternsAndroid Design Patterns
Android Design Patterns
 
TechDays 2016 - Developing websites using asp.net core mvc6 and entity framew...
TechDays 2016 - Developing websites using asp.net core mvc6 and entity framew...TechDays 2016 - Developing websites using asp.net core mvc6 and entity framew...
TechDays 2016 - Developing websites using asp.net core mvc6 and entity framew...
 
Beautiful java script
Beautiful java scriptBeautiful java script
Beautiful java script
 
Reduxing like a pro
Reduxing like a proReduxing like a pro
Reduxing like a pro
 
Spca2014 hillier build your_own_rest_service
Spca2014 hillier build your_own_rest_serviceSpca2014 hillier build your_own_rest_service
Spca2014 hillier build your_own_rest_service
 
Http Communication in Angular 2.0
Http Communication in Angular 2.0Http Communication in Angular 2.0
Http Communication in Angular 2.0
 
“iOS 11 в App in the Air”, Пронин Сергей, App in the Air
“iOS 11 в App in the Air”, Пронин Сергей, App in the Air“iOS 11 в App in the Air”, Пронин Сергей, App in the Air
“iOS 11 в App in the Air”, Пронин Сергей, App in the Air
 
API 통신, Retrofit 대신 Ktor 어떠신가요.pdf
API 통신, Retrofit 대신 Ktor 어떠신가요.pdfAPI 통신, Retrofit 대신 Ktor 어떠신가요.pdf
API 통신, Retrofit 대신 Ktor 어떠신가요.pdf
 
Create methods to_insert
Create methods to_insertCreate methods to_insert
Create methods to_insert
 
Blending Culture in Twitter Client
Blending Culture in Twitter ClientBlending Culture in Twitter Client
Blending Culture in Twitter Client
 
«Управление логикой переходов между экранами приложения с помощью координатор...
«Управление логикой переходов между экранами приложения с помощью координатор...«Управление логикой переходов между экранами приложения с помощью координатор...
«Управление логикой переходов между экранами приложения с помощью координатор...
 
【Unity】Scriptable object 入門と活用例
【Unity】Scriptable object 入門と活用例【Unity】Scriptable object 入門と活用例
【Unity】Scriptable object 入門と活用例
 
A GWT Application with MVP Pattern Deploying to CloudFoundry using Spring Roo
A GWT Application with MVP Pattern Deploying to CloudFoundry using  Spring Roo A GWT Application with MVP Pattern Deploying to CloudFoundry using  Spring Roo
A GWT Application with MVP Pattern Deploying to CloudFoundry using Spring Roo
 
A test framework out of the box - Geb for Web and mobile
A test framework out of the box - Geb for Web and mobileA test framework out of the box - Geb for Web and mobile
A test framework out of the box - Geb for Web and mobile
 
React, Redux and es6/7
React, Redux and es6/7React, Redux and es6/7
React, Redux and es6/7
 
Vuex to Pinia, how to migrate an existing app
Vuex to Pinia, how to migrate an existing appVuex to Pinia, how to migrate an existing app
Vuex to Pinia, how to migrate an existing app
 
Understanding backbonejs
Understanding backbonejsUnderstanding backbonejs
Understanding backbonejs
 
F3
F3F3
F3
 
Durable functions 2.0 (2019-10-10)
Durable functions 2.0 (2019-10-10)Durable functions 2.0 (2019-10-10)
Durable functions 2.0 (2019-10-10)
 
Cocoaheads Meetup / Alex Zimin / Swift magic
Cocoaheads Meetup / Alex Zimin / Swift magicCocoaheads Meetup / Alex Zimin / Swift magic
Cocoaheads Meetup / Alex Zimin / Swift magic
 

More from DeNA

More from DeNA (20)

DRIVE CHARTの裏側 〜 AI ☓ IoT ☓ ビッグデータを 支えるアーキテクチャ 〜
DRIVE CHARTの裏側  〜 AI ☓ IoT ☓ ビッグデータを 支えるアーキテクチャ 〜DRIVE CHARTの裏側  〜 AI ☓ IoT ☓ ビッグデータを 支えるアーキテクチャ 〜
DRIVE CHARTの裏側 〜 AI ☓ IoT ☓ ビッグデータを 支えるアーキテクチャ 〜
 
IoTと業務システムをつなぐgRPC/RESTサービスの開発と運用
IoTと業務システムをつなぐgRPC/RESTサービスの開発と運用IoTと業務システムをつなぐgRPC/RESTサービスの開発と運用
IoTと業務システムをつなぐgRPC/RESTサービスの開発と運用
 
Can We Make Maps from Videos? ~From AI Algorithm to Engineering for Continuou...
Can We Make Maps from Videos? ~From AI Algorithm to Engineering for Continuou...Can We Make Maps from Videos? ~From AI Algorithm to Engineering for Continuou...
Can We Make Maps from Videos? ~From AI Algorithm to Engineering for Continuou...
 
SHOWROOMとDeNAで取り組んだライブ配信基盤刷新・超低遅延ライブ配信の裏側【DeNA TechCon 2020 ライブ配信】
SHOWROOMとDeNAで取り組んだライブ配信基盤刷新・超低遅延ライブ配信の裏側【DeNA TechCon 2020 ライブ配信】SHOWROOMとDeNAで取り組んだライブ配信基盤刷新・超低遅延ライブ配信の裏側【DeNA TechCon 2020 ライブ配信】
SHOWROOMとDeNAで取り組んだライブ配信基盤刷新・超低遅延ライブ配信の裏側【DeNA TechCon 2020 ライブ配信】
 
クラウド環境でのセキュリティ監査自動化【DeNA TechCon 2020 ライブ配信】
クラウド環境でのセキュリティ監査自動化【DeNA TechCon 2020 ライブ配信】クラウド環境でのセキュリティ監査自動化【DeNA TechCon 2020 ライブ配信】
クラウド環境でのセキュリティ監査自動化【DeNA TechCon 2020 ライブ配信】
 
DeClang 誕生!Clang ベースのハッキング対策コンパイラ【DeNA TechCon 2020 ライブ配信】
DeClang 誕生!Clang ベースのハッキング対策コンパイラ【DeNA TechCon 2020 ライブ配信】DeClang 誕生!Clang ベースのハッキング対策コンパイラ【DeNA TechCon 2020 ライブ配信】
DeClang 誕生!Clang ベースのハッキング対策コンパイラ【DeNA TechCon 2020 ライブ配信】
 
仕様起因の手戻りを減らして開発効率アップを目指すチャレンジ 【DeNA TechCon 2020 ライブ配信】
仕様起因の手戻りを減らして開発効率アップを目指すチャレンジ 【DeNA TechCon 2020 ライブ配信】仕様起因の手戻りを減らして開発効率アップを目指すチャレンジ 【DeNA TechCon 2020 ライブ配信】
仕様起因の手戻りを減らして開発効率アップを目指すチャレンジ 【DeNA TechCon 2020 ライブ配信】
 
DeNA データプラットフォームにおける 自由と統制のバランス【DeNA TechCon 2020 ライブ配信】
DeNA データプラットフォームにおける 自由と統制のバランス【DeNA TechCon 2020 ライブ配信】DeNA データプラットフォームにおける 自由と統制のバランス【DeNA TechCon 2020 ライブ配信】
DeNA データプラットフォームにおける 自由と統制のバランス【DeNA TechCon 2020 ライブ配信】
 
リアルタイムリモートデバッグ環境によるゲーム開発イテレーションの高速化【DeNA TechCon 2020 ライブ配信】
リアルタイムリモートデバッグ環境によるゲーム開発イテレーションの高速化【DeNA TechCon 2020 ライブ配信】リアルタイムリモートデバッグ環境によるゲーム開発イテレーションの高速化【DeNA TechCon 2020 ライブ配信】
リアルタイムリモートデバッグ環境によるゲーム開発イテレーションの高速化【DeNA TechCon 2020 ライブ配信】
 
MOV の機械学習システムを支える MLOps 実践【DeNA TechCon 2020 ライブ配信】
MOV の機械学習システムを支える MLOps 実践【DeNA TechCon 2020 ライブ配信】MOV の機械学習システムを支える MLOps 実践【DeNA TechCon 2020 ライブ配信】
MOV の機械学習システムを支える MLOps 実践【DeNA TechCon 2020 ライブ配信】
 
コンピュータビジョン技術の実応用〜DRIVE CHARTにおける脇見・車間距離不足検知〜【DeNA TechCon 2020 ライブ配信】
コンピュータビジョン技術の実応用〜DRIVE CHARTにおける脇見・車間距離不足検知〜【DeNA TechCon 2020 ライブ配信】コンピュータビジョン技術の実応用〜DRIVE CHARTにおける脇見・車間距離不足検知〜【DeNA TechCon 2020 ライブ配信】
コンピュータビジョン技術の実応用〜DRIVE CHARTにおける脇見・車間距離不足検知〜【DeNA TechCon 2020 ライブ配信】
 
DeNA の Slack 導入と活用の事例紹介
DeNA の Slack 導入と活用の事例紹介DeNA の Slack 導入と活用の事例紹介
DeNA の Slack 導入と活用の事例紹介
 
タクシーxAIを支えるKubernetesとAIデータパイプラインの信頼性の取り組みについて [SRE NEXT 2020]
タクシーxAIを支えるKubernetesとAIデータパイプラインの信頼性の取り組みについて [SRE NEXT 2020]タクシーxAIを支えるKubernetesとAIデータパイプラインの信頼性の取り組みについて [SRE NEXT 2020]
タクシーxAIを支えるKubernetesとAIデータパイプラインの信頼性の取り組みについて [SRE NEXT 2020]
 
オートモーティブ領域における 位置情報関連アルゴリズムあれこれ
オートモーティブ領域における 位置情報関連アルゴリズムあれこれオートモーティブ領域における 位置情報関連アルゴリズムあれこれ
オートモーティブ領域における 位置情報関連アルゴリズムあれこれ
 
後部座席タブレットにおけるMaaS時代を見据えた半歩先のUX設計」 [MOBILITY:dev]
後部座席タブレットにおけるMaaS時代を見据えた半歩先のUX設計」 [MOBILITY:dev]後部座席タブレットにおけるMaaS時代を見据えた半歩先のUX設計」 [MOBILITY:dev]
後部座席タブレットにおけるMaaS時代を見据えた半歩先のUX設計」 [MOBILITY:dev]
 
ドライブレコーダ映像からの3次元空間認識 [MOBILITY:dev]
ドライブレコーダ映像からの3次元空間認識 [MOBILITY:dev]ドライブレコーダ映像からの3次元空間認識 [MOBILITY:dev]
ドライブレコーダ映像からの3次元空間認識 [MOBILITY:dev]
 
MOVで実践したサーバーAPI実装の超最適化について [MOBILITY:dev]
MOVで実践したサーバーAPI実装の超最適化について [MOBILITY:dev]MOVで実践したサーバーAPI実装の超最適化について [MOBILITY:dev]
MOVで実践したサーバーAPI実装の超最適化について [MOBILITY:dev]
 
MOV お客さま探索ナビの GCP ML開発フローについて
MOV お客さま探索ナビの GCP ML開発フローについてMOV お客さま探索ナビの GCP ML開発フローについて
MOV お客さま探索ナビの GCP ML開発フローについて
 
課題ドリブン、フルスタックAI開発術 [MOBILITY:dev]
課題ドリブン、フルスタックAI開発術 [MOBILITY:dev]課題ドリブン、フルスタックAI開発術 [MOBILITY:dev]
課題ドリブン、フルスタックAI開発術 [MOBILITY:dev]
 
DeNA の AWS アカウント管理とセキュリティ監査自動化
DeNA の AWS アカウント管理とセキュリティ監査自動化DeNA の AWS アカウント管理とセキュリティ監査自動化
DeNA の AWS アカウント管理とセキュリティ監査自動化
 

Recently uploaded

Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
WSO2
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
panagenda
 

Recently uploaded (20)

Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 
Six Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal OntologySix Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal Ontology
 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
 
Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with Milvus
 
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
CNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In PakistanCNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In Pakistan
 
Platformless Horizons for Digital Adaptability
Platformless Horizons for Digital AdaptabilityPlatformless Horizons for Digital Adaptability
Platformless Horizons for Digital Adaptability
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 

ヘルスケアサービスを実現する最新技術 〜HealthKit・GCP + Goの活用〜

  • 1.
  • 2. 2
  • 3. 3
  • 4. 4
  • 5. 5
  • 6. 6
  • 7. 7
  • 8. 8
  • 9. 9
  • 10.
  • 11. 11
  • 12. 12
  • 13. 13
  • 14. 14
  • 15. 15
  • 16. 16
  • 17. 17
  • 18. 18
  • 19.
  • 20. 20
  • 21. 21
  • 22. import UIKit import HealthStore class ViewController: UIViewController { private let healthStore = HealthStore() override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. } } 22
  • 23. guard let healthStore = healthStore else { return } guard let type = HKQuantityType.quantityType(forIdentifier: .stepCount) else { return } let builder = DailyQueryBuilder(quantityType: type) healthStore.requestSources(from: Date.startOfToday(), to: Date(), builder: builder) { (sources: [StepSource]?) in if let sources = sources { print("sources: (sources)”) } else { print("step sources are not found.”) } } 23
  • 24. guard let healthStore = healthStore else { return } guard let type = HKQuantityType.quantityType(forIdentifier: .stepCount) else { return } let builder = DailyQueryBuilder(quantityType: type) healthStore.requestSources(from: Date.startOfToday(), to: Date(), builder: builder) { (sources: [StepSource]?) in if let sources = sources { print("sources: (sources)”) } else { print("step sources are not found.”) } } 24
  • 25. guard let healthStore = healthStore else { return } guard let type = HKQuantityType.quantityType(forIdentifier: .stepCount) else { return } let builder = DailyQueryBuilder(quantityType: type) healthStore.requestSources(to: Date(), builder: builder) { (sources: [StepSource]?) in if let sources = sources { print("sources: (sources)”) } else { print("step sources are not found.”) } } 25
  • 26. guard let healthStore = healthStore else { return } guard let type = HKQuantityType.quantityType(forIdentifier: .stepCount) else { return } let builder = DailyQueryBuilder(quantityType: type) healthStore.observeSourceUpdates(from: Date(), builder: builder, handler: { (sources: [StepSource]?) in if let sources = sources { print("sources: (sources)") } else { print("step sources are not found.") } }) 26
  • 27. guard let healthStore = healthStore else { return } guard let type = HKQuantityType.quantityType(forIdentifier: .stepCount) else { return } let builder = RestrictedSourceQueryBuilder(quantityType: type) healthStore.requestSources(from: Date.startOfToday(), to: Date(), builder: builder) { (sources: [StepSource]?) in if let sources = sources { print("sources: (sources)”) } else { print("step sources are not found.”) } } 27
  • 28. 28
  • 29. import HealthKit public protocol HealthStoreQueryBuildable { var quantityType: HKQuantityType { get } var typesToWrite: Set<HKSampleType>? { get } var typesToRead: Set<HKObjectType>? { get } var options: HKStatisticsOptions { get } var anchorDate: Date { get } var intervalComponents: DateComponents { get } var predicates: [NSPredicate] { get } func build() -> HKStatisticsCollectionQuery? func build(completion: @escaping (HKStatisticsCollectionQuery?) -> Void) } 29
  • 30. public extension HealthStoreQueryBuildable { var typesToWrite: Set<HKSampleType>? { return nil } var typesToRead: Set<HKObjectType>? { return nil } func build() -> HKStatisticsCollectionQuery? { let predicate = NSCompoundPredicate(andPredicateWithSubpredicates: predicates) return HKStatisticsCollectionQuery( quantityType: quantityType, quantitySamplePredicate: predicate, options: options, anchorDate: anchorDate, intervalComponents: intervalComponents) } func build(completion: @escaping (HKStatisticsCollectionQuery?) -> Void) { completion(build()) } } 30
  • 31. public struct DailyQueryBuilder: HealthStoreQueryBuildable { public let quantityType: HKQuantityType public var typesToRead: Set<HKObjectType>? { return [quantityType] } public let options: HKStatisticsOptions = .cumulativeSum public let anchorDate: Date public let intervalComponents: DateComponents = DateComponents(day: 1) public let predicates: [NSPredicate] = [] public init(quantityType: HKQuantityType, anchorDate: Date = Date.startOfToday()) { self.quantityType = quantityType self.anchorDate = anchorDate } } 31
  • 32. public class RestrictedSourceQueryBuilder: HealthStoreQueryBuildable { public func build(completion: @escaping (HKStatisticsCollectionQuery?) -> Void) { guard let provider = HealthSourceProvider() else { completion(nil) return } provider.appleSources(sampleType: quantityType) { (sources, error) in if let error = error { print(error) } guard let sources = sources else { completion(nil) return } // update predicates let metadataPredicate = HKQuery.predicateForObjects(withMetadataKey: HKMetadataKeyWasUserEntered, operatorType: .notEqualTo, value: true) let sourcePredicate = HKQuery.predicateForObjects(from: sources) self.predicates = [metadataPredicate, sourcePredicate] // build query completion(self.build()) } } } 32
  • 33. 33
  • 34. 34
  • 35. 35
  • 36. 36
  • 37.
  • 38. 38
  • 41. 41
  • 42. 42
  • 43. 43
  • 44. 44
  • 45. 45
  • 46. 46
  • 47. 47 var ( ErrNoSuchUser = errors.New("...") ) type Repository interface { Get(id string) (*User, error) } var NewRepository func(context.Context) Repository domain/user/repository.go
  • 48. 48
  • 49. 49 type userRepository struct { Ctx context.Context } func NewUserRepository(ctx context.Context) user.Repository { return &userRepository{ Ctx: ctx, } } func (r *userRepository) Get(id string) (*user.User, error) { // ... } infrastructure/persistence/datastore/user_repository.go
  • 50. 50 func init() { user.NewRepository = datastore.NewUserRepository } func main() { repo := user.NewRepository(ctx) // datastore.userRepository }
  • 51. 51 type userRepository struct { Ctx context.Context } func NewUserRepository(ctx context.Context) user.Repository { return &userRepository{ Ctx: ctx, } } func (r *userRepository) Get(id string) (*user.User, error) { // ... } infrastructure/persistence/mock/user_repository.go
  • 52. 52 func TestMain(m *testing.M) { user.NewRepository = mock.NewUserRepository m.Run() }
  • 54.
  • 55.
  • 56.
  • 57.
  • 58. 58
  • 59. 59 func Namespacer(h http.HandlerFunc) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { // treat an error! ctx, _ := appengine.Namespace(r.Context(), "Namespace-a") h(w, r.WithContext(ctx)) } } Middleware
  • 60.
  • 61.
  • 62.
  • 63. 63
  • 65.
  • 76. 76