• 20 heures
  • Facile

Ce cours est visible gratuitement en ligne.

Ce cours existe en livre papier.

J'ai tout compris !

Mis à jour le 21/06/2013

Multimédia : l'image

Que diriez-vous d'exploiter le lecteur vidéo et l'appareil photo qui se cachent dans votre device ? Apple a bien fait les choses et ces fonctionnalités sont vraiment aisées à manipuler en Objective-C. Dans ce chapitre, je vous propose de découvrir comment insérer un lecteur vidéo dans vos applications pour lire tout fichier vidéo qui respecte les standards H.264 et MPEG-4 Part 2. Quelques lignes de code sont suffisantes ! Pour ne pas vous arrêter en si bon chemin, je vous montrerai ensuite comment prendre des photos dans une application et les stocker dans l'album photo du device. Là encore, il vous suffira d'écrire quelques lignes de code !

J'espère vous avoir mis l'eau à la bouche. Tournez vite les pages et découvrez comment procéder.

Jouer des éléments vidéo

Dans cette section, vous allez découvrir comment jouer des vidéos sur un device iOS. Cette prouesse réside dans l'utilisation du framework MediaPlayer, et plus particulièrement de la classe MPMoviePlayerController, incluse dans ce framework. La vidéo sera jouée dès l'exécution de l'application.

Créez une nouvelle application basée sur le modèle Single View Application et donnez-lui le nom « videoPlayer ».

Les fichiers d'extension .mov, .mp4, .mpv et .3gp sont supportés à condition qu'ils utilisent un des formats de compression suivants :

  • H.264 Baseline Profile Level 3.0 video, jusqu'à 640x480 pixels, 30 images par seconde ;

  • MPEG-4 Part 2 video.

Implémentation du framework MediaPlayer

Avant tout chose, il nous faut ajouter le framework MediaPlayer à l'application. Cliquez sur la première icône du volet de navigation, basculez sur l'onglet Build Phases et développez la zone Link Binary With Libraries. Cliquez sur l'icône + et ajoutez le framework MediaPlayer.framework.

Cliquez sur ViewController.h dans le volet de navigation et ajoutez une instruction import au début du fichier d'en-têtes pour accéder au framework MediaPlayer :

#import <MediaPlayer/MediaPlayer.h>

Tant que vous êtes dans le fichier d'en-têtes, définissez les variables d'instance lecteur, de classe MPMoviePlayerController ainsi qu'adresse, de classe NSURL :

MPMoviePlayerController* lecteur;
NSURL* adresse;

Définissez enfin la chaîne constante cheminComplet et initialisez-la comme suit :

#define cheminComplet @"http://www.siteduzero.com/uploads/fr/ftp/iphone/coins-arrondis.mp4"

Le fichier d'en-têtes devrait maintenant ressembler à ceci :

#import <UIKit/UIKit.h>
#import <MediaPlayer/MediaPlayer.h>
#define cheminComplet @"http://www.siteduzero.com/uploads/fr/ftp/iphone/coins-arrondis.mp4"
@interface ViewController : UIViewController
{
MPMoviePlayerController* lecteur;
NSURL* adresse;
}
@end

Affichage en mode paysage

Pour que l'application s'affiche en mode paysage par défaut, vous allez agir sur ses « informations de déploiement », c'est-à-dire sur l'écran Summary de l'application.

Comme à la figure suivante, cliquez sur l'entrée videoPlayer dans le volet de navigation (1), sélectionnez l'onglet Summary dans la partie centrale de la fenêtre (2) et demandez à ce que l'application ne s'affiche qu'en mode paysage orienté à gauche. Pour cela, cliquez sur Landscape Left pour que cette icône apparaisse en noir (3) et, si nécessaire, cliquez sur Portrait, Upside Down et/ou Landscape Right pour que ces icônes apparaissent en gris (4).

L'application doit s'afficher en mode paysage

Implémentation du lecteur

Cette application n'utilise aucun contrôle. Interface Builder ne nous sera donc d'aucune utilité. Cliquez directement sur ViewController.m dans le volet de navigation et modifiez la méthode viewDidLoad comme suit :

- (void)viewDidLoad
{
[super viewDidLoad];
adresse = [[NSURL alloc] initWithString:cheminComplet];
lecteur = [[MPMoviePlayerController alloc] initWithContentURL:adresse];
lecteur.view.frame = CGRectMake(0,0,480,310);
[self.view addSubview:lecteur.view];
[lecteur play];
}

La ligne 4 transforme la chaîne constante cheminComplet en un objet de classe NSURL en utilisant la méthode initWithString et l'affecte à la variable d'instance adresse :

