Accéder au contenu principal

Articles

Maccatalyst et Product Bundle Identifier

Les premières version de MacCatalyst (application iPad sur Mac) créaient un nouvel identifiant de package. Mon application Quadrillages avait donc deux identifiants : fr.lantranet.quadrillages et maccatalyst.fr.lantranet.quadrillages  Apple, a finalement décidé que les applications Mac et iPad pouvait avoir le même identifiant (et donc le même achat). Cela permet aussi sur AppStoreConnect de n'avoir qu'une seul entrée. C'est vrai que c'est mieux ainsi... Mais, j'avais déjà fait une app catalyst avec le deuxième identifiant, et Apple refuse de créer une nouvelle app Mac attachée à l'app IOS si une app de même nom existe déjà. Lors d'une mise à jour je me retrouve à faire le choix de supprimer l'application Mac pour la réintégrer ensuite dans l'application IOS. Je supprime donc l'app Mac (sur l'appStoreConnect), puis je crée une nouvelle app Mac comme attachée à l'app IOS. Un message de warning apparaît disant que l'identifiant de bundl
Articles récents

afconvert

J'utilise Audacity pour travailler mes sons, j'exporte ceci en WAV. Mais je préfère utiliser un format CAF avec mes programmes sur IOS. J'utilise donc le programme "afconvert" en ligne de commande pour faire la conversion. for i in *.wav;  do    afconvert -f caff -d LEI16@44100 -c 1 $i ${i%.wav}.caf;  done C'est tout simple.   

Adapter l'interface à la taille des caractères pour malvoyants.

Depuis quelques temps, je fais attention aux réglages de la taille des caractères systèmes. Les malvoyant peuvent décider dans les Réglages de l'iPad, Accessibilité de changer la taille des textes par défaut : Mais dans ce cas, les interfaces sont souvent trop petites, et les texte ne rentre pas dedans. Si vous avez besoin d'une valeur en pixel, en proportion du niveau de zoom des caractères, vous devez utilisez UIFontMetrics. if ( @available (iOS 11.0 , *)) {    larg = [ UIFontMetrics . defaultMetrics scaledValueForValue :larg]; } Ici, vous ne verrez aucune différence à moins de changer les réglages d'accessibilité. Mais, si vous touchez aux réglages, votre valeur en pixels correspondra au niveau de zoom. Cette fonctionnalité n'existe que depuis IOS 11, il faut donc mettre un available si vous compilez comme moi des apps pour IOS9. Je me sers de cette fonctionnalité, par exemple, dans : - ( CGSize ) collectionView :( UICollectionView *)collectionView             layo

archivedDataWithRootObject

archivedDataWithRootObject: est deprecated depuis IOS12.   NSData *data = [ NSKeyedArchiver archivedDataWithRootObject : @{} ]; // deprecated ISO12 Cela va avec l'avancée de SWIFT qui ne permet pas facilement de faire des tableaux de "trucs" non définis. C'est la nouvelle option requiringSecureCoding qui indique si le tableaux (NSDictionnary ou NSArray) peut contenir n'importe quoi ou uniquement des objets bien définis.   NSData  *data  = [ NSKeyedArchiver   archivedDataWithRootObject : @{}   requiringSecureCoding : NO   error :&error]; Le problème est que la fonction pour dés-archiver n'est pas deprecated, mais plante ! NSDictionary *dico = [ NSKeyedUnarchiver unarchivedObjectOfClass : NSDictionary . class                                                          fromData :data error :&error];  // plante Si l'on désire faire comme avant, il faut un requiresSecureCoding:NO, mais il n'y a pas le pendant du archivedDataWithRootObject ! Il n&#

UISwitch dans un UITableViewCell

Je construis des formulaire dans des UITable, chaque UITableViewCell peut donc contenir des UILabel, UISwitch, UIButton, etc. Je partage le code entre plusieurs application, mais j'ai eu un bug dans l'une d'elles que je n'avais pas dans les autres. Les gadgets interactifs ne fonctionnaient pas... En fait, j'avais construit mes UITableViewCell avec du code comme celui-ci : -( instancetype ) initWithStyle :( UITableViewCellStyle )style reuseIdentifier :( NSString *)reuseIdentifier {     self = [ super initWithStyle :style reuseIdentifier :reuseIdentifier];     self . backgroundColor = [ UIColor clearColor ];     _uiLabel = [ UILabel new ];     _uiLabel . frame = CGRectMake ( 8 , 4 , self . frame . size . width - 51 - 24 , self . frame . size . height - 8 );     _uiLabel . translatesAutoresizingMaskIntoConstraints = NO ;     _uiLabel . textAlignment = NSTextAlignmentLeft ;     _uiLabel . lineBreakMode = NSLineBreakByWordWrapping ;     _uiLabel . adjustsFontS

Boutons invisibles avec UIDocumentInteractionController

Les boutons OK et Export peuvent être invisibles dans un UIDocumentInteractionController. Il s'agit en fait de la couleur "tint" qui n'est pas fixée dans UINavigationBar. On fixe aussi le window.backgroundColor pour que la barre au dessus de l'application est bien un fond.      if ( @available (iOS 11.0 , *)) {         if ( @available (iOS 13.0 , *)) {             self . window . backgroundColor =                                                   UIColor . systemBackgroundColor ;             UINavigationBar . appearance . tintColor =                                               UIColor . linkColor ;         } else {             self . window . backgroundColor  =                                               UIColor . whiteColor ;             UINavigationBar . appearance . tintColor =                                               UIColor . systemBlueColor ;         }     } Les ligne d'Objective-C ci-dessus règlent le problème et sont à mettre directement

UISceneSession is only available on iOS 13

Lorsque vous faites une nouvelle application, celle-ci est par défaut pour le dernier IOS.  Mais si vos clients, comme les miens, ont de vieux appareils, vous pourriez vouloir que votre application fonctionne avec IOS9 (pour le moment on peut encore faire des apps IOS9, mais je crois que la limite sera IOS12 dans pas longtemps). Dans les infos de déploiement, vous changez donc le IOS 14  en IOS 9. Mais, le lancement de l'app vous donne un écran noir ! Pour régler le problème, il faut ajouter une propriété "window" dans l'interface du appDelegate. @interface AppDelegate : UIResponder < UIApplicationDelegate > @property ( strong , nonatomic ) UIWindow * window ; @end Reste les warnings... Le plus simple est de faire confiance à Xcode, tapez sur les warnings et un menu vous proposera un "fix" qui ajoutera un API_AVAILABLE à la définition de la fonction. - ( void ) scene :( UIScene *)scene willConnectToSession :( UISceneSession *)session options :(