Corebluetooth tips: after cancel a Peripheral, the device isn’t shown during scan

This is a strange one:

when you disconnect a peripheral calling cancelPeripheralConnectionthedidDisconnectPeripheral delegate method is invoked, but the peripheral doesn’t advertise itself for about 30 seconds.

This happens because in this time frame, iOS doesn’t really close the connection, so, from the peripheral point of view, the pairing it’s still established.

Apple didn’t explain this behaviour and a lot of speculation was done; the explanation considered more likely believes that it prevents occasionally glitch of connection.

Anyway it seems than in iOS 6.1 Beta4 the timeout is reduced to a couple of seconds.


CoreBluetooth tips: reconnect a device

Unlike previous version of Bluetooth, in Low Energy version almost everything must be managed by the application layer.
It’s quite easy to understand scan, connect and discovery process, because there is plenty of tutorial and blog posts about it, but the reconnection stuff it’s a different kettle of fish.

As usual, after found the way, it’s very easy, but I had to dig deep into Stackoverflow before see the light.

First of all, we have to save the uuid of the paired device, using a local db, NSUserDefaults, a file…

Don’t forget to transform uuid to string format before save it:

NSString *pUuid = (__bridge NSString *)(CFUUIDCreateString(nil, otherPeripheral.UUID));

When the app restart, retrieve the identifier, transform it into CFUUIDRef

        CFUUIDRef cbuuid = CFUUIDCreateFromString(nil, (__bridge CFStringRef)(uuid));

and send retrievePeripherals message to CentralManager with the list of devices to reconnect:

    [manager retrievePeripherals:@[cbuuid]];

After that, the relative callback is then called:

- (void)centralManager:(CBCentralManager *)central didRetrievePeripherals:(NSArray *)peripherals{
    for (CBPeripheral *peripheral  in peripherals) {
        [central connect:peripheral];
    }
}

The connect message is an inexpensive method, and it’s useful also to reconnect when a device go away from iPhone.

CoreBluetooth tips: what is Bluetooth Low Energy

Ok, let’s face it: Bluetooth is a well know and established technology, but it’s still a pain in the a**.

Its reconnecting feature should avoid the need to discover and connect a device, but too often it simply doesn’t work!

Some time ago, I bought a Zeo (I know, I know… a forehead band it’s just… stupid), but most annoying problem was connect it to the iPhone: every night I had to fight with the Bluetooth connection (switch off/switch on the iPhone, the device, etc), until I quit that crap.

Moreover, Bluetooth 2.0 is a energy drainer and, in a Bluetooth device, the battery life is too short for my taste.

Ok, enter Bluetooth 4.0, a really game changer.

It’s been defined as the hidden treasure of iPhone 4S, because few people noticed it, but now, as big players like Fitbit,  Withings and Parrot are entering the arena, no one can still understimate it.

From development point of view, the main difference with its predecessor is the lack of a stream channel, therefore it has a narrow bandwidth and data transfer is made through async api.

In iOS, Bluetooth 2.0 is still managed by GameKit library, but a brand new api, CoreBluetooth, has been introduced in iOS 5.0 to deal with 4.0 version.

Strangely enough, the documentation is very sparse, so that tutorials and first hand experiences, so a lot of discoveries should be made  by trial and error.

A good introduction to CoreBluetooth can be find here.
In upcoming posts I’ll share some findings from the past few months, that if I found written down somewhere,  it would have saved several sleepless night.

Draggable Body in Cocos2d

Implement a draggable object in Cocos2d+Box2d is a common task, mainly during first development, so I wonder why itsn’t native in the framework.

Anyway, after struggled a little in google, I took my dead-tree copy of Learning Cocos2d and cut the useful part.

First of all it needs to create a query callback:

class SimpleQueryCallback : public b2QueryCallback
{
public:
    b2Vec2 pointToTest;
    b2Fixture * fixtureFound;
    SimpleQueryCallback(const b2Vec2& point) {
        pointToTest = point;
        fixtureFound = NULL;
    }
    bool ReportFixture(b2Fixture* fixture) {
        b2Body* body = fixture->GetBody();
        if (body->GetType() == b2_dynamicBody) {
            if (fixture->TestPoint(pointToTest)) {
                fixtureFound = fixture;
                return false;
            } }
        return true;
    }
};