adresse = [[NSURL alloc] initWithString:cheminComplet];

La ligne 5 initialise la variable d'instance lecteur (c'est-à-dire notre lecteur vidéo) en lui affectant l'adresse URL de la vidéo à jouer :

lecteur = [[MPMoviePlayerController alloc] initWithContentURL:adresse];

La ligne 6 définit la taille de la zone dans laquelle sera affichée la vidéo :

lecteur.view.frame = CGRectMake(0,0,480,310);

La ligne 7 ajoute la vidéo à la vue courante :

[self.view addSubview:lecteur.view];

Enfin, la ligne 8 déclenche la lecture de la vidéo :

[lecteur play];

Et c'est tout ? Cinq instructions suffisent vraiment pour créer un lecteur vidéo sur un device iOS ?

Eh bien oui. Et c'est bien là toute la puissance de la classe MPMoviePlayerController !

Pourquoi ne pas lancer l'application et voir si elle fonctionne. La figure suivante représente ce que vous devriez obtenir au bout de quelques secondes (ce temps est nécessaire pour précharger la vidéo qui, rappelons-le, se trouve sur le Web) :

La vidéo est lue dans l'application

Je sens que vous aimeriez aller plus loin avec cette application, c'est pourquoi je vous propose de lui ajouter un « observateur d'événements » afin de détecter la fin de la vidéo.

Pour définir un observateur d'événements, il faut créer un objet NSNotificationCenter et lui affecter un observateur, associé à l'événement que vous voulez observer. Dans le cas qui nous intéresse, l'événement « fin de la vidéo » répond au joli nom de :

MPMoviePlayerPlaybackDidFinishNotification

Je n'aurais jamais pu trouver ce nom d'événement tout seul. Comment savoir quels événements sont associés à un objet particulier ?

En consultant l'aide Apple de la classe correspondante bien sûr. Dans cette section, nous nous intéressons à la classe MPMoviePlayerController. C'est donc ici que vous trouverez les diverses notifications émises par ces objets.

Ajoutez l'instruction suivante au début de la méthode viewDidLoad :

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playbackFinished:) name:MPMoviePlayerPlaybackDidFinishNotification object:nil];

Cette instruction définit un objet NSNotificationCenter, lui ajoute un observateur de nom playbackFinished pour répondre à l'événement :

MPMoviePlayerPlaybackDidFinishNotification

Vous vous en doutez certainement, cette instruction ne se suffit pas à elle-même : il faut lui associer une méthode pour traiter la notification lorsqu'elle sera émise.

Ajoutez le code suivant :

- (void)playbackFinished:(NSNotification*)notification
{
NSNumber* raison = [[notification userInfo] objectForKey:MPMoviePlayerPlaybackDidFinishReasonUserInfoKey];
switch ([raison intValue])
{
case MPMovieFinishReasonPlaybackEnded:
NSLog(@"La vidéo a été entièrement lue");
break;
case MPMovieFinishReasonPlaybackError:
NSLog(@"Erreur de lecture");
break;
case MPMovieFinishReasonUserExited:
NSLog(@"L'utilisateur a mis fin à la vidéo");
break;
default:
break;
}
}

Que diriez-vous de détailler un peu ce code ? La ligne 3 récupère la valeur associée à la clé MPMoviePlayerPlaybackDidFinishReasonUserInfoKey. Cette clé donne la raison ayant provoqué la fin de la vidéo. En cliquant dans la fenêtre d'aide sur MPMoviePlayerPlaybackDidFinishReasonUserInfoKey puis sur MPMovieFinishReason, on obtient les différentes valeurs possibles pour cette clé (figure suivante).

Les différentes valeurs possibles pour la clé

Les instructions suivantes testent la valeur de la clé et affichent un message en conséquence dans la console. Bien évidemment, ils ne produiront aucun effet sur un device réel.

Les fichiers de cette application se trouvent dans le dossier videoPlayer.

