Affichage des articles dont le libellé est iOS. Afficher tous les articles
Affichage des articles dont le libellé est iOS. Afficher tous les articles

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.

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.

samedi 19 novembre 2011

Tutorial iOS : Détection multi touch - 2 doigts

Voici un petit tutorial pour vous apprendre à détecter l'événements "multitouch", permettant notamment de pratiquer le zoom avec 2 doigts !

Tout d'abord une citation de Steve Jobs : "Dieu nous a donné 10 stylets, on a besoin de rien d'autre !" (disait-t-il à ceux qui pensaient qu'il fallait une tablette ou un smartphone équipé d'un stylet).

Vous verrez ci-dessous :
1. Comment dans une UIView détecter les événements "touch" (la détection de vos doigts).
2. Les bases du dessin dans une UIView.
3. La fonction "[self setNeedsDisplay]" qui provoque le redessin d'une vue.
4. La mise en oeuvre des événements : touchesBegan, touchesMoved, touchesEnded et touchesCancelled.
5. Les classes UIEvent et UITouch.

On utilisera également les classes :
- NSString : classe de base Objective-C pour gérer les chaînes de caractères, avec notamment son constructeur spécifique initWithFormat, très pratique pour formater une chaîne (type sprintf du langage C).
- NSSet : classe utilitaire qui retourne un jeu d'objets, à utiliser avec un NSEnumerator pour itérer dans une liste. Pour gérer plusieurs touches (touch) simultanément, on récupère la liste des endroits pressés à l'écran (vos doigts).

Pré-requis :
1. Vous aurez besoin d'un MAC équipé de l'IDE XCode (3 ou 4).
2. D'un minimum de connaissances sur le langage Objective-C (Il existe un très bon bouquin en ligne de Pierre Chatelier : ici.
3. Un véritable périphérique c'est bien mieux, avec le Simulateur dans XCode vous pourrez au moins tester un minimum.
4. Savoir rajouter un classe Objective-C héritant de UIView et attachée au controleur.

Voici la petite application en question:

Notre application à l'exécution
- Les 2 premiers champs affichés : 'width' et 'height' représentent la taille de la vue (ici la partie jaune).

- Le 'tap count' représentent la nombre d'événements 'tap' pratiqués avec les doigts. Dans beaucoup d'applications iOS on intercepte très souvent le "tap simple", souvent le "double tap".

- p1 représentent le point où se trouve le premier doigt, p2 le second doigt.



1. création du projet avec XCode (ici XCode 4)

On choisit "iOS->Application->Single View Application"



Ici on choisit un projet "IPhone"































2. Une fois le projet crée, on ajoute une classe Objective-C héritant de UIView et on attache le contrôleur à cette vue.

File -> New -> New File
















Choisir UIView comme classe mère



















3. Implémentation de la vue : fichier header


@interface MaVue : UIView {
    @private
    int     _tap_count;
    CGPoint _point1, _point2;
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;

@end


Les 4 méthodes ci-dessus permettent d'intercepter les touches de doigts sur l'écran.

En gros : l'événement touchesBegan se produit quand vous posez le doigt. Ensuite quand vous déplacez le doigt (ou les doigts) touchesMoved se déclenche.
touchesEnded se produit quand vous relevez le doigt.
touchesCancelled se produit par exemple quand une autre application prend le focus !

Le membre _tap_count permet de mémoriser le nombre d'événements 'tap' enregistré.

Les membres _point1 et _point2 mémorisent les localisations des doigts posés.


4. Implémentation de la vue : fichier avec le code

Ci-dessous l'implémentation des 4 événements 'touch' :


-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
NSLog(@"touchesBegan !");
    self.multipleTouchEnabled = TRUE;
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
    NSLog(@"touchesMoved !");
    NSEnumerator * en = [touches objectEnumerator];
    
    UITouch * touch1 = [en nextObject];
    _point1 = [touch1 locationInView:self];
    
    UITouch * touch2 = [en nextObject];
    if( nil != touch2 ) {
        NSLog(@"touch2");
        _point2 = [touch2 locationInView:self];
    }
    
    [self setNeedsDisplay]; // invalidate the view
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
NSLog(@"touchesEnded !");
    for (UITouch *touch in touches) 
        _tap_count = touch.tapCount;
    
    [self setNeedsDisplay]; // invalidate the view
}

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event{
NSLog(@"touchesCancelled !");
}

- Dans la fonction touchesBegan on passe la vue en multitouch.

- Dans la fonction touchesMoved, on intercepte le déplacement des 2 doigts et on met à jour les points.

- La fonction touchesEnd met à jour le nombre de tap !



Ci-dessous la fonction de dessin de la vue :