Then add touches handler:

- (b2Vec2)touchedPointConvertedFrom:(UITouch *)touch{
    CGPoint touchLocation = [touch locationInView:[touch view]];
    touchLocation = [[CCDirector sharedDirector]
                     convertToGL:touchLocation];
    touchLocation = [self convertToNodeSpace:touchLocation];
    
    b2Vec2 locationWorld =
    b2Vec2(touchLocation.x/PTM_RATIO, touchLocation.y/PTM_RATIO);
    return locationWorld;
}

-(BOOL) ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event {
    b2Vec2 locationWorld = [self touchedPointConvertedFrom:touch];
    
    b2AABB aabb;
    b2Vec2 delta = b2Vec2(1.0/PTM_RATIO, 1.0/PTM_RATIO);
    aabb.lowerBound = locationWorld - delta;
    aabb.upperBound = locationWorld + delta;
    SimpleQueryCallback callback(locationWorld);
    world->QueryAABB(&callback, aabb);

    if (callback.fixtureFound) {
        b2Body *body = callback.fixtureFound->GetBody();
        b2MouseJointDef mouseJointDef;
        mouseJointDef.bodyA = groundBody;
        mouseJointDef.bodyB = body;
        mouseJointDef.target = locationWorld;
        mouseJointDef.maxForce = 100 * body->GetMass();
        mouseJointDef.collideConnected = true;
        mouseJoint = (b2MouseJoint *) world->CreateJoint(&mouseJointDef);
        body->SetAwake(true);
        return YES;
    }
    
    return TRUE;
}

-(void) ccTouchMoved:(UITouch *)touch withEvent:(UIEvent *)event {
    CGPoint touchLocation = [touch locationInView:[touch view]];
    touchLocation =
    [[CCDirector sharedDirector] convertToGL:touchLocation];
    touchLocation = [self convertToNodeSpace:touchLocation];
    
    b2Vec2 locationWorld = b2Vec2(touchLocation.x/PTM_RATIO,
                                  touchLocation.y/PTM_RATIO);
    
    if (mouseJoint) {
        mouseJoint->SetTarget(locationWorld);
    }
}

-(void) ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event {
    if (mouseJoint) {
        world->DestroyJoint(mouseJoint);
        mouseJoint = NULL;
    }
}

Seth Godin in three lines: The Dip

Quit often.
Quit tactically, not strategically.
Stay when you are in a dip, quit when you are in a cul-de-sac.

Recently I saw somebody asked a question in a forum, the question is “Which programming language should I learn first?”. Then someone answered this question. His answer:

Depends.

  • To program in an expressive and powerful language: Python
  • To get a website up quickly: PHP
  • To mingle with…

(Source: pixelstech.net)

'Android - Programmazione Avanzata': un libro da leggere

Seguo e stimo Stefano ed Emanuele da molti anni e nel tempo ne ho apprezzato la competenza, ma soprattutto la grande passione per lo sviluppo Android.

Per cui quando è uscito il loro ‘Android programmazione avanzata’, me ne sono avvicinato con molto interesse ed aspettative.

Devo dire che le aspettative non solo sono state soddisfatte, ma anzi la qualità mi ha stupito sempre di più, capitolo dopo capitolo.

Soprattutto la chiarezza e scorrevolezza del testo sono da far notare, mai declinate in superficialità e banalità.

Come già fatto notare altrove, il libro “trasuda esperienza d’uso”, che è quello che ci si aspetta in un libro che voglia andare al di là del semplice tutorial con l’Hello world di ogni funzionalità.

Il primo capitolo tratta dell’architettura dei ‘blocchi’ di ogni applicazione Android, fondamentali per la comprensione del sistema di sviluppo, e cioè Activity e Service, in modo molto completo ed approfondito; questo capitolo, inoltre, contiene la miglior spiegazione del mainloop grafico che io abbia mai trovato: visto che è un concetto che si trova, implicito o esplicito, in tutti i sistemi operativi, dovrebbe essere preso come esempio per ogni libro tecnico che tratti di programmazione.

Visto che nello sviluppo mobile la maggior parte della complessità si trova nella logica di presentazione, molto interessate il capitolo successivo che tratta con dovizia di particolari ed esempi la grafica e l’interfaccia utente, parlando di modalità, ma anche di performance.