ViewController.h
#import <UIKit/UIKit.h>
#import <MediaPlayer/MediaPlayer.h>
#define cheminComplet @"http://www.siteduzero.com/uploads/fr/ftp/iphone/coins-arrondis.mp4"
@interface ViewController : UIViewController
{
MPMoviePlayerController* lecteur;
NSURL* adresse;
}
@end
ViewController.m
#import "ViewController.h"
@implementation ViewController
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
- (void)playbackFinished:(NSNotification*)notification
{
NSNumber* raison = [[notification userInfo] objectForKey:MPMoviePlayerPlaybackDidFinishReasonUserInfoKey];
switch ([raison intValue])
{
case MPMovieFinishReasonPlaybackEnded:
NSLog(@"La vidéo a été entièrement lue");
break;
case MPMovieFinishReasonPlaybackError:
NSLog(@"Erreur de lecture");
break;
case MPMovieFinishReasonUserExited:
NSLog(@"L'utilisateur a mis fin à la vidéo");
break;
default:
break;
}
}
- (void)viewDidLoad
{
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playbackFinished:) name:MPMoviePlayerPlaybackDidFinishNotification object:nil];
adresse = [[NSURL alloc] initWithString:cheminComplet];
lecteur = [[MPMoviePlayerController alloc] initWithContentURL:adresse];
lecteur.view.frame = CGRectMake(0,0,480,310);
[self.view addSubview:lecteur.view];
[lecteur play];
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationLandscapeRight);
}
@end

Prendre des photos

Dans un chapitre précédent, vous avez appris à utiliser un objet pour choisir des images dans l'album photo et à les afficher sur l'écran. Nous allons nous appuyer sur ce projet pour manipuler l'appareil photo contenu dans un device iOS. Après validation par l'utilisateur, les photos seront stockées dans l'album photo.

Création du projet

Définissez un nouveau projet basé sur le modèle Single View Application et donnez-lui le nom « appPhoto ».

Une fois le projet créé, cliquez sur MainStoryboard.storyboard dans le volet de navigation, puis ajoutez un contrôle Rounded Rect Button et un contrôle Label. Double-cliquez sur le Rounded Rect Button et donnez-lui le nom « Prendre une photo ». Double-cliquez sur le contrôle Label et tapez « Appuyez sur le bouton pour prendre une photo ».

Redimensionnez et repositionnez ces contrôles pour obtenir quelque chose ressemblant à la figure suivante.

Disposez vos contrôles de cette manière

Vous allez maintenant ajouter une image de fond d'écran au projet. Je vous rappelle que cette image doit faire 320x480 pixels.

Cliquez du bouton droit sur l'icône appPhoto, affichée dans la partie supérieure du volet de navigation et sélectionnez New Group dans le menu contextuel. Renommez le nouveau dossier « Resources » et faites glissez l'image à utiliser en fond d'écran depuis le finder jusqu'au dossier Resources du volet de navigation.

À la fin du glisser-déposer, lorsque vous relâchez le bouton gauche de la souris, une boîte de dialogue intitulée Choose options for adding these files est affichée. Assurez-vous que la case Copy items into destination group's folder est cochée (ainsi, l'image sera copiée dans l'application), puis cliquez sur Finish.

Une fois l'image insérée dans les ressources, le volet de navigation devrait ressembler à la figure suivante.

Le volet de navigation du projet

Liaison des contrôles au code

Vous allez maintenant relier les contrôles Label et Rounded Rect Button au code.

En créant :

  • un outlet pour le contrôle Label, il sera possible d'afficher le nombre de photos prises avec l'application ;

  • une action pour le Rounded Rect Button, il sera possible de déclencher l'appareil photo sur un simple clic de l'utilisateur.

Cliquez sur Show the Assistant editor dans la barre d'outils de Xcode, puis contrôle-glissez-déposez le Label de la zone d'édition dans le fichier ViewController.h, juste au-dessus du @end final et créez l'outlet infos.

Contrôle-glissez-déposez le Rounded Rect Button de la zone d'édition dans le fichier ViewController.h, juste au-dessus du @end final et créez l'action prendPhoto, déclenchée sur l'événement Touch Up Inside.

Cette application va utiliser un UIImagePickerController (nécessaire pour la prise de vues) et un compteur de prises de vues. Pour mettre en place ces deux objets, définissez les variables d'instance suivantes :

UIImagePickerController *picker;
int compteur;

Si vous avez suivi mes consignes, le fichier d'en-têtes devrait avoir l'allure suivante :

#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
{
UIImagePickerController *picker;
int compteur;
}
@property (weak, nonatomic) IBOutlet UILabel *infos;
- (IBAction)prendPhoto:(id)sender;
@end

Écriture du code de l'application

Vous allez maintenant modifier le code de l'application. Cliquez sur ViewController.m dans le volet de navigation et complétez la méthode viewDidLoad comme suit :

- (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [[UIColor alloc] initWithPatternImage:[UIImage imageNamed:@"fond-ap-photo.jpg"]];
compteur = 0;
}

L'instruction de la ligne 4 indique que l'application utilisera l'image fond-ap-photo.jpg en arrière-plan de l'application.

L'instruction de la ligne 5 initialise la variable int compteur à 0. Cette variable sera utilisée pour comptabiliser le nombre de photos prises dans l'application. Il est donc tout à fait normal de l'initialiser à 0 au lancement de l'application.