- (void)drawRect:(CGRect) rect {
    NSLog(@"drawRect");
    UIFont   *font    = [UIFont systemFontOfSize:18.0];
    [[UIColor blueColor] set];
    
    // Affichage de la taille de la vue !
    CGPoint location = CGPointMake( 10, 20 );
    CGRect taille = [self bounds];
    NSString * tailles = [[NSString alloc] initWithFormat:@"view size width = %f", taille.size.width];
    [tailles drawAtPoint:location withFont:font];
//    [tailles release]; // dépend du système iOS utilisé
    
    location = CGPointMake( 10, 50 );
    NSString * tailles2 = [[NSString alloc] initWithFormat:@"view size height = %f", taille.size.height];
    [tailles2 drawAtPoint:location withFont:font];
//    [tailles2 release];
    
    // Affichage du nombre de tap !
    NSString * tap_count = [[NSString alloc] initWithFormat:@"tap count = %d", _tap_count];
    location = CGPointMake( 10, 80 );
    [tap_count drawAtPoint:location withFont:font];
//    [tap_count release];
    
    // Affichage du premier point !
    NSString * point1 = [[NSString alloc] initWithFormat:@"p1.x = %f, p1.y = %f", _point1.x, _point1.y];
    location = CGPointMake(10, 110);
    [point1 drawAtPoint:location withFont:font];
//    [point1 release];
    
    // Affichage du second point !
    NSString * point2 = [[NSString alloc] initWithFormat:@"p2.x = %f, p2.y = %f", _point2.x, _point2.y];
    location = CGPointMake(10, 140);
    [point2 drawAtPoint:location withFont:font];
//    [point2 release];
}


Ci-dessus le code de dessin de la vue. Cette méthode est provoquée notamment quand on appelle la fonction de re dessin de la vue : setNeedsDisplay.
On affiche les résultats à l'écran.

A vous de jouer maintenant !

mercredi 26 octobre 2011

Chercher les fuites mémoires avec XCode sur MACOSX

Si vous développez sous MACOSX avec l'outil de développement Apple(tm) : XCode (version 3 ou 4), vous disposez d'outils puissants de "monitoring" pour vos applications fonctionnant sous iOS ou MacOSX.
Vous pouvez ainsi mesurer : les threads, les core des processeurs, les temps d'exécution de vos méthodes, etc., et les fuites mémoires.

Pour ce il vous faut développer en Objective-C (ou en C++) avec XCode, en voici un exemple :

A gauche et au centre l'IDE XCode 4, à droite le "profileur"

Ci-dessus un tout petit programme écrit avec l'IDE XCode(tm) et écrit avec quelques lignes de langage Objective-C.

A noter : @autoreleasepool { ... } permet de spécifier le code pris en compte par la gestion de la bassine autorelease d'Objective-C.

Deux objets sont ainsi alloués (Alloc 1 et Alloc 2) :

- Le premier est pris en compte par la bassine "autorelease" du langage : [p autorelease];
- Le second (Alloc 2) est volontairement exclu de la bassine d'autorelease, on constate donc une fuite mémoire (image de droite -> Leaks, la barre rouge).

L'outil "profile" de XCode permet de faire des photos (snapshot) à intervalles réguliers et constate les fuites mémoires.

Bien pratique pour développer des applications avec MAC.

A savoir qu'un "garbage collector" est aussi disponible si vous développez avec Objective-C et XCode.


dimanche 16 octobre 2011

Tutorial IPhone : Une vue, un bouton et un label

Voici ci-après un tutorial permettant de créer une application IPhone avec XCode 3.2, Interface Builder et le langage Objective-C d'Apple(tm), système d'exploitation iOS.

Au programme :
1) Création du projet
2) Gestion du projet dans XCode 3
3) Utilisation d'InterfaceBuilder : customisation de la vue, ajout d'un bouton et d'un label
4) Création dans IB d'une variable outlet pour le label, puis une action pour le bouton
5) On relie le contrôleur graphique au code du projet dans XCode
6) On surcharge la méthode click du bouton pour mettre à jour le label.
7) On teste




















vendredi 14 octobre 2011

Tutorial création d'une application IPhone ultra simple

Voici un petit tutorial qui consiste à réaliser une application IPhone avec XCode 3.
On dessine le texte dans l'espace de dessin de la vue.
On ne manipule pas dans cet exemple de "widgets" iOS.

Le test final de l'application est réalisé sur le simulteur IPhone intégré dans XCode.











vendredi 1 juillet 2011

PhoneGap ou développer Multiplateforme sur Mobile

Un des plus gros soucis rencontré actuellement concernant le développement mobile est l'aspect multiplateforme.

C'est un vrai casse tête pour le développeur : pas de Java sur iOS, pas de Flash. L'environnement de développement XCode pour iOS nécessite un MAC et de connaître le langage Objective-C : bref que du bonheur !

PhoneGap est un projet permettant de développement simplement des applications pour mobile avec un seul code.

C'est ici : http://www.phonegap.com

Un wiki pour les développeurs c'est ici : http://wiki.phonegap.com

Un bon tutorial montrant comment développer son IHM c'est ici : http://www.sencha.com/learn/Tutorial:Sencha_Touch_PhoneGap

Au rendez-vous technique : HTML5, JavaScript, extensions PhoneGap, etc.

Bref que du bonheur !