Slide 1

Slide 1 text

AccessorySetupKitͰ࣮ݱ͢Δ γʔϜϨεͳϖΞϦϯάମݧ @nekowen iOSDC Japan 2025 Day 0 18:30 ʙ

Slide 2

Slide 2 text

ࣗݾ঺հ nekowen (Ͷ͜͏͐Μ) STORES גࣜձࣾ ॴଐ iOS ΞϓϦΤϯδχΞ Bluetooth σόΠεͱ͔εϚʔτϗʔϜʹ ڵຯ͕͋Γ·͢

Slide 3

Slide 3 text

օ͞Μʹ࣭໰ʂ🙋

Slide 4

Slide 4 text

Bluetooth σόΠεͱͷϖΞϦϯά΍ ઀ଓϑϩʔΛվળ͍ͨ͠ͱࢥͬͨ͜ͱ͸͋Γ·ͤΜ͔ʁ

Slide 5

Slide 5 text

AccessorySetupKit Λ࢖͏͜ͱͰ࣮ݱͰ͖Δ͔΋͠Ε·ͤΜ

Slide 6

Slide 6 text

Bluetooth σόΠεʁ

Slide 7

Slide 7 text

਎ۙʹᷓΕΔແઢσόΠε ΢ΣΞϥϒϧσόΠε εϚʔτ΢Υον εϚʔτάϥε εϚʔττϥοΧʔ εϚʔτϗʔϜؔ࿈ εϚʔτϩοΫ ੺֎ઢϦϞίϯ Թ࣪౓ܭ εϚʔτిٿ ϖοτΧϝϥ etc…

Slide 8

Slide 8 text

Bluetooth Classic(BR/EDR/HS) Bluetooth Low Energy(BLE) ɾैདྷ͔Β͋Δඪ४తͳن֨ ɾ࠷େ 3Mbps ͷσʔλసૹ଎౓ ɾϖΞϦϯά͸ඞਢ ɾফඅిྗ͕ߴ͍ ɾBluetooth 4.0 ͔Βొ৔ ɾ࠷େ 1 - 2Mbps ͷσʔλసૹ଎౓ ɾϖΞϦϯά͸೚ҙ ɾফඅిྗ͕௿͍ Bluetooth ʹ͍ͭͯ

Slide 9

Slide 9 text

εϚʔτϑΥϯͱͷ࿈ܞύλʔϯ ΞϓϦͱ௚઀௨৴͢ΔλΠϓ e.g. ϑΟοτωετϥοΧʔɺԹ౓ܭͳͲ Bluetooth LE ܦ༝

Slide 10

Slide 10 text

σόΠεͷηοτΞοϓʹར༻͢ΔλΠϓ e.g. ϖοτΧϝϥɺ੺֎ઢϦϞίϯͳͲ Bluetooth LE ܦ༝ ※ηοτΞοϓͷΈ Wi-Fi ܦ༝ εϚʔτϑΥϯͱͷ࿈ܞύλʔϯ

Slide 11

Slide 11 text

Bluetooth σόΠεͱͷ ϖΞϦϯάɾ઀ଓମݧͷ՝୊Λਂ۷Δ

Slide 12

Slide 12 text

No content

Slide 13

Slide 13 text

ڐՄΛλοϓ

Slide 14

Slide 14 text

ڐՄΛλοϓ ݕग़͞ΕͨσόΠεΛ λοϓ

Slide 15

Slide 15 text

ڐՄΛλοϓ ݕग़͞ΕͨσόΠεΛ λοϓ (ϖΞϦϯάඞਢͷ৔߹) ϖΞϦϯάڐՄɺ΋͘͠͸ύείʔυΛೖྗ

Slide 16

Slide 16 text

ڐՄΛλοϓ ݕग़͞ΕͨσόΠεΛ λοϓ (ϖΞϦϯάඞਢͷ৔߹) ϖΞϦϯάڐՄɺ΋͘͠͸ύείʔυΛೖྗ

Slide 17

Slide 17 text