Vous allez maintenant définir les instructions à exécuter lorsque l'utilisateur appuie sur le Rounded Rect Button. Localisez la méthode prendPhoto et complétez-la comme suit :

- (IBAction)prendPhoto:(id)sender
{
picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
[self presentModalViewController:picker animated:YES];
}

L'instruction de la ligne 3 définit l'objet UIImagePickerController picker et l'initialise :

picker = [[UIImagePickerController alloc] init];

L'instruction de la ligne 4 indique que les événements liés à l'UIImagePickerController seront gérés dans cette classe.

picker.delegate = self;

La ligne 5 indique que les données manipulées par l'UIImagePickerController proviendront de l'appareil photo :

picker.sourceType = UIImagePickerControllerSourceTypeCamera;

Enfin, la ligne 6 définit le mode d'affichage de l'UIImagePickerController :

[self presentModalViewController:picker animated:YES];

Il se peut qu'un triangle « Attention » de couleur jaune soit affiché en face de l'instruction picker.delegate = self;. Si tel est le cas, cliquez dessus pour prendre connaissance du problème. Voici ce qui est affiché :

Assigning to 'id<UINavigationControllerDelegate.UIImagePickerControllerDelegate>' from incompatible type 'appPhotoViewController *'

Ce type d'erreur a déjà été rencontré dans ce livre. Il signifie que vous devez ajouter un delegate (un gestionnaire d'événements) pour UINavigationControllerDelegate et UIImagePickerControllerDelegate.

Retournez dans le fichier ViewController.h et modifiez la déclaration de l'interface comme suit :

@interface appPhotoViewController : UIViewController <UINavigationControllerDelegate, UIImagePickerControllerDelegate>
{
...
}

Vous pouvez retourner dans le fichier ViewController.m et constater que l'avertissement a disparu.

Puisque nous venons d'indiquer que les événements générés par UIImagePickerController vont être gérés dans la classe appPhoto, nous allons écrire le code correspondant aux deux événements susceptibles de se produire : didFinishPickingMediaWithInfo et imagePickerControllerDidCancel.

Commencez par définir la méthode didFinishPickingMediaWithInfo :

- (void)imagePickerController:(UIImagePickerController *) Picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
UIImage *img = [info objectForKey:UIImagePickerControllerOriginalImage];
UIImageWriteToSavedPhotosAlbum(img, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
[[Picker parentViewController] dismissModalViewControllerAnimated:YES];
}

Lorsqu'une photo a été prise, la méthode didFinishPickingMediaWithInfo est exécutée et l'objet info de classe NSDictionary lui est transmis. La photo se trouve dans la clé UIImagePickerControllerOriginalImage de l'objet info. Pour la récupérer, on envoie un message à l'objet info ([info…) en lui demandant d'accéder à la clé (objectForKey:) UIImagePickerControllerOriginalImage. Cet objet est mémorisé dans l'objet img de classe UIImage :

UIImage *img = [info objectForKey:UIImagePickerControllerOriginalImage];

On utilise la méthode UIImageWriteToSavedPhotosAlbum pour sauvegarder la photo dans l'album photo :

UIImageWriteToSavedPhotosAlbum(img, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);}

Quatre paramètres sont transmis à cette méthode.

  1. La photo : img.

  2. L'objet pour lequel une méthode sera exécutée après la sauvegarde dans l'album. Le mot self signifie que la méthode à appeler se trouve dans la classe.

  3. Le nom de la méthode à exécuter lorsque la sauvegarde dans l'album a été faite : @selector(image:didFinishSavingWithError:contextInfo:).

  4. Un éventuel pointeur vers des données à passer à la méthode : nil. Ici, aucun pointeur n'est passé.

La dernière instruction supprime la vue de la photo qui vient d'être prise :

[[Picker parentViewController] dismissModalViewControllerAnimated:YES];

Lorsqu'une photo a été prise, l'utilisateur peut annuler sa sauvegarde dans l'album en appuyant sur le bouton Cancel. La méthode imagePickerControllerDidCancel est alors exécutée :

- (void)imagePickerControllerDidCancel:(UIImagePickerController *) Picker
{
[[Picker parentViewController] dismissModalViewControllerAnimated:YES];
}

L'instruction contenue dans cette méthode a déjà été rencontrée dans la méthode précédente, didFinishPickingMediaWithInfo. Elle supprime la vue de la photo qui vient d'être prise.

