Saving HealthKit Data & Closures

iOS 8 HealthKit Santiapps Marcio Valenzuela
iOS 8 HealthKit Santiapps Marcio Valenzuela
iOS 8 HealthKit

This code bit saves:

  healthKitStore.saveObject(bmiSample, withCompletion: { (success, error) -> Void in
    if( error != nil ) {
      println("Error saving BMI sample: \(error.localizedDescription)")
    } else {
      println("BMI sample saved successfully!")
    }
  })

The method signature is:

saveObject(object: HKObject!, withCompletion completion: ((Bool, NSError!) -> Void)!)

This method takes an HKObject which is bmiSample

and it takes a completion closure which itself takes a bool & error and returns void.

So in our method call, we pass in the bmiSample as the HKObject and for the success and error completion block we say:

if error is NOT nil then log that error’s description,

else log that the bmiSample was saved successfully.

 

 

This code bit reads:

// 2. Call the method to read the most recent weight sample
self.healthManager?.readMostRecentSample(sampleType, completion: { (mostRecentWeight, error) -> Void in
 
  if( error != nil )
  {
    println("Error reading weight from HealthKit Store: \(error.localizedDescription)")
    return;
  }
 
  var weightLocalizedString = self.kUnknownString;
  // 3. Format the weight to display it on the screen
  self.weight = mostRecentWeight as? HKQuantitySample;
  if let kilograms = self.weight?.quantity.doubleValueForUnit(HKUnit.gramUnitWithMetricPrefix(.Kilo)) {
    let weightFormatter = NSMassFormatter()
    weightFormatter.forPersonMassUse = true;
    weightLocalizedString = weightFormatter.stringFromKilograms(kilograms)
  }
 
  // 4. Update UI in the main thread
  dispatch_async(dispatch_get_main_queue(), { () -> Void in
    self.weightLabel.text = weightLocalizedString
    self.updateBMI()
 
  });
});

Here we are calling the .readMostRecentSample method which has this signature:

func readMostRecentSample(sampleType:HKSampleType , completion: ((HKSample!, NSError!) -> Void)!)

This method takes an HKSampleType which is sampleType

and it takes a completion closure which itself takes an HKSample & error and returns void.

So in our method call, we pass in the sampleType as the HKSample and for the success and error completion block we say:

if error is NOT nil then log that error’s description,

else get that mostRecentWeight as self.weight, format it and set it as the label’s text.

How does this method get the actual value from the HKHealthStore?  Inside itself, it executes an HKQuery which itself says this:

let sampleQuery = HKSampleQuery(sampleType: sampleType, predicate: mostRecentPredicate, limit: limit, sortDescriptors: [sortDescriptor])
    { (sampleQuery, results, error ) -> Void in
 
      if let queryError = error {
        completion(nil,error)
        return;
      }
 
      // Get the first sample
      let mostRecentSample = results.first as? HKQuantitySample
 
      // Execute the completion closure
      if completion != nil {
        completion(mostRecentSample,nil)
      }
  }
  // 5. Execute the Query
  self.healthKitStore.executeQuery(sampleQuery)

Give me:

a.  sampleType

b.  a predicate, limit, sortDescriptors

c. and a completion closure which takes a sampleQuery, results & error

such that;

if error it NOT nil, set the readMostRecentSample method’s completion closure to nil,error

otherwise set the completion closure with the results and no error.

NOOB iPhone Dev

I’ve been barging into Alex Whittemore’s blog which was originally about uploading apps to your iPhone, not really about programming so I decided to stop butting in and get my own blog :-). Alex, thanks for your hospitality. Please I beg you to participate in my blog helping us noobs to iPhone.

Arduino (IoT): Simple Tutorial WiFi CC3000 Arduino Shield

Wifi Communication Arduino Santiapps

Arduino Honduras Santiapps Marcio Valenzuela

Tutorial WiFi CC3000 Arduino Shield

En este tutorial exploramos la shield original de Arduino, WiFi, CC3000.  Esta acaba de ser reemplazada (Nov 2015) por la WiFi 101.  Veremos esa en tutoriales futuros.

Ahora veamos los componentes requeridos.