ڐՄΛλοϓ ݕग़͞ΕͨσόΠεΛ λοϓ (ϖΞϦϯάඞਢͷ৔߹) ϖΞϦϯάڐՄɺ΋͘͠͸ύείʔυΛೖྗ

Slide 18

Slide 18 text

Ϣʔβʔ໨ઢ • ڐՄ͢ΔͨΊͷ൑அίετ͕͔͔Δ ։ൃऀ໨ઢ • ΞϥʔτΛग़͢λΠϛϯά͕೉͍͠ • ڐՄ͞Εͳ͔ͬͨ࣌ͷϋϯυϦϯά͕ඞཁ • ઃఆʹભҠͤ͞Δʁ Core Bluetooth API ͷར༻ʹϢʔβʔڐՄ͕ඞཁ

Slide 19

Slide 19 text

εϙοτͰ͔͠εΩϟϯΛར༻͠ͳ͍৔߹Ͱ΋ݖݶ͸ඞ ཁͱͳΔ → Ҏ߱ΞϓϦͰεΩϟϯ͕ෆཁͩͱͯ͠΋ʮڐՄʯͷঢ় ଶ͕࢒Γଓ͚Δ ݖݶͷ࢒ଘ = ϢʔβʔʹͱͬͯϓϥΠόγʔ্ͷϦεΫ ݖݶͷ࢒ଘ໰୊

Slide 20

Slide 20 text

༷ʑͳέΞ͕ඞཁʹͳΔ͜ͱ΋ɻ • Bluetooth͕Φϑʹͳ͍ͬͯͨ৔߹ • BluetoothσόΠε͕ݟ͚ͭΒΕͳ͍৔߹ ଞʹ΋…

Slide 21

Slide 21 text

• Bluetooth ར༻ڐՄ͕ඞཁ • ݖݶ͕࢒ଘ͠ଓ͚ΔʢʹϓϥΠόγʔϦεΫʣ • BluetoothΦϑɺσόΠε͕ݟ͔ͭΒͳ͍…ͱ͍༷ͬͨʑͳέΞ͕ඞཁ ·ͱΊΔͱ

Slide 22

Slide 22 text

ref: https://developer.apple.com/videos/play/wwdc2024/10203/

Slide 23

Slide 23 text

AccessorySetupKit ͱ͸Կ͔ • iOS18 ͔Βొ৔ͨ͠ϑϨʔϜϫʔΫ • ϓϥΠόγʔΛอͬͨ·· Bluetooth/WiFi Λར༻ ͨ͠σόΠεͷݕग़ɾϖΞϦϯάॲཧΛ୲͏ • ΞΫηαϦ͕௥Ճ͞Εͨޙ͸ɺCore Bluetooth ΁ ઀ଓॲཧͷҾ͖ܧ͕͗Մೳ ref: https://developer.apple.com/videos/play/wwdc2024/10203/

Slide 24

Slide 24 text

εΩϟϯͷݖݶڐՄ͕ෆཁ • σόΠεͷεΩϟϯʹඞཁͩͬͨݖݶͷڐՄ͕ෆཁ • γʔτ্ͰʮઃఆʯʹਐΉ͔ ϢʔβʔʹਘͶΒΕΔ

Slide 25

Slide 25 text

઀ଓϑϩʔ͕౷Ұ͞ΕΔ • σόΠεͱͷ઀ଓʹඞཁͳॲཧɾUI ΛϑϨʔϜϫʔΫ ଆ͕ఏڙ͢Δ • Bluetooth LE σόΠεͷεΩϟϯ • ݟ͔ͭͬͨσόΠεͷબ୒ • (PIN ίʔυ͕ඞཁͳ৔߹) PIN ίʔυͷೖྗ • ϖΞϦϯάɾϘϯσΟϯά

Slide 26

Slide 26 text

ઃఆΞϓϦͰʮΞΫηαϦʯͱͯ͠؅ཧՄೳ • ηοτΞοϓ͞ΕͨσόΠε͸ ʮΞΫηαϦʯͱͯ͠ɺiOS ͷ ઃఆΞϓϦ͔Β؅ཧՄೳ • ΞϓϦ͔Β੡඼໊ɾ੡඼ը૾Λ౉͢ͱɺ ઃఆΞϓϦ͔Β΋ݟ͑ΔΑ͏ʹͳΔ • Bluetooth ໊͔Β੡඼Λਪଌ͢Δඞཁ ͕ͳ͘ɺҰ໨ྎવ

