Accéder au contenu principal

imagePickerController avec Mac Catalyst

Lorsque l'on utilise UIImagePickerController sous IOS, la fonction didFinishPickingMediaWithInfo renvoie l'image originale venant de la caméra ou de la photothèque à travers la variable imageInfo qui est un dictionnaire.

    UIImage *img = imageInfo[@"UIImagePickerControllerOriginalImage"];


Cela fonctionne très bien sous IOS, mais avec Mac Catalyst, lorsque l'on récupère une image de la photothèque, celle-ci n'est plus transmise, il n'y a que l'URL qui l'est :

    NSURL *url = imageInfo[@"UIImagePickerControllerReferenceURL"];


Mais je n'ai pas trouvé de fonction simple pour récupérer l'image à partir de l'URL. J'ai donc utilisé PHAsset::fetchAssetsWithLocalIdentifiers: mais cette fonction prend en paramètre l'UUID de l'image or cet UUID est en paramètre dans l'URL.

Par exemple, voici une URL que peut contenir imageInfo :

assets-library://asset/asset.jpeg?id=6D3B81E3-7332-46D7-AAB8-023F28AC4ADD&ext=jpeg


On a donc besoin de récupérer les variables, ce qui se fait avec un :

    NSString *query = url.query;


"query" vaut donc:

id=6D3B81E3-7332-46D7-AAB8-023F28AC4ADD&ext=jpeg


Puis on récupère la liste des variables+valeurs. Comme les variables sont séparée par des caractère "&" on fait un tableau des variables avec :

    NSArray *vars = [query componentsSeparatedByString:@"&"];


Pour chaque variable on se sert du caractère "=" pour séparer le nom de la variable de sa valeur :

    NSArray *variable = [var componentsSeparatedByString:@"="];

    NSString *name = variable.firstObject;

    NSString *value = variable.lastObject;


Si la variable est "id" on peut utiliser fetchImageWithLocalIdentifiers... Voici un code complet :

- (void) imagePickerController:(UIImagePickerController *)thePicker didFinishPickingMediaWithInfo:(NSDictionary *)imageInfo {

    [thePicker dismissViewControllerAnimated:YES completion:nil];


    for(NSString *key in imageInfo) NSLog(@"-- %@ : %@",key,imageInfo[key]);


    UIImage *img = imageInfo[@"UIImagePickerControllerOriginalImage"];

    if(img) {

        [self traitementImage:img];

        return;

    }


    NSURL *url = imageInfo[@"UIImagePickerControllerReferenceURL"];

    if(url) {

        NSString *query = url.query;

        NSArray *vars = [query componentsSeparatedByString:@"&"];

        for(NSString *var in vars) {

            NSArray *variable = [var componentsSeparatedByString:@"="];

            NSString *name = variable.firstObject;

            if([name isEqualToString:@"id"]) {

                NSString *value = variable.lastObject;

                PHAsset *asset = [PHAsset fetchAssetsWithLocalIdentifiers:@[ value ] options:nil].firstObject;

                PHCachingImageManager *cache = [PHCachingImageManager new];

                [cache requestImageForAsset:asset

                                 targetSize:CGSizeMake(640, 480)

                                contentMode:PHImageContentModeAspectFill

                                    options:nil

                              resultHandler:^(UIImage *image,NSDictionary *infos) {

                      [self traitementImage:image];

                }];

                return;

            }

        }

    }

}


Il vaut mieux faire une fonction pour le traitement effectué avec l'image qui sera appelée soit avec l'image originale, soit avec l'image récupérée à partir de l'URL.

Commentaires

Posts les plus consultés de ce blog

IOS14 et Bonjour qui ne fonctionne pas.

 J'utilise Bonjour dans certaines de mes application pour échanger des données entre appareils se trouvant sur le même réseau local.  Depuis IOS14, vous devez déclarer dans info.plist : <key> NSLocalNetworkUsageDescription </key> <string> L'accès au réseau local est obligatoire pour.... </string> <key> NSBonjourServices </key> <array> <string> _http._tcp </string> </array>  La clef NSLocalNetworkUsageDescription est obligatoire pour toute utilisation du réseau local (en dehors des produits Apple comme AirDrop, AirPrint, etc.). C'est la même chose que l'accès à la caméra ou au micro, vous devez dire pourquoi vous désirez cet accès dans votre application. La clef NSBonjourServices est spécifique pour le protocole Bonjour, elle contient la liste des services que vous partagez avec Bonjour. Dans l'exemple, il s'agit d'un serveur web (http).

UITableView avec multi-sélection sur Mac Catalyst

Si vous mettez à YES les attributs Multi Selection  et Multi Sélection During Editing d'un UITableView, cela ne fonctionnera pas comme attendu sur Mac. C'est juste énervant et voici ubout de code qui règle le problème. #if TARGET_OS_MACCATALYST -( NSIndexPath *) tableView :( UITableView *)tableView willSelectRowAtIndexPath :( NSIndexPath *)indexPath {     if ([tableView. indexPathsForSelectedRows containsObject :indexPath]) {         [tableView deselectRowAtIndexPath :indexPath animated : NO ];         return nil ;     }     return indexPath; } -( NSIndexPath *) tableView :( UITableView *)tableView willDeselectRowAtIndexPath :( NSIndexPath *)indexPath {     if ([tableView. indexPathsForSelectedRows containsObject :indexPath]) {         return nil ;     }     return indexPath; } -( BOOL ) tableView :( UITableView *)tableView shouldHighlightRowAtIndexPath :( NSIndexPath *)indexPath {     for ( NSIndexPath *ip in tableView. indexPathsForSelectedRows ) {         [tabl

Tiret insécable

 Ecrivant un livre sur CoreAnimation en Objective-C et en Swift, j'écris souvent "Objective-C".  Mais je ne souhaite pas que la césure du texte se face avec le C, il me faut donc un tiret insécable. Malheureusement il n'y a pas de tiret insécable sur le clavier du Mac, il faut donc utiliser le caractère Unicode U+2011. Mais le clavier du Mac ne comprends pas non plus par défaut de possibilité d'ajouter un caractère par son code Unicode.  Il faut donc aller dans les réglages d'Apple, dans les réglages du clavier, dans les méthodes de saisie et ajouter le clavier "Universel (Unicode Hex)". Ensuite, lorsque l'on a besoin d'un caractère Unicode, on change de clavier et on utilise la touche Option + le code en hexadécimal. Pour accélérer le changement d'un clavier à l'autre, toujours dans les réglages du clavier, vous pouvez activer les raccourcis clavier. Bon, c'était encore trop long, alors j'ai mis un remplacement automatique da