SlideShare uma empresa Scribd logo
1 de 14
Baixar para ler offline
IOT LESSONS
LEARNED
HUGUES BERNET-ROLLANDE
@ROMPELSTILCHEN
GITHUB.COM/HUGUESBR
CHIEF SOFTWARE OFFICER @ WIRED BEAUTY
1
IOT LESSONS LEARNED
@rompelstilchen
TOPIC
▸BLE vs Bluetooth
▸IoT vs Connected Object
▸Not BLE tutorial
2
IOT LESSONS LEARNED
UNIT TESTS
▸Debugging IoT is hard
▸Data transformation layer (bytes ->
value)
▸Models (aggregated values)
@rompelstilchen
IOT LESSONS LEARNED
DATA TRANSFORMATION
extension Data {
func value<T>() -> T {
return withUnsafeBytes { (ptr: UnsafePointer<T>) -> T in
return ptr.pointee
}
}
}
class test: XCTestCase {
func testInt16() {
let bytes: [UInt8] = [0xFC, 0xFF] // big endian
let data = Data(bytes: bytes)
let v: Int16 = data.value() // reverse inference :)
print(v == -4)
}
}
extension Integer {
public var data: Data {
var v = self
return Data(buffer: UnsafeBufferPointer(start: &v, count: 1))
}
}
class IntegerTests: XCTestCase {
func testUInt32() {
let bytes: [UInt8] = [0x01, 0x01, 0x01, 0x03] // big endian
let data = Data(bytes: bytes)
XCTAssertEqual(UInt32(50_397_441).data, data)
}
}
4
@rompelstilchen
IOT LESSONS LEARNED
UNIT TEST YOUR MODELS
// 0xABCDEFGH -> "ABCDEFGH"
public struct DeviceSerial {
public let serialString: String
init(data: Data) throws {
// check data length
// reverse string (little
endian)
// decode as hex
self.serialString = …
}
}}
5
public protocol DataRepresentable: Equatable {
var data: Data { get }
}
public func == <T: DataRepresentable>(lhs: T, rhs: T) -> Bool {
return lhs.data == rhs.data
}
extension DeviceSerial: DataRepresentable {
public var data: Data {
return …
}
}
extension DeviceSerial {
public init?(serialString: String) {
// check len
// check characters
self.serialString = serialString
}
}
class test: XCTestCase {
func testValidSerial() {
let data = Data(…)
let a = DeviceSerial(serialString: "ABCD")
let b = DeviceSerial(data: data)
XCTAssertEqual(a, b)
}
}
@rompelstilchen
IOT LESSONS LEARNED
IOS SIMULATOR VS BLE
▸Simulator doesn’t support BLE
▸Use Wrapper & Protocols
▸Stream fake Object (and data)
@rompelstilchen
IOT LESSONS LEARNED
DEVICE MANAGER
protocol DeviceInterfaceProtocol {
func getBattery(completion: (result: Result<BatteryLevel>) ->
Void)
}
public protocol DeviceManagerProtocol {
associatedtype DeviceInterface
var central: CBCentralManager? { get }
var device: DeviceInterface? { get }
var state: DeviceManagerState { get }
var paired: Bool { get }
init(central: CBCentralManager)
func pair(block: (String) -> Bool)
func unpair()
}
class DeviceManager<DeviceInterface: DeviceInterfaceProtocol >:
DeviceManagerProtocol {
// some share default implementation
}
class DeviceWrapper {
#if ( (arch(i386) || arch(x86_64)) && os(iOS) )
static var sharedManager: DeviceManager = {
return FakeDeviceManager()
}()
#else
static var sharedManager: DeviceManager = {
return DeviceManager<DeviceInterface>()
}()
#endif
}
7
class FakeDeviceInterface:
DeviceInterfaceProtocol {
func getBattery(completion: (result:
Result<BatteryLevel>) -> Void) {
let level = BatteryLevel(voltage:
3.7)
completion(.success(level))
}
}
class FakeDeviceManager:
DeviceManager<FakeDeviceInterface> {
override var state: DeviceManagerState
{
get { return .Connected }
set {}
}
override var paired: Bool {
get { return true }
set {}
}
}
@rompelstilchen
IOT LESSONS LEARNED
DEVICE VS APP
▸Device will be slower
to develop than App
▸Develop a Device
Simulator
▸macOS Playground
support BLE
@rompelstilchen
IOT LESSONS LEARNED
@rompelstilchen
ACCESS DATA INDIRECTLY
▸Fetch from DB
▸Ease Unit Tests
▸Simulated mode
9
IOT LESSONS LEARNED
@rompelstilchen
TOOLS
▸Light Blue
▸Apple Bluetooth Explorer
▸(macOS) Playground
▸Console (BTServer)
10
IOT LESSONS LEARNED
SUMMARY
▸Simulate as much as you can
▸Apply same principles for BLE than
Server
▸Unit Tests (again!)
@rompelstilchen
@rompelstilchen
A GOOD BLE APP
IS LIKE A GOOD
CAKE: IT HAS
LAYER
Hugues Bernet-Rollande
IOT LESSONS LEARNED
@rompelstilchen
LEARN MORE ABOUT BLE
▸Core Bluetooth Programming Guide
▸WWDC (CoreBluetooth 101)
▸Zero to BLE
13
https://www.cloudcity.io/blog/2015/06/11/zero-to-ble-on-ios-part-one/
https://developer.apple.com/ - Core Bluetooth Programming Guide
https://developer.apple.com/videos/play/wwdc2012/703/
THANK YOU!
SLIDES AVAILABLE ON SPEAKER DECK: HTTP://BIT.LY/2LV3ISK
HUGUES BERNET-ROLLANDE
@ROMPELSTILCHEN
GITHUB.COM/HUGUESBR
CSO ENGINEER @ WIRED BEAUTY
14
@rompelstilchen