Slide 27

Slide 27 text

• Bluetooth ར༻ڐՄ͕ඞཁ • ݖݶ͕࢒ଘ͠ଓ͚ΔʢʹϓϥΠόγʔϦεΫʣ • BluetoothΦϑɺσόΠε͕ݟ͔ͭΒͳ͍…ͱ͍༷ͬͨʑͳέΞ͕ඞཁ (લ߲)·ͱΊΔͱ…

Slide 28

Slide 28 text

• Bluetooth ར༻ڐՄ͕ඞཁ • ݖݶ͕࢒ଘ͠ଓ͚ΔʢʹϓϥΠόγʔϦεΫʣ • BluetoothΦϑɺσόΠε͕ݟ͔ͭΒͳ͍…ͱ͍༷ͬͨʑͳέΞ͕ඞཁ → AccessorySetupKit ͰղܾͰ͖ͦ͏ʂ΍ͬͨͶʂ (લ߲)·ͱΊΔͱ…

Slide 29

Slide 29 text

AccessorySetupKit Λ࢖ͬͨ৔߹ͷϖΞϦϯάϑϩʔ

Slide 30

Slide 30 text

No content

Slide 31

Slide 31 text

ઃఆΛλοϓ

Slide 32

Slide 32 text

(ϖΞϦϯάͰඞཁͰ͋Ε͹) PINίʔυΛೖྗ͢Δ ઃఆΛλοϓ

Slide 33

Slide 33 text

(ϖΞϦϯάͰඞཁͰ͋Ε͹) PINίʔυΛೖྗ͢Δ ΞϓϦͰଓ͚ΔΛλοϓ ઃఆΛλοϓ

Slide 34

Slide 34 text

(ϖΞϦϯάͰඞཁͰ͋Ε͹) PINίʔυΛೖྗ͢Δ ΞϓϦͰଓ͚ΔΛλοϓ ઃఆΛλοϓ

Slide 35

Slide 35 text

AccessorySetupKit Λ࢖ͬͯΈΑ͏

Slide 36

Slide 36 text

…ͷલʹ

Slide 37

Slide 37 text

AccessorySetupKit ͰεΩϟϯͰ͖Δ৚݅ • ҎԼͷ͍ͣΕ͔ͷ AD Structure ΛΞυόλΠζ͢Δ͜ͱ • Service UUID • Company ID (Manufacture Speci f ic Data)

Slide 38

Slide 38 text

ࣗ෼͸͜͜ʹ͍ΔΑʂ Service UUID: xxxx-xxxx Local Name: BLE-Demo Manufacture Speci f ic Data: … ΞυόλΠζͱ͸ ઀ଓର৅ͷσόΠεͩͳʂϤγʂ

Slide 39

Slide 39 text

AccessorySetupKit Λར༻ͯ͠ ϖΞϦϯάΛߦ͏

Slide 40

Slide 40 text

AccessorySetupKit Λ࢖ͬͨϖΞϦϯάखॱ 1. Info.plist ͷઃఆ 2. ASAccessorySession ͷ activate ϝιουͰΠϕϯτͷ ϋϯυϦϯάΛ࣮૷ 3. ઀ଓ͢ΔσόΠε৘ใΛ ASDiscoveryDescriptor ʹࢦఆ 4. showPicker ϝιουΛݺͼग़͢

Slide 41

Slide 41 text

AccessorySetupKit Λ࢖ͬͨϖΞϦϯάखॱ 1. Info.plist ͷઃఆ 2. ASAccessorySession ͷ activate ϝιουͰΠϕϯτͷ ϋϯυϦϯάΛ࣮૷ 3. ઀ଓ͢ΔσόΠε৘ใΛ ASDiscoveryDescriptor ʹࢦఆ 4. showPicker ϝιουΛݺͼग़͢

Slide 42

Slide 42 text

