Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
ヘッドジェスチャを検知して Vibe Cooking - iOSDC Japan 2025
Search
Kanta Oikawa
September 20, 2025
720
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
ヘッドジェスチャを検知して Vibe Cooking - iOSDC Japan 2025
Kanta Oikawa
September 20, 2025
More Decks by Kanta Oikawa
See All by Kanta Oikawa
2027年のMetricKit
kantacky
0
250
はじめてのCoreSpotlight
kantacky
0
190
もう怖くないバックグラウンド処理 Background Tasks のすべて - Hakodate.swift #1
kantacky
0
560
Featured
See All Featured
A brief & incomplete history of UX Design for the World Wide Web: 1989–2019
jct
2
530
HDC tutorial
michielstock
2
960
Java REST API Framework Comparison - PWX 2021
mraible
34
9.8k
How STYLIGHT went responsive
nonsquared
100
6.3k
How To Speak Unicorn (iThemes Webinar)
marktimemedia
1
600
sira's awesome portfolio website redesign presentation
elsirapls
0
450
Code Review Best Practice
trishagee
74
20k
Un-Boring Meetings
codingconduct
0
460
The Hidden Cost of Media on the Web [PixelPalooza 2025]
tammyeverts
2
520
How to Build an AI Search Optimization Roadmap - Criteria and Steps to Take #SEOIRL
aleyda
1
2.2k
Leadership Guide Workshop - DevTernity 2021
reverentgeek
1
400
How to build a perfect <img>
jonoalderson
1
6.1k
Transcript
Kanta Oikawa - 2025/09/20 ϔουδΣενϟΛݕͯ͠ Vibe Cooking iOSDC Japan 2025
Day 1 Track A 1
͓͍͍͠ྉཧΛָʹ࡞ͬͯ৯͍ͨ 1ਓΒ͠ͷྉཧॳ৺ऀ • ޮతʹ͡Ό͕ɾਬ͖ࠐΈ͝ΜɾಲोΛ࡞Γ͍ͨ • γϯάϧεϨουͰ • ϨγϐΛݟͳ͕Β࡞Γ͍ͨ • ྉཧதʹiPhoneɾiPadΛ৮Γͨ͘ͳ͍
2
Vibe Cooking • ෳͷϨγϐ͔Β1ͭͷϨγϐΛੜ • ϨγϐͷखॱΛಡΈ্͛ • ಡΈ্͛ΔखॱΛԻͰίϯτϩʔϧ 3
Vibe Cooking x ϔουδΣενϟ • ԻಡΈ্͛ɾίϯτϩʔϧͰڥͷӨڹΛड͚͍͢ • ྉཧத AirPods Λண
• Core Motion Λͬͯ AirPods ͷϞʔγϣϯσʔλΛऔಘՄೳ • ਐΉɾΔૢ࡞ΛϔουδΣενϟͰ 4
AirPods ͰϔουδΣενϟΛݕ͢Δྫ (2024/09) ϔουδΣενϟΛ༻ͯ͠ Siri ʹԠ͢Δ • AirPods Pro 2·ͨAirPods
4ʢ྆ϞσϧʣΛ͓࣋ͪͰɺʮԻͰண৴Λ ΒͤΔʯͱʮ௨ͷಡΈ্͛ʯΛΦϯʹ͍ͯ͠Δ߹ɺ·ͨखΛΘ ͣʹɺϔουδΣενϟΛ༻ͯ͠ɺ௨Λड͚ͨΓڋ൱ͨ͠Γɺ௨Λ։͍ ͨΓดͨ͡Γ͢Δ͜ͱͰ͖·͢ɻ • ϔουδΣενϟΛ༻ͯ͠SiriʹԠ͢Δ • ిʹग़Δɺ·ͨ௨ͱϝοηʔδʹฦ৴͢Δ: ᰐ͖·͢ɻ • ిΛڋ൱͢Δɺ·ͨ௨ͱϝοηʔδΛด͡Δ: टΛࠨӈʹৼΓ·͢ɻ 5 AirPodsͰίϯτϩʔϧͱδΣενϟΛ༻͢Δ - Apple αϙʔτʢຊʣ https://support.apple.com/ja-jp/guide/airpods/devb2c431317 (Accessed on 2025/09/12)
UX ઃܭ 6 30° ͪ͜ΒΛ͍ͯ͏ͳͣ͘ͱ ӈʹεϫΠϓ ͪ͜ΒΛ͍ͯ͏ͳͣ͘ͱ ࠨʹεϫΠϓ
͍͍ͯΔํΛݕ͢Δ final class HeadphoneMotionRepository: NSObject, CMHeadphoneMotionManagerDelegate, Sendable { private let
manager: CMHeadphoneMotionManager override init() { ... } func startTracking(queue: OperationQueue? = .current) throws -> AsyncStream<CMDeviceMotion> { guard manager.isDeviceMotionAvailable else { throw HeadphoneMotionRepositoryError.deviceMotionNotAvailable } return AsyncStream { continuation in manager.startDeviceMotionUpdates(to: queue ?? .main) { motion, error in guard let motion else { return } continuation.yield(motion) } } } ... } 7
͍͍ͯΔํΛݕ͢Δ for await motion in try motionService.startTracking() { state.motion =
motion } ... if abs(state.motion?.attitude.yaw ?? 0) > .pi / 12 { // π / 12 = 15° ... } 8 yaw | Apple Developer Documentation https://developer.apple.com/documentation/coremotion/cmattitude/yaw (Accessed on 2025/09/20)
͏ͳ͖ͣδΣενϟΛݕ͢Δ 1. ͏ͳ͖ͣδΣενϟͷϞʔγϣϯσʔλΛऩू͢Δ 2. ϞʔγϣϯσʔλΛֶशͯ͠ Core ML ϞσϧΛ࡞͢Δ 3. ϞσϧΛͬͯ͏ͳ͖ͣδΣενϟΛݕ͢Δ
9
͏ͳ͖ͣδΣενϟΛݕ͢Δ 1. ͏ͳ͖ͣδΣενϟͷϞʔγϣϯσʔλΛऩू͢Δ • ͏ͳͣ͘δΣενϟ ͱ ͦΕҎ֎ͷδΣενϟ ͷ 2 Ϋϥε
• CMDeviceMotion ʹؚ·ΕΔΛ CSV ϑΝΠϧʹॻ͖ࠐΈ • attitude_roll, attitude_pitch, attitude_yaw, gravity_x, gravity_y, gravity_z, quaternion_x, quaternion_y, quaternion_z, quaternion_w, rotation_rate_x, rotation_rate_y, rotation_rate_z, user_acceleration_x, user_acceleration_y, user_acceleration_z • ͻͨ͢Β͏ͳͣ͘ 10
͏ͳ͖ͣδΣενϟΛݕ͢Δ 1. ͏ͳ͖ͣδΣενϟͷϞʔγϣϯσʔλΛऩू͢Δ 11
͏ͳ͖ͣδΣενϟΛݕ͢Δ 2. ϞʔγϣϯσʔλΛֶशͯ͠ Core ML ϞσϧΛ࡞͢Δ 12
͏ͳ͖ͣδΣενϟΛݕ͢Δ 3. ϞσϧΛͬͯ͏ͳ͖ͣδΣενϟΛݕ͢Δ let configuration = MLModelConfiguration() let model =
try HeadGestureClassifier(configuration: configuration) let input = HeadGestureClassifierInput( rotation_rate_x: try MLMultiArray(motions.map { $0.rotationRate.x }), stateIn: try MLMultiArray(shape: [400], dataType: .double) ) let output = try model.prediction(input: input) return Gesture(rawValue: output.label) ?? .idle ... enum Gesture: String { case idle case nod ... } 13
σϞ 14
ͬͯΈͨײɾߟ • टΛಈ͔͢ͷ͕ͭΒ͍ • খ͞ͳಈ͖ͰݕͰ͖Δײ • ޡݕ͠ͳ͍ਫ਼ • ϑΟʔυόοΫ͕΄͍͠ •
Siri ͷԠ࣌ʹ "Χνο"ͱ͍͏ԻʢʁʣͷϑΟʔυόοΫ 15
࣮ͯ͠Έͨײ • Core Motion ͱ Core ML ΛΈ߹ΘͤͯδΣενϟݕ͕؆୯ʹ࣮Ͱ͖ͨ • ML
ʹؔ͢Δߴͳ͕ࣝͳͯ͘؆୯ʹϞσϧΛ࡞Δ͜ͱ͕Ͱ͖Δ • ͕ࣝ͋Εਫ਼্͕͕Γͦ͏ • CMDeviceMotionͷͦΕͧΕͷ͕ҙຯ͢Δ͜ͱΛཧղ͢Δ͜ͱ͕ॏཁ 16
Vibe Cooking Coming this fall 17
Kanta Oikawa Kantacky • ެཱͩͯ͜ະདྷେֶ M1 • ઈࢍब׆தʂʂ • GitHub:
@kantacky • Twitter: @kanta_cky 18