Mais conteúdo relacionado

Mais procurados

Mais procurados (20)

Swift Sequences & Collections
Swift Sequences & CollectionsSwift Sequences & Collections
Swift Sequences & Collections
 
Protocol-Oriented Programming in Swift
Protocol-Oriented Programming in SwiftProtocol-Oriented Programming in Swift
Protocol-Oriented Programming in Swift
 
Map kit light
Map kit lightMap kit light
Map kit light
 
New Design of OneRing
New Design of OneRingNew Design of OneRing
New Design of OneRing
 
Callbacks and control flow in Node js
Callbacks and control flow in Node jsCallbacks and control flow in Node js
Callbacks and control flow in Node js
 
Mca 2nd sem u-4 operator overloading
Mca 2nd  sem u-4 operator overloadingMca 2nd  sem u-4 operator overloading
Mca 2nd sem u-4 operator overloading
 
Avoiding Callback Hell with Async.js
Avoiding Callback Hell with Async.jsAvoiding Callback Hell with Async.js
Avoiding Callback Hell with Async.js
 
Avoiding callback hell in Node js using promises
Avoiding callback hell in Node js using promisesAvoiding callback hell in Node js using promises
Avoiding callback hell in Node js using promises
 
ES6: The Awesome Parts
ES6: The Awesome PartsES6: The Awesome Parts
ES6: The Awesome Parts
 
Protocol-Oriented MVVM
Protocol-Oriented MVVMProtocol-Oriented MVVM
Protocol-Oriented MVVM
 
Reactive Access to MongoDB from Scala
Reactive Access to MongoDB from ScalaReactive Access to MongoDB from Scala
Reactive Access to MongoDB from Scala
 
Zenly - Reverse geocoding
Zenly - Reverse geocodingZenly - Reverse geocoding
Zenly - Reverse geocoding
 
Textile
TextileTextile
Textile
 