NSAccessorySetupKitSupports Bluetooth NSAccessorySetupBluetoothCompanyIdentifiers XXXX NSAccessorySetupBluetoothServices 181C NSAccessorySetupBluetoothNames BLE

Slide 43

Slide 43 text

NSAccessorySetupKitSupports Bluetooth NSAccessorySetupBluetoothCompanyIdentifiers XXXX NSAccessorySetupBluetoothServices 181C NSAccessorySetupBluetoothNames BLE

Slide 44

Slide 44 text

NSAccessorySetupKitSupports Bluetooth NSAccessorySetupBluetoothCompanyIdentifiers XXXX NSAccessorySetupBluetoothServices 181C NSAccessorySetupBluetoothNames BLE Bluetooth SIGͷϝϯόʔاۀʹׂΓ౰ͯΒΕΔݻ༗൪߸(೚ҙ)

Slide 45

Slide 45 text

NSAccessorySetupKitSupports Bluetooth NSAccessorySetupBluetoothCompanyIdentifiers XXXX NSAccessorySetupBluetoothServices 181C NSAccessorySetupBluetoothNames BLE ΞυόλΠζ͞ΕΔService UUID(୹ॖUUID΋Մ)

Slide 46

Slide 46 text

NSAccessorySetupKitSupports Bluetooth NSAccessorySetupBluetoothCompanyIdentifiers XXXX NSAccessorySetupBluetoothServices 181C NSAccessorySetupBluetoothNames BLE Bluetooth໊Λࢦఆ ෦෼Ұக

Slide 47

Slide 47 text

AccessorySetupKit Λ࢖ͬͨϖΞϦϯάखॱ 1. Info.plist ͷઃఆ 2. ASAccessorySession ͷ activate ϝιουͰΠϕϯτͷ ϋϯυϦϯάΛ࣮૷ 3. ઀ଓ͢ΔσόΠε৘ใΛ ASDiscoveryDescriptor ʹࢦఆ 4. showPicker ϝιουΛݺͼग़͢

Slide 48

Slide 48 text

// MARK: - Accessory Setup private let session = ASAccessorySession() private var currentAccessory: ASAccessory? // MARK: - AccessorySession session.activate(on: DispatchQueue.main) { [weak self] (event: ASAccessoryEvent) in guard let self else { return } switch event.eventType { case .activated: if let accessory = session.accessories.first { // ͢ͰʹηοτΞοϓࡁΈͰ͋Ε͹ɺͦͷΞΫηαϦΛ࢖ͬͯ઀ଓॲཧΛߦ͏ self.currentAccessory = accessory self.handleAccessoryAdded(accessory) } case .accessoryAdded: // ΞΫηαϦ͕௥Ճ͞Εͨ(ηοτΞοϓ͞Εͨ) self.currentAccessory = event.accessory case .pickerDidDismiss: // ϐοΧʔ͕ด͡ΒΕͨ guard let currentAccessory else { return } handleAccessoryAdded(currentAccessory) self.currentAccessory = nil case .pickerSetupFailed: // ԿΒ͔ͷཧ༝ʹΑΓηοτΞοϓʹࣦഊͨ͠(ύείʔυͷෆҰகͳͲ) ... } }

Slide 49

Slide 49 text

// MARK: - Accessory Setup private let session = ASAccessorySession() private var currentAccessory: ASAccessory? // MARK: - AccessorySession session.activate(on: DispatchQueue.main) { [weak self] (event: ASAccessoryEvent) in guard let self else { return } switch event.eventType { case .activated: if let accessory = session.accessories.first { // ͢ͰʹηοτΞοϓࡁΈͰ͋Ε͹ɺͦͷΞΫηαϦΛ࢖ͬͯ઀ଓॲཧΛߦ͏ self.currentAccessory = accessory self.handleAccessoryAdded(accessory) } case .accessoryAdded: // ΞΫηαϦ͕௥Ճ͞Εͨ(ηοτΞοϓ͞Εͨ) self.currentAccessory = event.accessory case .pickerDidDismiss: // ϐοΧʔ͕ด͡ΒΕͨ guard let currentAccessory else { return } handleAccessoryAdded(currentAccessory) self.currentAccessory = nil case .pickerSetupFailed: // ԿΒ͔ͷཧ༝ʹΑΓηοτΞοϓʹࣦഊͨ͠(ύείʔυͷෆҰகͳͲ) ... } } activateϝιουΛݺΜͩ࣌ɺ࠷ॳʹݺ͹ΕΔ

