samedi 15 décembre 2012

Application IPhone FlavoRise

Pour les amateurs de bons vins et seulement eux, je viens de sortir une application IPhone permettant de conserver et de partager vos meilleurs vins goutés.

FlavoRise est disponible dans l'App Store : http://itunes.com/apps/flavorise

Une des fonctionnalités innovante est de partager sa base de données avec ses amis et par mail !












Le site Web de FlavoRise : http://www.flavorise.com

samedi 13 octobre 2012

Tutorial iOS - Réduite la taille d'une UIImage

UIImage : réduction de la taille d'une l'image

En développant vos applications iOS il est fréquent de devoir réduire la taille d'une image à afficher.

En effet afficher quelques images de grandes tailles dans une UIImageView cause des crashs (cf :  doc Apple(tm)).
Une bonne pratique est de se limiter à un affichage des images à 1024x768 max.

Bref à partir d'une image prise de l'appareil photo ou autre, voici un algorithme de réduction de la taille d'une UIImage :

// Algorithme de réduction de la taille d'une image
+(UIImage *) reductionImageSize :(UIImage*)imageOriginale :(CGFloat) coefficientReduction {
    
    // transformation de l'image, réduction
    CGSize destinationSize = CGSizeMake( imageOriginale.size.width / coefficientReduction,  imageOriginale.size.height / coefficientReduction );
    
    UIGraphicsBeginImageContext( destinationSize );
    [imageOriginale drawInRect:CGRectMake( 0., 0., destinationSize.width, destinationSize.height)];
UIImage * newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    
    return newImage;
}

Le premier paramètre en entrée est imageOriginal.
Le second est le coefficient de réduction.

jeudi 14 juin 2012

Tutorial iOS - Obtenir un UUID

Voici l'API iOS qui permet d'obtenir un identifiant universel, bien connu par les développeurs : l'UUID.

L'API iOS pour obtenir un UUID :

+ (NSString *)generateUuidString {
    return [[NSProcessInfo processInfo] globallyUniqueString];;
}


samedi 9 juin 2012

Tutorial iOS - Transformer une NSDate en string et inversement

Voici une petite formule de code (sniplet) pour calculer une NSDate, la transformer en NSString et inversement :

// Initialise l'objet avec la date courante

NSDate * pDate = [[NSDate alloc] init];
    
NSDateFormatter * pDateFormatter = [[NSDateFormatter alloc] init];
[pDateFormatter setTimeStyle:NSDateFormatterMediumStyle];
[pDateFormatter setDateStyle:NSDateFormatterMediumStyle];
    
// Transforme une NSDate en NSString
NSString * pString = [pDateFormatter stringFromDate:pDate];
    
// Transforme une NSString en NSDate
NSDate * pDateResult = [pDateFormatter dateFromString:pString];
NSLog( @"%@",pDateResult );

vendredi 8 juin 2012

