Skip to content

Instantly share code, notes, and snippets.

View yostane's full-sized avatar

Yassine Benabbas yostane

View GitHub Profile
/**
1- checks if the characteristic is correctly discovered
2- Register for notifications using the dataFuture variable
*/
let dataFuture = discoveryFuture.flatMap { service -> Future<Characteristic> in
guard let dataCharacteristic = service.characteristic(dateCharacteristicUUID) else {
throw AppError.dataCharactertisticNotFound
}
self.dataCharacteristic = dataCharacteristic
DispatchQueue.main.async {
//we will next discover the "ec00" service in order be able to access its characteristics
let discoveryFuture = connectionFuture.flatMap { peripheral -> Future<Peripheral> in
return peripheral.discoverServices([serviceUUID])
}.flatMap { discoveredPeripheral -> Future<Service> in
guard let service = discoveredPeripheral.service(serviceUUID) else {
throw AppError.serviceNotFound
}
peripheral = discoveredPeripheral
DispatchQueue.main.async {
self.connectionStatusLabel.text = "Discovered service \(service.uuid.uuidString). Trying to discover characteristics"
//We will connect to the first scanned peripheral
let connectionFuture = scanFuture.flatMap { peripheral -> FutureStream<Peripheral> in
//stop the scan as soon as we find the first peripheral
manager.stopScanning()
DispatchQueue.main.async {
self.connectionStatusLabel.text = "Found peripheral \(peripheral.identifier.uuidString). Trying to connect"
print(self.connectionStatusLabel.text!)
}
//connect to the peripheral in order to trigger the connected mode
return peripheral.connect(connectionTimeout: 10, capacity: 5)
//handle state changes and return a scan future if the bluetooth is powered on.
let scanFuture = stateChangeFuture.flatMap { state -> FutureStream<Peripheral> in
switch state {
case .poweredOn:
DispatchQueue.main.async {
self.connectionStatusLabel.text = "start scanning"
print(self.connectionStatusLabel.text!)
}
//scan for peripherlas that advertise the ec00 service
return manager.startScanning(forServiceUUIDs: [serviceUUID])
//initialize a central manager with a restore key. The restore key allows to resuse the same central manager in future calls
let manager = CentralManager(options: [CBCentralManagerOptionRestoreIdentifierKey : "CentralMangerKey" as NSString])
//A future stram that notifies us when the state of the central manager changes
let stateChangeFuture = manager.whenStateChanges()
@yostane
yostane / dispatch10.swift
Created February 12, 2017 12:41
We can specify a timeout for the wait function
let sem = DispatchSemaphore(value: 0)
DispatchQueue.global().async {
print("waiting for at least one signal for 1 second")
//wait for a signal
let res = sem.wait(timeout: DispatchTime.now() + 1)
if(res == .timedOut){
print("wait timed out")
}else{
print("At least one signal has been received")
@yostane
yostane / dispatch9.swift
Created February 12, 2017 12:30
A semaphore that blocks execution until it recieves at least one signal -> value = 0
let semaphore = DispatchSemaphore(value: 0)
DispatchQueue.global().async {
print("waiting for at least one signal")
//wait for a signal
semaphore.wait()
print("At least one signal has been received")
}
DispatchQueue.global().async {
sleep(2)
@yostane
yostane / dispatch8.swift
Created February 12, 2017 12:22
DispatchGroup allows to track the completion of a set of blocks
let dispatchWorkItem = DispatchWorkItem{
print("work item start")
sleep(1)
print("work item end")
}
let dg = DispatchGroup()
//submiy work items to the group
let dispatchQueue = DispatchQueue(label: "custom dq")
dispatchQueue.async(group: dg) {
@yostane
yostane / dispatch7.swift
Created February 12, 2017 12:09
DispatchWorkItem notify example
let dwi3 = DispatchWorkItem {
print("start DispatchWorkItem")
sleep(2)
print("end DispatchWorkItem")
}
//this block will be executed on a the siqpatch queue 'dq' when dwi3 completes
let myDq = DispatchQueue(label: "A custom dispatch queue")
dwi3.notify(queue: myDq) {
print("notify")
}
@yostane
yostane / dispatch7.swift
Last active August 14, 2018 22:25
Handling calcellation of a dispatch work item is ugly
//create the dispatch work item
var dwi2:DispatchWorkItem?
dwi2 = DispatchWorkItem {
for i in 1...5 {
print("\(dwi2?.isCancelled)")
if (dwi2?.isCancelled)!{
break
}
sleep(1)
print("DispatchWorkItem 2: \(i)")