Slide 50

Slide 50 text

// MARK: - Accessory Setup private let session = ASAccessorySession() private var currentAccessory: ASAccessory? // MARK: - AccessorySession session.activate(on: DispatchQueue.main) { [weak self] (event: ASAccessoryEvent) in guard let self else { return } switch event.eventType { case .activated: if let accessory = session.accessories.first { // ͢ͰʹηοτΞοϓࡁΈͰ͋Ε͹ɺͦͷΞΫηαϦΛ࢖ͬͯ઀ଓॲཧΛߦ͏ self.currentAccessory = accessory self.handleAccessoryAdded(accessory) } case .accessoryAdded: // ΞΫηαϦ͕௥Ճ͞Εͨ(ηοτΞοϓ͞Εͨ) self.currentAccessory = event.accessory case .pickerDidDismiss: // ϐοΧʔ͕ด͡ΒΕͨ guard let currentAccessory else { return } handleAccessoryAdded(currentAccessory) self.currentAccessory = nil case .pickerSetupFailed: // ԿΒ͔ͷཧ༝ʹΑΓηοτΞοϓʹࣦഊͨ͠(ύείʔυͷෆҰகͳͲ) ... } } ΞΫηαϦ͕௥Ճ͞ΕͨΒݱࡏͷΞΫηαϦΛอ࣋ ʢ͜ͷ࣌·ͩγʔτ͸දࣔ͞Ε͍ͯΔ)

Slide 51

Slide 51 text

// MARK: - Accessory Setup private let session = ASAccessorySession() private var currentAccessory: ASAccessory? // MARK: - AccessorySession session.activate(on: DispatchQueue.main) { [weak self] (event: ASAccessoryEvent) in guard let self else { return } switch event.eventType { case .activated: if let accessory = session.accessories.first { // ͢ͰʹηοτΞοϓࡁΈͰ͋Ε͹ɺͦͷΞΫηαϦΛ࢖ͬͯ઀ଓॲཧΛߦ͏ self.currentAccessory = accessory self.handleAccessoryAdded(accessory) } case .accessoryAdded: // ΞΫηαϦ͕௥Ճ͞Εͨ(ηοτΞοϓ͞Εͨ) self.currentAccessory = event.accessory case .pickerDidDismiss: // ϐοΧʔ͕ด͡ΒΕͨ guard let currentAccessory else { return } handleAccessoryAdded(currentAccessory) self.currentAccessory = nil case .pickerSetupFailed: // ԿΒ͔ͷཧ༝ʹΑΓηοτΞοϓʹࣦഊͨ͠(ύείʔυͷෆҰகͳͲ) ... } } γʔτ͕ด͡ΒΕͨͷͰ઀ଓॲཧΛߦ͏

Slide 52

Slide 52 text

// MARK: - CoreBluetooth private var central: CBCentralManager? // AccessorySetupKit ͰΞΫηαϦ͕௥Ճ͞Εͨ࣌ʹݺ͹ΕΔϝιου private func handleAccessoryAdded(_ accessory: ASAccessory) { // Bluetooth IDΛऔಘ guard let bluetoothIdentifier = accessory.bluetoothIdentifier else { return } // CBCentralManager͕ະॳظԽͳΒॳظԽ͢Δ if central == nil { central = CBCentralManager(delegate: self, queue: nil) } // Bluetooth ID͔ΒCBPeripheralΛऔಘ͢Δ let peripherals = central?.retrievePeripherals(withIdentifiers: [bluetoothIdentifier]) // ֘౰ͷPeripheral͕ଘࡏ͍ͯ͠Ε͹઀ଓ͢Δ if let peripheral = peripherals?.first { bleConnect(peripheral) } }

Slide 53

Slide 53 text