Tutorial iOS - Faire un screenshot (d'une View)

Voici le code Cocoa Touch pour faire un "screen shot", une copie d'écran :

-(UIImage*) printScreen {
    // On donne la taille de la vue à copier (bonds.size)
    UIGraphicsBeginImageContext(self.view.bounds.size);

    [self.view.layer renderInContext:UIGraphicsGetCurrentContext()];

    // pi contient l'image copie de la vue
    UIImage * pi = UIGraphicsGetImageFromCurrentImageContext();
    
    return pi;
}

Ici nous sommes dans le contrôleur, "self.view" retourne la vue du contrôleur.
"bounds.size" retourne la taille de cette vue.

samedi 17 mars 2012

Tutorial Phonegap - Géolocalisation


Phonegap permettant de développer des 'web apps' permet d'accéder aux capteurs du périphérique et ce, sur la plupart des plateformes mobiles. On utilise ici HTML5, javascript et CSS.

Le tutorial suivant vous montre le code nécessaire pour une mise en oeuvre rapide.



Géolocalisation avec Phonegap


1. Préalable : Créer un projet Phonegap (ici avec XCode 4)


2. Référencer dans la page HTML (ici dans le projet une seule page est présente), le code javascript correspondant à la version de Phonegap :




3. Insérer le code permettant au système d'appeler la 'callback' deviceready

document.addEventListener("deviceready", onDeviceReady, false);


4. Dans la callback 'onDeviceReady' on met en place le code nécessaire

function onDeviceReady() {
            alert("device pret");
            navigator.geolocation.getCurrentPosition(onSuccess, onError);
        }

L'instruction : 'navigator.geolocalisation.getCurrentPosition(...)' permet de lancer une requête de géolocalisation.


5. Voici la callback qui affiche à l'écran les coordonnées de géolocalisation

// onSuccess Geolocation
function onSuccess(position) {
   alert( "onSuccess !" );
            
   var element = document.getElementById('geolocation');
   element.innerHTML = 'Latitude: ' + position.coords.latitude + '
' +
            'Longitude: '          + position.coords.longitude             + '
' +
            'Altitude: '           + position.coords.altitude              + '
' +
            'Accuracy: '           + position.coords.accuracy              + '
' +
            'Altitude Accuracy: '  + position.coords.altitudeAccuracy      + '
' +
            'Heading: '            + position.coords.heading               + '
' +
            'Speed: '              + position.coords.speed                 + '
' +
            'Timestamp: '          + new Date(position.timestamp)          + '
';
        }



6. Voici le source de la page HTML en entier



7. Capture d'écran du résultat final sur le smartphone


jeudi 15 mars 2012

Tutorial Objective-C : Appeler du code C++ d'un programme Objective-C

Ce tutorial a pour but d'expliquer comment appeler du code C++ d'une application écrite en Objective-C, voir avec le framework Cocoa ou Cocoa Touch.

Il est fort à parier que bon nombre d'entreprises ayant des applications écrites en C++, les porteront vers Mac OS X ou iOS.
Pour ce faire il est fort utile de créer des applications bénéficiant d'une interface graphique écrite avec COCOA et l'outil Interface Builder, mais dont le coeur est en C++.


Le tutorial :

1) Créer un projet avec XCode (ici XCode 4) du type console



























2) Dans notre projet il y aura les fichiers suivants :











a) Le fichier 'main.m' sera du pur Objective-C
b) Les fichiers 'Wrapper.h' et 'Wrapper.mm' sera la classe Objective-C intégrant et appelant du code C++
c) Les fichiers 'CATPeageSimulation.h' et 'CATPeageSimulation.cpp' représentant le pur code C++, sans trace d'Objective-C


3) Le fichier 'main.m' (en Objective-C)

#import "WrapperCPP.h"

// SOURCE Objective-C
int main (int argc, const char * argv[])
{
    @autoreleasepool {
        
        NSLog(@"Programme Objective-C appelant du code C++");
        
        WrapperCPP * pw = [[WrapperCPP alloc] init];
        
        [pw launchSimu];
        
    }
    return 0;
}

Ci-dessus le source du main écrit en Objective-C.
On constate la création d'un objet représenté par le pointeur 'pw'.

Ici pas de 'release' nous disposons d'un GC.


4) Le "wrapper" : fichiers 'WrapperCPP.h" et "WrapperCPP.mm"

WrapperCPP.h

// Prototype Objective-C de la classe WrapperCPP
@interface WrapperCPP : NSObject

-(void) launchSimu;

@end

WrapperCPP.mm

#import "WrapperCPP.h"

#include "CATPeageSimulation.h"

// Implementation Objective-C
@implementation WrapperCPP

// Implementation du message Objective-C
-(void) launchSimu {
    
    // ######################################
    // ICI LE CODE C++
    
    CATPeageSimulation objet1;
    int ret = objet1.RunSimu();
    
    if( ret )
        std::cout << "echec au retour de simu" << std::endl;

    // ######################################
   
}

@end