ESCMAScript 6: Get Ready For The Future. Now
ESCMAScript 6: Get Ready For The Future. NowESCMAScript 6: Get Ready For The Future. Now
ESCMAScript 6: Get Ready For The Future. Now
 
Let's migrate to Swift 3.0
Let's migrate to Swift 3.0Let's migrate to Swift 3.0
Let's migrate to Swift 3.0
 
Node Boot Camp
Node Boot CampNode Boot Camp
Node Boot Camp
 
Building and Incredible Machine with Pipelines and Generators in PHP (IPC Ber...
Building and Incredible Machine with Pipelines and Generators in PHP (IPC Ber...Building and Incredible Machine with Pipelines and Generators in PHP (IPC Ber...
Building and Incredible Machine with Pipelines and Generators in PHP (IPC Ber...
 
Asynchronous programming done right - Node.js
Asynchronous programming done right - Node.jsAsynchronous programming done right - Node.js
Asynchronous programming done right - Node.js
 
Presenting things in Swift
Presenting things in SwiftPresenting things in Swift
Presenting things in Swift
 
Understanding Asynchronous JavaScript
Understanding Asynchronous JavaScriptUnderstanding Asynchronous JavaScript
Understanding Asynchronous JavaScript
 

Destaque

Destaque (20)

Make Acccessibility Great Again
Make Acccessibility Great AgainMake Acccessibility Great Again
Make Acccessibility Great Again
 
Rebranding an ios application
Rebranding an ios applicationRebranding an ios application
Rebranding an ios application
 
Design like a developer
Design like a developerDesign like a developer
Design like a developer
 
J'ai fait une app native en React Native
J'ai fait une app native en React NativeJ'ai fait une app native en React Native
J'ai fait une app native en React Native
 
What's new in iOS9
What's new in iOS9What's new in iOS9
What's new in iOS9
 
Chainable datasource
Chainable datasourceChainable datasource
Chainable datasource
 
MVC-RS par Grégoire Lhotelier
MVC-RS par Grégoire LhotelierMVC-RS par Grégoire Lhotelier
MVC-RS par Grégoire Lhotelier
 
Alamofire
AlamofireAlamofire
Alamofire
 
CONTINUOUS DELIVERY WITH FASTLANE
CONTINUOUS DELIVERY WITH FASTLANECONTINUOUS DELIVERY WITH FASTLANE
CONTINUOUS DELIVERY WITH FASTLANE
 
Programme MFI retour d'expérience
Programme MFI retour d'expérienceProgramme MFI retour d'expérience
Programme MFI retour d'expérience
 
How to communicate with Smart things?
How to communicate with Smart things?How to communicate with Smart things?
How to communicate with Smart things?
 
Handle the error
Handle the errorHandle the error
Handle the error
 
SwiftyGPIO
SwiftyGPIOSwiftyGPIO
SwiftyGPIO
 
L'intégration continue avec Bitrise
L'intégration continue avec BitriseL'intégration continue avec Bitrise
L'intégration continue avec Bitrise
 
La sécurité sur iOS par Arnaud de Bock
La sécurité sur iOS par Arnaud de BockLa sécurité sur iOS par Arnaud de Bock
La sécurité sur iOS par Arnaud de Bock
 
CloudKit as a backend
CloudKit as a backendCloudKit as a backend
CloudKit as a backend
 
BitTorrent on iOS
BitTorrent on iOSBitTorrent on iOS
BitTorrent on iOS
 
Project Entourage
Project EntourageProject Entourage
Project Entourage
 
Comment faire de HLS votre solution vidéo préférée ?
Comment faire de HLS votre solution vidéo préférée ?Comment faire de HLS votre solution vidéo préférée ?
Comment faire de HLS votre solution vidéo préférée ?
 
Quoi de neuf dans iOS 10.3
Quoi de neuf dans iOS 10.3Quoi de neuf dans iOS 10.3
Quoi de neuf dans iOS 10.3
 

Semelhante a IoT Best practices

Software Transactioneel Geheugen
Software Transactioneel GeheugenSoftware Transactioneel Geheugen
Software Transactioneel Geheugen
Devnology
 
33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good Tests33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good Tests
Tomek Kaczanowski
 
망고100 보드로 놀아보자 19
망고100 보드로 놀아보자 19망고100 보드로 놀아보자 19
망고100 보드로 놀아보자 19
종인 전
 
Столпы функционального программирования для адептов ООП, Николай Мозговой
Столпы функционального программирования для адептов ООП, Николай МозговойСтолпы функционального программирования для адептов ООП, Николай Мозговой
Столпы функционального программирования для адептов ООП, Николай Мозговой
Sigma Software
 

Semelhante a IoT Best practices (20)

Software Transactioneel Geheugen
Software Transactioneel GeheugenSoftware Transactioneel Geheugen
Software Transactioneel Geheugen
 
JVM Mechanics: When Does the JVM JIT & Deoptimize?
JVM Mechanics: When Does the JVM JIT & Deoptimize?JVM Mechanics: When Does the JVM JIT & Deoptimize?
JVM Mechanics: When Does the JVM JIT & Deoptimize?
 
33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good Tests33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good Tests
 
Flink Batch Processing and Iterations
Flink Batch Processing and IterationsFlink Batch Processing and Iterations
Flink Batch Processing and Iterations
 
Silicon Valley JUG: JVM Mechanics
Silicon Valley JUG: JVM MechanicsSilicon Valley JUG: JVM Mechanics
Silicon Valley JUG: JVM Mechanics
 
C++aptitude questions and answers
C++aptitude questions and answersC++aptitude questions and answers
C++aptitude questions and answers
 
2012 JDays Bad Tests Good Tests
2012 JDays Bad Tests Good Tests2012 JDays Bad Tests Good Tests
2012 JDays Bad Tests Good Tests
 
Java Concurrency
Java ConcurrencyJava Concurrency
Java Concurrency
 
Java
JavaJava
Java
 
GDG Jakarta Meetup - Streaming Analytics With Apache Beam
GDG Jakarta Meetup - Streaming Analytics With Apache BeamGDG Jakarta Meetup - Streaming Analytics With Apache Beam
GDG Jakarta Meetup - Streaming Analytics With Apache Beam
 
망고100 보드로 놀아보자 19
망고100 보드로 놀아보자 19망고100 보드로 놀아보자 19
망고100 보드로 놀아보자 19
 
Lo Mejor Del Pdc2008 El Futrode C#
Lo Mejor Del Pdc2008 El Futrode C#Lo Mejor Del Pdc2008 El Futrode C#
Lo Mejor Del Pdc2008 El Futrode C#
 
Category theory, Monads, and Duality in the world of (BIG) Data
Category theory, Monads, and Duality in the world of (BIG) DataCategory theory, Monads, and Duality in the world of (BIG) Data
Category theory, Monads, and Duality in the world of (BIG) Data
 
From object oriented to functional domain modeling
From object oriented to functional domain modelingFrom object oriented to functional domain modeling
From object oriented to functional domain modeling
 
From object oriented to functional domain modeling
From object oriented to functional domain modelingFrom object oriented to functional domain modeling
From object oriented to functional domain modeling
 
2. Design patterns. part #2
2. Design patterns. part #22. Design patterns. part #2
2. Design patterns. part #2
 
Столпы функционального программирования для адептов ООП, Николай Мозговой
Столпы функционального программирования для адептов ООП, Николай МозговойСтолпы функционального программирования для адептов ООП, Николай Мозговой
Столпы функционального программирования для адептов ООП, Николай Мозговой
 
掀起 Swift 的面紗
掀起 Swift 的面紗掀起 Swift 的面紗
掀起 Swift 的面紗
 
DSD
DSDDSD
DSD
 
Oleksandr Tolstykh
Oleksandr TolstykhOleksandr Tolstykh
Oleksandr Tolstykh
 

Mais de CocoaHeads France

Mais de CocoaHeads France (11)

Mutation testing for a safer Future
Mutation testing for a safer FutureMutation testing for a safer Future
Mutation testing for a safer Future
 
iOS App Group for Debugging
iOS App Group for DebuggingiOS App Group for Debugging
iOS App Group for Debugging
 
Asynchronous swift
Asynchronous swiftAsynchronous swift
Asynchronous swift
 
Visual accessibility in iOS11
Visual accessibility in iOS11Visual accessibility in iOS11
Visual accessibility in iOS11
 
My script - One year of CocoaHeads
My script - One year of CocoaHeadsMy script - One year of CocoaHeads
My script - One year of CocoaHeads
 
Ui testing dealing with push notifications
Ui testing dealing with push notificationsUi testing dealing with push notifications
Ui testing dealing with push notifications
 
Super combinators
Super combinatorsSuper combinators
Super combinators
 
Build a lego app with CocoaPods
Build a lego app with CocoaPodsBuild a lego app with CocoaPods
Build a lego app with CocoaPods
 
Un retour d'expérience sur Apple Pay
Un retour d'expérience sur Apple PayUn retour d'expérience sur Apple Pay
Un retour d'expérience sur Apple Pay
 
Firebase par nicolas lehovetzki
Firebase par nicolas lehovetzkiFirebase par nicolas lehovetzki
Firebase par nicolas lehovetzki
 
Safari app extensions cleared up by Sanaa Squalli
Safari app extensions cleared up by Sanaa SqualliSafari app extensions cleared up by Sanaa Squalli
Safari app extensions cleared up by Sanaa Squalli
 

Último

+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
Health
 

Último (20)

Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 
Define the academic and professional writing..pdf
Define the academic and professional writing..pdfDefine the academic and professional writing..pdf
Define the academic and professional writing..pdf
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 
8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial Goals
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
 
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdfAzure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
 
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionIntroducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
 
Exploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdfExploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdf
 
How to Choose the Right Laravel Development Partner in New York City_compress...
How to Choose the Right Laravel Development Partner in New York City_compress...How to Choose the Right Laravel Development Partner in New York City_compress...
How to Choose the Right Laravel Development Partner in New York City_compress...
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.js
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docx
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 

IoT Best practices

  • 2. IOT LESSONS LEARNED @rompelstilchen TOPIC ▸BLE vs Bluetooth ▸IoT vs Connected Object ▸Not BLE tutorial 2
  • 3. IOT LESSONS LEARNED UNIT TESTS ▸Debugging IoT is hard ▸Data transformation layer (bytes -> value) ▸Models (aggregated values) @rompelstilchen
  • 4. IOT LESSONS LEARNED DATA TRANSFORMATION extension Data { func value<T>() -> T { return withUnsafeBytes { (ptr: UnsafePointer<T>) -> T in return ptr.pointee } } } class test: XCTestCase { func testInt16() { let bytes: [UInt8] = [0xFC, 0xFF] // big endian let data = Data(bytes: bytes) let v: Int16 = data.value() // reverse inference :) print(v == -4) } } extension Integer { public var data: Data { var v = self return Data(buffer: UnsafeBufferPointer(start: &v, count: 1)) } } class IntegerTests: XCTestCase { func testUInt32() { let bytes: [UInt8] = [0x01, 0x01, 0x01, 0x03] // big endian let data = Data(bytes: bytes) XCTAssertEqual(UInt32(50_397_441).data, data) } } 4 @rompelstilchen
  • 5. IOT LESSONS LEARNED UNIT TEST YOUR MODELS // 0xABCDEFGH -> "ABCDEFGH" public struct DeviceSerial { public let serialString: String init(data: Data) throws { // check data length // reverse string (little endian) // decode as hex self.serialString = … } }} 5 public protocol DataRepresentable: Equatable { var data: Data { get } } public func == <T: DataRepresentable>(lhs: T, rhs: T) -> Bool { return lhs.data == rhs.data } extension DeviceSerial: DataRepresentable { public var data: Data { return … } } extension DeviceSerial { public init?(serialString: String) { // check len // check characters self.serialString = serialString } } class test: XCTestCase { func testValidSerial() { let data = Data(…) let a = DeviceSerial(serialString: "ABCD") let b = DeviceSerial(data: data) XCTAssertEqual(a, b) } } @rompelstilchen
  • 6. IOT LESSONS LEARNED IOS SIMULATOR VS BLE ▸Simulator doesn’t support BLE ▸Use Wrapper & Protocols ▸Stream fake Object (and data) @rompelstilchen
  • 7. IOT LESSONS LEARNED DEVICE MANAGER protocol DeviceInterfaceProtocol { func getBattery(completion: (result: Result<BatteryLevel>) -> Void) } public protocol DeviceManagerProtocol { associatedtype DeviceInterface var central: CBCentralManager? { get } var device: DeviceInterface? { get } var state: DeviceManagerState { get } var paired: Bool { get } init(central: CBCentralManager) func pair(block: (String) -> Bool) func unpair() } class DeviceManager<DeviceInterface: DeviceInterfaceProtocol >: DeviceManagerProtocol { // some share default implementation } class DeviceWrapper { #if ( (arch(i386) || arch(x86_64)) && os(iOS) ) static var sharedManager: DeviceManager = { return FakeDeviceManager() }() #else static var sharedManager: DeviceManager = { return DeviceManager<DeviceInterface>() }() #endif } 7 class FakeDeviceInterface: DeviceInterfaceProtocol { func getBattery(completion: (result: Result<BatteryLevel>) -> Void) { let level = BatteryLevel(voltage: 3.7) completion(.success(level)) } } class FakeDeviceManager: DeviceManager<FakeDeviceInterface> { override var state: DeviceManagerState { get { return .Connected } set {} } override var paired: Bool { get { return true } set {} } } @rompelstilchen
  • 8. IOT LESSONS LEARNED DEVICE VS APP ▸Device will be slower to develop than App ▸Develop a Device Simulator ▸macOS Playground support BLE @rompelstilchen
  • 9. IOT LESSONS LEARNED @rompelstilchen ACCESS DATA INDIRECTLY ▸Fetch from DB ▸Ease Unit Tests ▸Simulated mode 9
  • 10. IOT LESSONS LEARNED @rompelstilchen TOOLS ▸Light Blue ▸Apple Bluetooth Explorer ▸(macOS) Playground ▸Console (BTServer) 10
  • 11. IOT LESSONS LEARNED SUMMARY ▸Simulate as much as you can ▸Apply same principles for BLE than Server ▸Unit Tests (again!) @rompelstilchen
  • 12. @rompelstilchen A GOOD BLE APP IS LIKE A GOOD CAKE: IT HAS LAYER Hugues Bernet-Rollande
  • 13. IOT LESSONS LEARNED @rompelstilchen LEARN MORE ABOUT BLE ▸Core Bluetooth Programming Guide ▸WWDC (CoreBluetooth 101) ▸Zero to BLE 13 https://www.cloudcity.io/blog/2015/06/11/zero-to-ble-on-ios-part-one/ https://developer.apple.com/ - Core Bluetooth Programming Guide https://developer.apple.com/videos/play/wwdc2012/703/
  • 14. THANK YOU! SLIDES AVAILABLE ON SPEAKER DECK: HTTP://BIT.LY/2LV3ISK HUGUES BERNET-ROLLANDE @ROMPELSTILCHEN GITHUB.COM/HUGUESBR CSO ENGINEER @ WIRED BEAUTY 14 @rompelstilchen