// MARK: - CoreBluetooth private var central: CBCentralManager? // AccessorySetupKit ͰΞΫηαϦ͕௥Ճ͞Εͨ࣌ʹݺ͹ΕΔϝιου private func handleAccessoryAdded(_ accessory: ASAccessory) { // Bluetooth IDΛऔಘ guard let bluetoothIdentifier = accessory.bluetoothIdentifier else { return } // CBCentralManager͕ະॳظԽͳΒॳظԽ͢Δ if central == nil { central = CBCentralManager(delegate: self, queue: nil) } // Bluetooth ID͔ΒCBPeripheralΛऔಘ͢Δ let peripherals = central?.retrievePeripherals(withIdentifiers: [bluetoothIdentifier]) // ֘౰ͷPeripheral͕ଘࡏ͍ͯ͠Ε͹઀ଓ͢Δ if let peripheral = peripherals?.first { bleConnect(peripheral) } }

Slide 54

Slide 54 text

// MARK: - CoreBluetooth private var central: CBCentralManager? // AccessorySetupKit ͰΞΫηαϦ͕௥Ճ͞Εͨ࣌ʹݺ͹ΕΔϝιου private func handleAccessoryAdded(_ accessory: ASAccessory) { // Bluetooth IDΛऔಘ guard let bluetoothIdentifier = accessory.bluetoothIdentifier else { return } // CBCentralManager͕ະॳظԽͳΒॳظԽ͢Δ if central == nil { central = CBCentralManager(delegate: self, queue: nil) } // Bluetooth ID͔ΒCBPeripheralΛऔಘ͢Δ let peripherals = central?.retrievePeripherals(withIdentifiers: [bluetoothIdentifier]) // ֘౰ͷPeripheral͕ଘࡏ͍ͯ͠Ε͹઀ଓ͢Δ if let peripheral = peripherals?.first { bleConnect(peripheral) } }

Slide 55

Slide 55 text

AccessorySetupKit Λ࢖ͬͨϖΞϦϯάखॱ 1. Info.plist ͷઃఆ 2. ASAccessorySession ͷ activate ϝιουͰΠϕϯτͷ ϋϯυϦϯάΛ࣮૷ 3. ઀ଓ͢ΔσόΠε৘ใΛ ASDiscoveryDescriptor ʹࢦఆ 4. showPicker ϝιουΛݺͼग़͢

Slide 56

Slide 56 text

let descriptor = ASDiscoveryDescriptor() // Company IdentifierΛࢦఆ descriptor.bluetoothCompanyIdentifier = .init(0xFC94) // Advertising Service UUID Λࢦఆ descriptor.bluetoothServiceUUID = .init(string: "181C") // Local Name Λࢦఆ descriptor.bluetoothNameSubstring = "BLE" // ରԠ͢ΔΦϓγϣϯΛࢦఆ descriptor.supportedOptions = [.bluetoothPairingLE, .bluetoothHID]

Slide 57

Slide 57 text

let descriptor = ASDiscoveryDescriptor() // Company IdentifierΛࢦఆ descriptor.bluetoothCompanyIdentifier = .init(0xFC94) // Advertising Service UUID Λࢦఆ descriptor.bluetoothServiceUUID = .init(string: "181C") // Local Name Λࢦఆ descriptor.bluetoothNameSubstring = "BLE" // ରԠ͢ΔΦϓγϣϯΛࢦఆ descriptor.supportedOptions = [.bluetoothPairingLE, .bluetoothHID] bluetoothCompanyIdenti f ier or bluetoothServiceUUID ͲͪΒ͔͸ࢦఆ͕ඞਢ(ࢦఆ͠ͳ͍ͱΫϥογϡ͢Δ)

Slide 58

Slide 58 text

let descriptor = ASDiscoveryDescriptor() // Company IdentifierΛࢦఆ descriptor.bluetoothCompanyIdentifier = .init(0xFC94) // Advertising Service UUID Λࢦఆ descriptor.bluetoothServiceUUID = .init(string: "1812") // Local Name Λࢦఆ descriptor.bluetoothNameSubstring = "M5" // ରԠ͢ΔΦϓγϣϯΛࢦఆ descriptor.supportedOptions = [.bluetoothPairingLE, .bluetoothHID] ϖΞϦϯά͕ඞཁͳσόΠεͰ͋Ε͹ɺbluetoothPairingLEΛࢦఆ