A seguire si tratta di Honeycomb e tablet cioè della rivoluzione grafica e di fruizione che essi hanno portato; per quanto Android 3.0 non abbia raggiunto una considerevole diffusione e sia ormai superato da Ice Cream Sandwitch, i cambiamenti proposti sono tali da aver cambiato completamente il paradigma di programmazione e aver creato nuove fondamenta su cui si baseranno le prossime versioni di android.

No man is an island”, ma potrebbe esserlo una app che non utilizza le potenzialità della rete. Di Networking tratta, appunto, il quarto capitolo e della modalità tipiche ed avanzate per connettersi e ricevere dati.

NFC, Near Field Communicaton è, secondo me, la grande occasione mancata di Android per raggiungere superare in funzionalità il mondo Apple: fosse presente in ogni smartphone, avremmo già superato il concetto di portafoglio; in ogni caso nel quinto capitolo vediamo come utilizzare questa tecnologia tramite le classi rese disponibili dall’Sdk.

A seguire, vediamo nel dettaglio la funzionalità delle Push Notification e del Bluetooth, altra consolidata tecnologia per connettere il mondo virtuale a quello fisico, non nuova, ma che con le prossime versioni a Low Energy, apre un nuovo mondo di possibilità ed applicazioni.

Qualsiasi libro e tecnologia seria non può prescindere, nel 2012, da temi come Test Driven Development, Continuous Deployment o, più in generale, dalla Qualità del software; ovviamente ’Android programmazione avanzata' tratta in modo esaustivo, nel capitolo otto, questi temi, mostrando come Test di Unità, Integrazione ed Accettazione possano essere implementati con i mezzi messi a disposizione dal framework, corredando il tutto con trucchi e consigli di chi utilizza queste tecniche ben prima del rilascio di Android.

Il nono ed ultimo capitolo parla di Ice Cream Sandwich, l’ultima versione di Android in cui si consolidano i concetti introdotti da Honeycomb e si riconciliano i mondi smartphone di Android 2 e di tablet di Android 3; un nuovo punto di arrivo, ma soprattutto un nuovo blocco di partenza su cui costruire il futuro dell’os mobile di Google.

In conclusione, il libro mi è piaciuto molto, e lo consiglio caldamente a chi ha intenzione di programmare in modo serio su Android. 

A minimalistic NSRemoteLogging library

Lately, I’m deeply involved into developing iOS apps for custom hardware.

Often I need to debug my app when it’s connected to that stuff, and I can’t use XCode to trace the log messages.

I’ve an ATS and a splitter, but sometimes I can’t plug it, because of the form of the custom connection.

So I needed, at last, a sort way to send NSLog messages elsewhere, maybe on a server.

I searched a ready made library, but didn’t find anything minimalistic as I needed, so I wrote one ;-)

Here they are the server and the client.

Of course is very opinionated (hosting on Heroku and CocoaPod spec), and tailored to my needs, anyway it works ;-)

To use into your project, add 

dependency ‘NSRemoteLog’, :podspec => ‘https://raw.github.com/gscalzo/NSRemoteLog/master/NSRemoteLog.podspec’

to your Podfile (are you using CocoaPods, aren’t you?), and add these line to the precompiled header:

#import "NSRemoteLog.h"

#define NSLog(__FORMAT__, …) [NSRemoteLog log:[NSString stringWithFormat:__FORMAT__, ##__VA_ARGS__] serverUrl:@"http://hollow-galaxy-7080.herokuapp.com/"]


That’s all!

robindarke:

Made with Paper

robindarke:

Made with Paper

So last month I wrote a bit about setting up your own personal Git repositories on a Linux box, and how to use that for sharing code.

I’ve had a slight epiphany since then: what if I just used the awesome Dropbox (my referral link, if you’re likely to sign up) to share Git repositories…

draftq:

The sad truth

So you want to write a book. It’s all in your head, you had an extensive experience on the latest technology, you did a tons of tests, you solve all the subtle problems, and you found the best practices to use it in production. You know that it would be great to have a book to share…

Development is design!

Screwups happen, so better prepared to apologize in effectively way.

Wonder why default stringByAddingPercentEscapesUsingEncoding often doesn’t work?

Maybe is quite broken, but all can be fixed with a category.