Fonctions spécifiques à  Lion: comment les inclures

APAP Membre
23:46 modifié dans API AppKit #1
Bonjour,

Je développe une application nécessitant Snow Leopard.
Cependant j'aimerais offrir pour les utilisateurs de Lion, la possibilité d'utiliser le nouveau mode plein écran.
Comment faut-il s'y prendre dans un tel cas? Créer 2 versions différentes?
faire une sorte de "conditionnel en fonction de la version du système" ?

Réponses

  • muqaddarmuqaddar Administrateur
    23:46 modifié #2
    Il doit y avoir des constantes pour tester la version du système, comme sur iOS.
    Du genre #ifdef MACOS_X_7 #else #endif
  • tabliertablier Membre
    23:46 modifié #3
    Du genre #ifdef MACOS_X_7 #else #endif
    Cela, ça permet de compiler pour Lion ou SnowLéopard. Mais Pour avoir une application unique qui marche quelque soit l'OS il faut détecter sa version et mettre les codes nécessaires pour chaque OS dans le projet. Exemple de détection de la version de l'OS:
    SInt32 osVersion;
    OSErr iErr ;
    iErr = Gestalt(gestaltSystemVersion, &osVersion);
    if((iErr == noErr) && (osVersion < 0x1070)) // need Lion 0x1070
    // code pour Snowléopard
    else
    // code pour Lion

  • muqaddarmuqaddar Administrateur
    23:46 modifié #4
    Très bonne réponse, tablier. 
    Il faut bien qu'il teste à  l'exécution et non à  la compilation si il veut faire une version commune.
  • AliGatorAliGator Membre, Modérateur
    août 2011 modifié #5
    Heu ce genre de méthodes qui sont nouvelles à  une version ne sont pas weak-linked ?
    C'est ce qui est fait en général, la méthode est rajoutée dans le SDK de Lion, est weak-linked, et du coup le pointeur de fonction est NULL sur les systèmes pré-Lion, et pointe vers la fonction sur un système OSX.7

    Tout est expliqué, comme d'hab... devinez où... hé, oui, ici ! (et Là  du coup aussi, en suivant les liens vers les pages plus détaillées)

    Je déconseillerais l'utilisation de Gestalt, d'une parce qu'Apple le déconseille aussi il me semble, mais aussi parce qu'en faisant cela, on teste la version de l'OS et non la disponibilité d'une API. Donc on ne teste pas le truc à  la racine, ce qui nous intéresse, mais un truc donc on sait qu'il a la conséquence de disponibilité ou non... c'est moins propre et moins portable.

    Exactement comme pour le développement web où l'on déconseille de tester la version du navigateur ou si on est sur IE ou Chrome ou Safari pour savoir s'il faut appeler telle ou telle méthode, et qu'on conseille à  la place... bah de tester directement si telle ou telle méthode existe avant de l'appeler. Autant tester... bah ce que l'on veut tester, et non un truc au niveau au dessus.
  • muqaddarmuqaddar Administrateur
    23:46 modifié #6
    Développer pour Lion sans Lion, c'est cavalier quand-même non ?
    Alors que dans l'autre sens, on peut s'en sortir.
  • 23:46 modifié #7
    Pour le plein écran c'est simple..
    <br />if([NSWindow instancesRespondsToSelector:@selector(toggleFullscreen:)])<br />{<br />	/// code pour Lion<br />}<br />
    


    Et tu peux faire ça pour plein d'autres choses
  • devulderdevulder Membre
    23:46 modifié #8
    dans 1314096087:

    Pour le plein écran c'est simple..
    <br />if([NSWindow instancesRespondsToSelector:@selector(toggleFullscreen:)])<br />{<br />	/// code pour Lion<br />}<br />
    


    Et tu peux faire ça pour plein d'autres choses


    Autre alternative avec l'échange de méthode, mais bon la méthode ci dessus est plus judicieuse.

    voir ici
  • 23:46 modifié #9
    dans 1314097151:

    dans 1314096087:

    Pour le plein écran c'est simple..
    <br />if([NSWindow instancesRespondsToSelector:@selector(toggleFullscreen:)])<br />{<br />	/// code pour Lion<br />}<br />
    


    Et tu peux faire ça pour plein d'autres choses


    Autre alternative avec l'échange de méthode, mais bon la méthode ci dessus est plus judicieuse.

    voir ici


    Heu carrément plus judicieuse oui.. Là  tu me montres un plugin, parce que le mec n'a pas accès au code source de TextMate...
  • tabliertablier Membre
    23:46 modifié #10
      Ben, je n'ai toujours pas Lion. Je vais probablement m'inscrire comme développeur en septembre.
    Le principe reste valable. Il faut, quelque soit le moyen, détecter la version de l'OS et mettre le code nécessaire pour chaque OS que l'on soutient. Gestalt existe depuis MacOS 7 (année 1995?) je pense, même si son utilisation n'est plus conseillée.

    Pour ceux qui sont restés de grands enfants (ou qui en ont des enfants) un Lion à  télécharger
  • FKDEVFKDEV Membre
    23:46 modifié #11
    dans 1314098252:

    Le principe reste valable. Il faut, quelque soit le moyen, détecter la version de l'OS et mettre le code nécessaire pour chaque OS que l'on soutient.


    Non le principe n'est pas le même. Détecter la version de l'OS est moins bien que détecter la présence de la fonctionnalité.

    C'est vrai que sur Mac OS, les deux méthodes donnent très souvent le même résultat mais il est bon de s'habituer à  faire comme l'a dit Ali (je lance un nouveau mémé au passage : "COM-LA-DI-ALI". Un gimmick qu'on peut utiliser dans 90% des threads de ce forum.).

    Sur iOS par exemple, beaucoup d'API sont liées à  un hardware qui peut ne pas être présent. Il est impossible de se baser sur la version de l'OS qui est la même dans tous les cas.
  • tabliertablier Membre
    23:46 modifié #12
    Non le principe n'est pas le même. Détecter la version de l'OS est moins bien que détecter la présence de la fonctionnalité.
    C'est vrai, mais sur Mac le sdk utilisé et la version de l'OS sont liés et je n'ai jamais eu de problème avec ma méthode.
      :P  NB: les exemples avec IOS sont à  poster dans dans la partie IOS du forum, bien sur.
  • AliGatorAliGator Membre, Modérateur
    23:46 modifié #13
    Pas forcément, j'ai pas d'exemple en tête mais tu peux avoir des méthodes ou des fonctions qui sont dispo dans SnowLeopard 32 bits et pas 64 bits par exemple, imaginons.
    En tout cas, de toute façon tu es justement en train de faire une supposition, à  savoir que la disponibilité d'un framework ou d'une de ses méthodes est liée à  la version du système, ce qui est peut-être vrai, en tout cas l'est certainement sous OSX pour la grande majorité des cas, mais tu n'es pas à  l'abri d'oublier un cas particulier (genre 32/64) pour lequel ça ne sera pas vrai. Autant tester directement ce que tu veux tester plutôt que de tester un truc plus haut niveau, quel intérêt de prendre ce risque de faire cette supposition sans être sûr qu'il n'y a pas d'exception ?

    C'est comme si tu disais "tiens pour récupérer le nom de tous les comptes utilisateurs de la machine, je vais lister le contenu du dossier /Users". C'est vrai que dans ce dossier y'a un sous-dossier par compte utilisateur, + le dossier "Shared", et donc que si tu ignores ce dernier, ça répondra à  ta question. Si un nouvel utilisateur est créé, un nouveau dossier sera créé par OSX ici.
    C'est bien, ça marche dans 99% des cas.
    Mais si l'utilisateur a créé de lui-même un dossier "Toto" dans "/Users", manuellement, alors qu'il n'y a pas de compte "Toto" sur la machine ? Ou si l'utilisateur a choisi de modifier les réglages de OSX (oui, on peut, même si c'est une manipulation plutôt avancée) pour modifier l'emplacement des dossiers utilisateurs et les mettre autre part que dans "/Users" ?
    Bref tu veux tester la liste des utilisateurs, demande au SDK de OSX de récupérer la liste des utilisateurs. Ne demande pas la liste des dossiers du dossier contenant les utilisateurs, en présupposant que ce soit lié et la même chose.

    Bah là  c'est pareil. Tu veux tester A (= "qu'une méthode existe"). Pourquoi se dire "Je sais que quand j'ai B, alors j'ai A, et quand j'ai pas B, j'ai pas A" (= quand j'ai 10.7 j'ai la méthode et quand j'ai pas 10.7 j'ai pas la méthode")... "donc je vais tester B pour savoir si j'ai A" ? Pourquoi ne pas tester A directement ?
  • tabliertablier Membre
    août 2011 modifié #14
    juste par esprit de contradiction (et pour le mac seulement):
    Pas forcément, j'ai pas d'exemple en tête mais ......... imaginons.
    Comme ça c'est clair: pas d'exemple.  Même si la méthode de test d'existence des méthodes est plus sure et que les utilisateurs peuvent faire n'importe quoi, j'observe que chaque SDK porte le n° de version d'un OS avec lequel il est associé. D'autre part, lorsque l'on programme on choisit un SDK et un "Mac OS X Deployment Target". Si c'est correcte on obtient un exécutable qui marche avec l'OS X minimum définit de cette manière.  Il suffit de vérifier au lancement que la version de l'OS courant est satisfaisante et basta!
    D'autre part je ne me vois pas tester l'existence de toutes les méthodes que j'utilise!
    Sinon à  quoi ça sert que Ducr qu'apple se décarcasse?
  • AliGatorAliGator Membre, Modérateur
    23:46 modifié #15
    Apple il se décarcasse... à  faire des docs pour indiquer comment faire du développement cross-versions de l'OS (cf les liens que j'ai fourni ci-dessus vers ladite doc Apple) justement, et c'est pas pour rien !

    Si j'ai pas d'exemple en tête, c'est parce que je ne fais plus de dévelopement MacOSX depuis un bail maintenant (m'étant concentré sur iOS). Donc si je peux pas te citer comme ça de tête un API du SDK OSX qui est weak-linked, sur iOS j'ai déjà  été confronté à  la question (et forcément j'ai suivi les recommandations Apple, vu qu'elles me paraissent logiques, je dirais même plus, faire autrement me semble aberrant du moins si pas justifié)

    Après, si tu préfères tester que 2*n est positif pour savoir si n est positif, plutôt que de tester n directement, c'est un choix bizarre, mais bon tu fais comme tu veux (et au passage tu introduis un bug, pour reprendre l'exemple du test du nombre positif, si tu fais ça, qui justement n'est pas trivial à  voir mais est pourtant un réel effet de bord)
  • APAP Membre
    23:46 modifié #16
    Merci pour toutes vos réponses. Je n'en demandais pas tant :)
  • tabliertablier Membre
    23:46 modifié #17
    .... des docs pour indiquer comment faire du développement cross-versions de l'OS (cf les liens que j'ai fourni ci-dessus vers ladite doc Apple) justement, et c'est pas pour rien
    Oui, je connais ces docs! Et non je ne testerai pas 2*n pour savoir si n est positif (sauf si je ne dispose que de 2*n). Je reste convaincu que si les SDK portent des n° de version  d'OS X, ce n'est pas pour des prunes.
  • FKDEVFKDEV Membre
    23:46 modifié #18
    dans 1314128079:

    D'autre part je ne me vois pas tester l'existence de toutes les méthodes que j'utilise!


    Et pourquoi pas ?


    Encore une fois je vais prendre l'exemple d'iOS, mais on sait bien qu'OS X ressemblera de plus en plus à  iOS.
    Aujourd'hui il n'y a pas vraiment de moyen automatisé de savoir avec quel OS un code donné est compatible. Il faut, en l'écrivant, avoir en tête la version minimum d'OS ciblé. Donc tout repose sur l'expérience et les bonnes pratiques.
    Ce qui est dommage car techniquement, à  part pour quelques cas tordus, il est possible de le faire.
    Ce serait à  Apple de le faire car personne n'a intérêt à  investir du temps dans ce genre d'outils, autant investir du temps dans la formation et la définition des bonnes pratiques.

    Cependant,  même quand on est conscient du problème, il y a un risque de se tromper.
    Moi par exemple je me suis fait avoir avec la classe NSDirectoryEnumerator. Rien de grave mais quand même dans un environnement de production cela aurait pu coûter quelques jours de retards.

    Cette classe est dispo depuis iOS 2.0, elle ne sert qu'à  énumérer le contenu d'un répertoire, le truc basique qui n'est en rien relié au hardware. Et ben... Apple a glissé des améliorations dans iOS 4.0 et je les ai utilisé sans faire gaffe alors que je vise iOS 3.2.
    Bien sur je l'en suis aperçu lors des tests mais j'aurais très bien pu passer à  côté car le bug n'est visible que sur les anciennes versions qui représente un faible pourcentage d'utilisateur et que je teste moins bien ne serait-ce que parce que je n'ai pas 15 iPad à  ma disposition.

    En l'occurrence, l'amélioration était simplement l'ajout d'une property "level" qui donne le niveau du fichier trouvé par  rapport à  la racine de la recherche, un truc anodin qui aurait pu être présent dès iOS 2.0.


    Tout ça pour dire que toute amélioration dans le domaine des dépendances est bonne à  prendre.
    Apple a le devoir de s'améliorer mais les développeurs ont aussi le devoir de progresser. Concrètement, avec ce que l'on sait aujourd'hui, il serait par exemple dommage de dire à  un stagiaire de tester la version de l'OS et non pas l'API du système. Sous-entendu, c'est peut-être trop tard pour toi, mais ce n'est pas une raison pour colporter des pratiques obsolètes.

    J'ai une suggestion pour Apple :
    Un système permettant de fournir dès la compilation une liste des méthodes utilisées avec une matrice de compatibilité par méthode devrait être intégré à  Xcode.
    Ensuite, on pourrait déplacer un curseur de version minimum compatible et on verrait les API qui risquent d'être absentes apparaà®tre en rouge.
    On pourrait alors regrouper ces API potentiellement absentes dans des groupes qui correspondrait aux fonctionnalités optionnelles de l'app et, au lancement de l'app, "NSBundle" nous fournirait la liste des groupes qui sont indisponibles à  cause de l'absence d'une ou plusieurs méthodes. Plus besoin, dans le code, de tester soi-même les méthodes qui correspondent au fonctionnalité du système, on teste directement les fonctionnalités de l'app.
    Merde, j'aurai dû déposer un brevet....

    En plus là  on parle du cas simple, où Apple ajoute des API. Mais il y aussi le cas où Apple retire des API, ou pire, modifie leur fonctionnement. Là  c'est la galère.



Connectez-vous ou Inscrivez-vous pour répondre.