Slide 59

Slide 59 text

let descriptor = ASDiscoveryDescriptor() // Company IdentifierΛࢦఆ descriptor.bluetoothCompanyIdentifier = .init(0xFC94) // Advertising Service UUID Λࢦఆ descriptor.bluetoothServiceUUID = .init(string: "1812") // Local Name Λࢦఆ descriptor.bluetoothNameSubstring = "M5" // ରԠ͢ΔΦϓγϣϯΛࢦఆ descriptor.supportedOptions = [.bluetoothPairingLE, .bluetoothHID] σόΠε͕Bluetooth LE HID(ΩʔϘʔυ΍Ϛ΢εೖྗ)ʹ ରԠ͍ͯ͠Ε͹ bluetoothHID ΋ඞཁ

Slide 60

Slide 60 text

let displayName = “BLE-Demo" let productImage = UIImage(named: “ble-device-image")! let displayItem = ASPickerDisplayItem( name: displayName, productImage: productImage, descriptor: descriptor ) try await session.showPicker(for: [displayItem])

Slide 61

Slide 61 text

let displayName = “BLE-Demo" let productImage = UIImage(named: “ble-device-image")! let displayItem = ASPickerDisplayItem( name: displayName, productImage: productImage, descriptor: descriptor ) try await session.showPicker(for: [displayItem]) ϐοΧʔʹදࣔ͢Δ੡඼໊ͱ੡඼ͷΠϝʔδը૾Λࢦఆ લ߲Ͱઃఆͨ͠ASDiscoveryDescriptor΋౉͢

Slide 62

Slide 62 text