Requisitos:

  1. Computadora (mac)
  2. Arduino UNO
  3. Arduino WiFi Shield CC300
  4. Arduino IDE (https://www.arduino.cc/en/Main/Software)
Arduino Simple Tutorial WiFi CC3000 Shield
Arduino Simple Tutorial WiFi CC3000 Shield

Las shields son muy practicas y fáciles de usar.  Simplemente se conectan sobre los headers de la Arduino UNO.  Cuidado porque hay shields para distintas placas.  Es decir que una shield es especifica para la UNO y no funciona sobre la MEGA y vv.

Ya conectada podemos repasar el código rápidamente para montar un servidor que muestre datos de sensores análogos (o digitales) de nuestra AVR como para montar rápidamente un servidor de datos de sensores.

[code]
#include <SPI.h>
#include <WiFi.h>
char ssid[] = “tuRed”; // La SSID de tu red
char pass[] = “clave”; // La clave de tu red (pass o key)
int keyIndex = 0; // El indice de tu red (para WEP)
int status = WL_IDLE_STATUS;
WiFiServer server(80);
void setup() {
//Inicializar
Serial.begin(9600);
while (!Serial) {
; // esperar el puerto (necesario solo en Leo)
}
// Verificar presencia de la shield
if (WiFi.status() == WL_NO_SHIELD) {
Serial.println(“No hay shield”);
// No continuar
while(true);
}
// Intentar conexion a red
while ( status != WL_CONNECTED) {
Serial.print(“Conectando a SSID: “);
Serial.println(ssid);
// Conectar a WPA/WPA2 network.
// Si es red WEP: status = WiFi.begin(ssid, keyIndex, key);
status = WiFi.begin(ssid, pass);
// Esperar para negociar conexion
delay(10000);
}
server.begin();
// Iniciar servidor imprimiendo estatus y ‘sirviendolo’
printWifiStatus();
}
void loop() {
// Buscar clientes activamente
WiFiClient client = server.available();
if (client) {
Serial.println(“Cliente Nuevo”);
// Un HTTPRequest termina con una linea en blanco
boolean currentLineIsBlank = true;
while (client.connected()) {
if (client.available()) {
char c = client.read();
Serial.write(c);
// Si se llego al final de una linea (via un caracter de linea nueva
// y la linea esta en blanco, el HTTPRequest ha terminado,
// asi que podemos responder asi…
if (c == ‘\n’ && currentLineIsBlank) {
// Enviar header de HTTPResponse tipico…
client.println(“HTTP/1.1 200 OK”);
client.println(“Content-Type: text/html”);
client.println(“Connection: close”); // La connexion cerrara luego de la HTTPResponse
client.println(“Refresh: 5”); // Refrescar cada 5 segundos
client.println();
client.println(“<!DOCTYPE HTML>”);
client.println(“<html>”); //tambien puede insertar php
// Escribir en pantalla los niveles de los puertos analogos
for (int analogChannel = 0; analogChannel < 6; analogChannel++) {
int sensorReading = analogRead(analogChannel);
client.print(“Input analogo “);
client.print(analogChannel);
client.print(” es “);
client.print(sensorReading); //algun sensor conectado a cada pin/channel
client.println(”
“);
}
client.println(</html>”);
break;
}
if (c == ‘\n’) {
// Nueva linea
currentLineIsBlank = true;
}
else if (c != ‘\r’) {
// Nuevo caracter en la linea actual
currentLineIsBlank = false;
}
}
}
// Dar tiempo para que browser reciba datos
delay(1);
// Cerrar conexion
client.stop();
Serial.println(“cliente desonectado”);
}
}
void printWifiStatus() {
// Imprimir ID de la red
Serial.print(“SSID: “);
Serial.println(WiFi.SSID());
// Imprimir IP del dispositivo
IPAddress ip = WiFi.localIP();
Serial.print(“Direccion IP: “);
Serial.println(ip);
// Imprimir senal
long rssi = WiFi.RSSI();
Serial.print(“Potencia de la senal (RSSI):”);
Serial.print(rssi);
Serial.println(” dBm”);
}[/code]