Ci-dessus le fichier "mm" obligatoire pour intégrer dans des classes Objective-C du code C++.


5) Le code C++ (uniquement du code C++) 


CATPeageSimulation.h
#ifndef Objective_C_AppelerCPP_ltm_CATPeageSimulation_h
#define Objective_C_AppelerCPP_ltm_CATPeageSimulation_h

#define NUM_THREADS 256

class CATPeageSimulation {
private:
    
public:
    CATPeageSimulation();
    virtual ~CATPeageSimulation();
    
    int RunSimu();
};

void * ThreadVoiture( void * );
int Random( int, int );

#endif



CATPeageSimulation.cpp
#include "CATPeageSimulation.h"

pthread_mutex_t mutex_caisse;

// Thread voiture
void * ThreadVoiture( void * threadid ) {
    long tid = (long)threadid;
    
    printf( "Thread voiture, thread #%ld, je fais la queue\n", tid );
    pthread_mutex_lock( &mutex_caisse );
    printf( "Thread voiture, thread #%ld, je paye\n", tid );
    
    // Random( x, y ) -> la valeur va être comprise entre x et y en seconde(s)
    sleep( Random( 10, 20 ) );
    
    printf( "Thread voiture, thread #%ld, j'ai payé\n", tid );
    sleep(1);
    pthread_mutex_unlock( &mutex_caisse );
    
    pthread_exit( NULL );

}

int Random( int min, int max ) {
    return (min +( rand() % (max - min + 1 )));
}

// ctor
CATPeageSimulation::CATPeageSimulation() {
}

// dtor
CATPeageSimulation::~CATPeageSimulation() {
}

int CATPeageSimulation::RunSimu() {
    pthread_t threads[NUM_THREADS];
    int rc = 0, t = 0;
    unsigned int nbr_c = 1, nbr_v;
    
    printf("\n\nEntrez le nbr de voiture se présentant au peage ? ");
scanf( "%d", &nbr_v );
    
    if( nbr_c <= 0 || nbr_v <=0 ) {
        printf( "chiffre négatif\n" );
        return 1;
    }
    
    printf ( "nbr de caisse = %d\n", nbr_c );

    if( pthread_mutex_init( &mutex_caisse, NULL ) ) {
        printf( "init mutex failed -> exit\n" );
        return 1;
    }
    
    for ( t=0; t < nbr_v; t++ ) {
        rc = pthread_create( &threads[0], NULL, ThreadVoiture, (void *)t );
    }
    
    for ( t=0; t < nbr_v; t++ ) {
        pthread_join( threads[t], NULL);
        printf( "thread %d joined\n", t );
    }

    pthread_mutex_destroy( &mutex_caisse );
    
    printf( "Fin de simulation !\n" );
    return 0;
}


Fin du tutorial

En résumé :
Un programme 'main.m' appelle une classe écrite en Objective-C Wrapper.mm qui appelle du pur code C++.

main.m : code Objective-C uniquement
Wrapper.mm : Mélange d'Objective-C appelant du code C++
CATPeageSimulation.cpp : Pur code C ++





mercredi 14 mars 2012

Tutorial rapide iOS : Afficher une MessageBox - UIAlertView

iOS, IPhone, IPad : Afficher une boîte de message.

Souvent dans le cadre d'un développement d'application mobile, on a besoin d'afficher une simple boîte de message, appelée le plus souvent par les développeurs : MessageBox.

La classe utilisée en Objective-C est : UIAlertview

UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Titre de la boîte" 
message:@"Message dans la boîte" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];

// Affiche la boîte
[alert show];

Remarque : Ici le code étant dédié à iOS5 on n'intègre pas le release du pointeur alert.

mercredi 11 janvier 2012

Tutorial Phonegap : Installation

Phonegap est un projet open source permettant le développement d'applications mobiles sur de multiples plateformes comme : iOS, Android, Windows Phone, Blackberry, : http://phonegap.com/