Rappelez-vous, dans la méthode didFinishPickingMediaWithInfo, on a utilisé la méthode UIImageWriteToSavedPhotosAlbum pour enregistrer la photo qui vient d'être prise dans l'album photo. Dans cette méthode, nous avons indiqué que la méthode didFinishSavingWithError devait être exécutée juste après la sauvegarde dans l'album photo. Pour en terminer avec le code, il reste donc à écrire cette méthode :

- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo
{
compteur++;
if (compteur == 1)
infos.text = @"1 photo ajoutée à l'album photo";
else
infos.text = [NSMutableString stringWithFormat:@"%i %@", compteur, @"photos ajoutées à l'album photo."];
}

Cette méthode est utilisée pour modifier le texte affiché dans le contrôle Label. Après avoir incrémenté le compteur de prises de vues avec compteur++;, la valeur du compteur est testée. Si une seule photo a été prise, le contrôle Label est mis à jour comme suit :

if (compteur == 1)
infos.text = @"1 photo ajoutée à l'album photo";

Si le compteur est différent de 1, cela signifie que plusieurs photos ont été prises. Le message est donc légèrement différent :

else
infos.text = [NSMutableString stringWithFormat:@"%i %@", compteur, @"photos ajoutées à l'album photo."];

Comme vous le voyez, le texte affiché dans le Label (infos.text) est obtenu en créant un objet NSMutableString ([NSMutableString …) dans lequel on concatène (stringWithFormat:) un entier et une chaîne (@"%i %@"). L'entier est la valeur de la variable compteur. La chaîne est spécifiée dans le troisième paramètre (@"photos ajoutées à l'album photo.").

L'application est entièrement fonctionnelle. Bien entendu, elle ne peut s'exécuter que sur un device réel. Si vous essayez de prendre une photo dans le simulateur iOS, une erreur sera affichée dans la console et l'application prendra fin.

Cette application se trouve dans le dossier appPhoto.

ViewController.h
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController<UINavigationControllerDelegate, UIImagePickerControllerDelegate>
{
UIImagePickerController *picker;
int compteur;
}
@property (weak, nonatomic) IBOutlet UILabel *infos;
- (IBAction)prendPhoto:(id)sender;
@end
ViewController.m
#import "ViewController.h"
@implementation ViewController
@synthesize infos;
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [[UIColor alloc] initWithPatternImage:[UIImage imageNamed:@"fond-ap-photo.jpg"]];
compteur = 0;
}
- (void)imagePickerController:(UIImagePickerController *) Picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
UIImage *img = [info objectForKey:UIImagePickerControllerOriginalImage];
UIImageWriteToSavedPhotosAlbum(img, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
[[Picker parentViewController] dismissModalViewControllerAnimated:YES];
}
- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo
{
compteur++;
if (compteur == 1)
infos.text = @"1 photo ajoutée à l'album photo";
else
infos.text = [NSMutableString stringWithFormat:@"%i %@", compteur, @"photos ajoutées à l'album photo."];
}
- (void)viewDidUnload
{
[self setInfos:nil];
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *) Picker
{
[[Picker parentViewController] dismissModalViewControllerAnimated:YES];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
- (IBAction)prendPhoto:(id)sender
{
picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
[self presentModalViewController:picker animated:YES];
}
@end

En résumé

  • Pour jouer des vidéos sur un device, vous utiliserez le framework MediaPlayer, et plus particulièrement la classe MPMoviePlayerController, incluse dans ce framework.

  • La méthode play déclenche la lecture de la vidéo.

  • L'événement MPMoviePlayerPlaybackDidFinishNotification permet de se tenir informé sur l'état de la vidéo (erreur de lecture, arrêt par l'utilisateur, vidéo entièrement lue).

  • Les fichiers d'extension .mov, .mp4, .mpv, et .3gp sont supportés, à condition qu'ils utilisent un des formats de compression H.264 Baseline Profile Level 3.0 video ou MPEG-4 Part 2 video.

  • L'objet UIImagePickerController permet de choisir des images dans l'album photo et de les afficher sur l'écran.

  • En affectant la valeur UIImagePickerControllerSourceTypeCamera à la propriété sourceType d'un tel objet, il est très simple de prendre des photos à partir d'une application. Une fois la photo prise, la méthode didFinishPickingMediaWithInfo est exécutée. Il suffit alors d'utiliser la méthode UIImageWriteToSavedPhotosAlbum : UIImageWriteToSavedPhotosAlbum pour sauvegarder la photo dans l'album photo.

Et si vous obteniez un diplôme OpenClassrooms ?
  • Formations jusqu’à 100 % financées
  • Date de début flexible
  • Projets professionnalisants
  • Mentorat individuel
Trouvez la formation et le financement faits pour vous
Exemple de certificat de réussite
Exemple de certificat de réussite