let displayName = “BLE-Demo” let productImage = UIImage(named: “ble-device-image")! let displayItem = ASPickerDisplayItem( name: displayName, productImage: productImage, descriptor: descriptor ) try await session.showPicker(for: [displayItem]) ASAccessorySession ͷ showPicker ϝιουΛݺͼग़͢

Slide 63

Slide 63 text

No content

Slide 64

Slide 64 text

Tips

Slide 65

Slide 65 text

1. CoreBluetooth ͷݖݶ state ͷѻ͍

Slide 66

Slide 66 text

extension BluetoothManager: CBCentralManagerDelegate { func centralManagerDidUpdateState(_ central: CBCentralManager) { switch central.state { case .poweredOn: // Bluetooth ͕Φϯɺ͔ͭ࢖༻ڐՄ͞Ε͍ͯΔ৔߹ case .poweredOff: // Bluetooth ͕Φϑɺ΋͘͠͸ݖݶະ֬ೝͷ৔߹ case .unauthorized: // Bluetooth ͷ࢖༻ڐՄΛڋ൱ͨ͠৔߹ … } } }

Slide 67

Slide 67 text

extension BluetoothManager: CBCentralManagerDelegate { func centralManagerDidUpdateState(_ central: CBCentralManager) { switch central.state { case .poweredOn: // Bluetooth ͕Φϯɺ͔ͭ࢖༻ڐՄ͞Ε͍ͯΔ৔߹ case .poweredOff: // Bluetooth ͕Φϑɺ΋͘͠͸ݖݶະ֬ೝͷ৔߹ case .unauthorized: // Bluetooth ͷ࢖༻ڐՄΛڋ൱ͨ͠৔߹ … } } } AccessorySetupKit ͰηοτΞοϓࡁΈͷσόΠε͕͋Ε͹ poweredOn ͕ฦΔ

Slide 68

Slide 68 text

extension BluetoothManager: CBCentralManagerDelegate { func centralManagerDidUpdateState(_ central: CBCentralManager) { switch central.state { case .poweredOn: // Bluetooth ͕Φϯɺ͔ͭ࢖༻ڐՄ͞Ε͍ͯΔ৔߹ case .poweredOff: // Bluetooth ͕Φϑɺ΋͘͠͸ݖݶະ֬ೝͷ৔߹ case .unauthorized: // Bluetooth ͷ࢖༻ڐՄΛڋ൱ͨ͠৔߹ … } } } ηοτΞοϓࡁΈͷσόΠε͕࡟আ͞ΕΔͱ poweredO ff ͕ฦΔ

Slide 69

Slide 69 text

2. ϖΞϦϯάࡁΈσόΠεͷҠߦ

Slide 70

Slide 70 text

No content

Slide 71

Slide 71 text

func migratePairedDevice() async throws { let descriptor = ASDiscoveryDescriptor() descriptor.supportedOptions = [.bluetoothPairingLE, .bluetoothHID] let displayName = “BLE-Demo" let productImage = UIImage(named: "ble-device-image")! let displayItem = ASMigrationDisplayItem( name: displayName, productImage: productImage, descriptor: descriptor ) // AccessorySetupKit ʹҠߦ͍ͨ͠ Peripheral Bluetooth Identifier Λࢦఆ͢Δ let bluetoothIdentifier = UUID(uuidString: "XXXXXXX-5CBD-9BFC-BC4C-4BBDE6436185") displayItem.peripheralIdentifier = bluetoothIdentifier try await session.showPicker(for: [displayItem]) }

Slide 72

Slide 72 text

func migratePairedDevice() async throws { let descriptor = ASDiscoveryDescriptor() descriptor.supportedOptions = [.bluetoothPairingLE, .bluetoothHID] let displayName = “BLE-Demo" let productImage = UIImage(named: "ble-device-image")! let displayItem = ASMigrationDisplayItem( name: displayName, productImage: productImage, descriptor: descriptor ) // AccessorySetupKit ʹҠߦ͍ͨ͠ Peripheral Bluetooth Identifier Λࢦఆ͢Δ let bluetoothIdentifier = UUID(uuidString: "XXXXXXX-5CBD-9BFC-BC4C-4BBDE6436185") displayItem.peripheralIdentifier = bluetoothIdentifier try await session.showPicker(for: [displayItem]) } peripheralIdenti f ier ʹ ϖΞϦϯάࡁΈBluetoothσόΠεͷUUIDΛ౉͓ͯ͘͠

Slide 73

Slide 73 text

σϞ

Slide 74

Slide 74 text

·ͱΊ • AccessorySetupKit Λར༻͢Δ͜ͱͰɺBluetooth LE σόΠεͱͷϖΞϦϯ ά΍ηοτΞοϓϑϩʔΛҰମԽ͞ΕͨϢʔβʔମݧͰఏڙͰ͖Δ • ηοτΞοϓ͞Εͨ Bluetooth LE σόΠεΛʮΞΫηαϦʯͱͯ͠ iOS ্Ͱ ؅ཧͰ͖ΔΑ͏ʹͳΔ • ϖΞϦϯάࡁΈͷσόΠεΛҠߦ͢ΔAPI͕͋ΓɺطଘΞϓϦʹ΋ద༻Մೳ

Slide 75

Slide 75 text

YODAN • 2025೥9݄ݱࡏ App Store ʹެ։͞Ε͍ͯΔΞϓϦͰɺAccessorySetupKit ͕࢖ΘΕ͍ͯΔέʔε͕͋·Γଘࡏ͍ͯ͠ͳ͍ • API ͕ iOS18 Ҏ߱ͱ͍͏ͷ͕ωοΫ͔΋͠Εͳ͍ • ৽نΞϓϦΛ࡞Δࡍ͸ͥͻʂ

Slide 76

Slide 76 text

https://github.com/nekowen/AccessorySetupKit-Sample

Slide 77

Slide 77 text

ࢀߟ • WWDC24: Meet AccessorySetupKit • https://developer.apple.com/videos/play/wwdc2024/10203/ • AccessorySetupKit | Apple Developer Documentation • https://developer.apple.com/documentation/AccessorySetupKit • iOS 18 AccessorySetupKit: Everything BLE Developers Need To Know • https://punchthrough.com/ios18-accessorysetupkit-everything-ble- developers-need-to-know/