Les technologies utilisées sont : HTML5, CSS3 et javascript : 1 seul code sur x plateformes.

Sur chaque outil de développement (ci-dessous XCode d'APPLE(tm)), il existe des bibliothèques, des librairies javascript adaptées et des "plug in" qui permettent de créer des projets dans l'IDE.

Ici intégration dans l'IDE XCode








Voici un petit tutorial pour l'installer sur XCode4

1. Télécharger du site PhoneGap le fichier dmg (ici le fichier téléchargé) et l'installer :












2. Lancer XCode4 et créez un projet Phonegap














3. Donnez un nom au projet

















4. La structure du projet dans XCode4














La structure ci-dessus est classique pour un développeur XCode. A savoir quand même qu'il nous manque un répertoire www dans le projet car la page de démarrage sera une page Html5 !


5. Essayons d'exécuter le code ci-dessus. 
XCode va utiliser le simulateur de l'IPhone si nous le choisissons dans la liste :
















Vous remarquez ci-dessus que le répertoire 'www' n'apparaît pas !
Appuyez sur le bouton RUN





















L'exécution se passe mal il nous manque dans le projet le répertoire avec la ou les pages web


6. Faites les manipulations suivantes :
Remarque : nous allons chercher sur le disque (grâce au finder) le répertoire 'www' et le glisser déposer dans le projet.












FAITES un DRAG and DROP du répertoire www vers le projet







Choisir l'option 'create folder references for any added folders'

















Ici on peut voir dans le projet que le répertoire 'www a été ajouté :














Résultat final :












mardi 29 novembre 2011

Tutorial Android : Lancer un service au boot d'AndroId

Il est tout à fait possible dans Android de lancer une application au démarrage du système d'exploitation, sans fenêtre graphique (sans activité), sans icône de démarrage, uniquement en tâche de fond : il s'agit d'un service.

Le tutorial suivant vous propose un petit programme uniquement constitué de deux composants Android, sans aucune interface graphique :

- 1 service (il sera notre tâche de fond)
- 1 "broadcast receiver". Celui-ci recevra un "intent" nous avertissant que le démarrage du système est terminé. Il lancera ensuite le service.

Remarque : Ici on utilise le sdk Android 2.2.

Voici les différentes étapes pour créer un tel programme :

1. Créez un projet Android sans activité graphique :

Ne pas sélectionner la création d'une activité




















2. Créez une classe service comme ci-dessous :


public class MonService extends Service {

@Override
public void onDestroy() {
Log.v( "LTM","onDestroy" );
super.onDestroy();
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.v( "LTM","onStartCommand" );
return super.onStartCommand(intent, flags, startId);
}

@Override
public IBinder onBind( Intent arg0 ) {
Log.v( "LTM","onBind" );
return null;
}
}



3. Créez une classe "receiver" comme ci-dessous :


public class MyReceiver extends BroadcastReceiver {

@Override
public void onReceive( Context ctx, Intent i ) {
Log.v( "LTM", "MyReceiver.onReceive : " + i.getAction() );
Intent intent = new Intent( ctx, MonService.class );
ctx.startService(intent);
}
}


4. Mettre à jour le fichier manifeste : il vous faut évidemment indiquer les 2 composants crées dans le fichier manifeste : le service et le receiver.
Il est nécessaire également d'intégrer la permission ci-dessous.



<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.ltm.service"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="8" />

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <service android:label="Mon beau service à moi" 
            android:name="MonService"
android:exported="false">
        service>
        <receiver
            android:name="MyReceiver">
<intent-filter>
                    <action android:name="android.intent.action.BOOT_COMPLETED" />
            intent-filter>
         receiver>
    application>
manifest>



5. Il ne vous reste plus qu'à compiler votre application et de la tester sur un périphérique.

Explications :
Notre application va recevoir l'intent 'BOOT_COMPLETED" via le receiver. Une fois cet événement reçu ce dernier lancera le service.

Et voilà, le tour est jouer !

A vous maintenant de jouer !