Themes CSS HTML Ajax ?

02:49 modifié dans API AppKit #1
Salut à  tous,

Je ne sais pas si vous connaissez bowtie : http://www.bowtieapp.com
C'est un simple controleur iTunes avec des themes très sympas !
Les themes sont apparemment écrits avec du HTML + CSS (peut-être aussi de l'AJAX, je m'y connais pas trop sur les langages web).

Vous pouvez télécharger un pack de themes ici : http://lbaumann.com/download/bowtieThemesPack.zip

Comme j'ai aussi fait mon controleur iTunes, j'aimerai le rentre compatible avec les themes Bowtie pour mon "mini-controleur"

Quelqu'un serait-il capable de m'expliquer comment adpater ces themes dans mon application ? Je n'arrive pas à  cerner comment Bowtie fait pour gérer les themes en fait.

<br />$(&#39;title&#39;).innerHTML = track.property(&#39;title&#39;);<br />


Il me suffirait en fait de faire passer ces variables à  index.html apparemment, c'est donc la première chose que j'aimerai comprendre.
Ensuite j'aimerai aussi savoir comment il se débrouille pour afficher le theme. WebView transparente ??

Merci d'avance,
Louka.

Réponses

  • AliGatorAliGator Membre, Modérateur
    02:49 modifié #2
    L'extrait de code que tu donnes ce n'est pas du CSS mais du javascript, c'est une notation propre à  un framework JS bien connu (jQuery ou prototype.js je ne sais plus lequel utilise ces notations), où la fonction "$(x)" retourne l'élément de ton HTML qui a l'ID x.
    Ici le code dit donc "met comme contenu HTML interne à  l'élément d'ID "title" (sans doute un "<div id="title"></div>" dans le HTML) la valeur de track.property('title'). Où "track" est un objet représentant la piste iTunes courante j'imagine, et property() une fonction de cet objet javascript permettant de demander une propriété donnée de l'objet...

    Bref, c'est plutôt de l'AJAX à  la limite, en tout cas du javascript, et n'a donc rien à  voir avec CSS de ce côté.
  • 02:49 modifié #3
    dans 1230414413:

    L'extrait de code que tu donnes ce n'est pas du CSS mais du javascript, c'est une notation propre à  un framework JS bien connu (jQuery ou prototype.js je ne sais plus lequel utilise ces notations), où la fonction "$(x)" retourne l'élément de ton HTML qui a l'ID x.
    Ici le code dit donc "met comme contenu HTML interne à  l'élément d'ID "title" (sans doute un "<div id="title"></div>" dans le HTML) la valeur de track.property('title'). Où "track" est un objet représentant la piste iTunes courante j'imagine, et property() une fonction de cet objet javascript permettant de demander une propriété donnée de l'objet...

    Bref, c'est plutôt de l'AJAX à  la limite, en tout cas du javascript, et n'a donc rien à  voir avec CSS de ce côté.


    Je remonte le sujet car je vais vraiment avoir besoin de supporter ce type de themes.
    Quel serait donc le moyen de communiquer avec le theme en choisi ? Il existe un framework pour ça ? Il faut passer par des paramètres dans l'URL ?

    Louka.
  • NoNo Membre
    02:49 modifié #4
    J'ai vaguement regardé l'appli en question.
    A priori, il s'agit d'une webview qui affiche le fichier .html contenu dans le thème.
    Ce fichier .html est décoré par des styles css.
    Enfin, quelques fonctions javascript vont être utilisé pour "animer" le tout, et permettre la communication des infos entre html et programme Objective-C.

    Cette page html communique avec l'appli Obj-c via le javascript-bridge (voir ce post pour les détails).

    En conclusion, toute l'ui est en html, et le reste (le non-visible) est en objective-C.

    Tu te lances dans un très gros travail, d'autant plus que la partie Obj-C est non documentée.
  • 02:49 modifié #5
    dans 1242129670:

    Tu te lances dans un très gros travail, d'autant plus que la partie Obj-C est non documentée.


    J'ai vraiment besoin d'une documentation? La partie "playerLogic.js" du theme ne suffit pas pour le faire communiquer avec mon application?
    Je regarderai ce soir, merci pour l'infos en tout cas.
  • NoNo Membre
    02:49 modifié #6
    dans 1242140404:

    J'ai vraiment besoin d'une documentation? La partie "playerLogic.js" du theme ne suffit pas pour le faire communiquer avec mon application?


    La partie javascript n'est qu'une coquille vide.
    Par exemple, en javascript, lorsque tu lances un iTunes.nextTrack() dans ton script, le javascript-bridge appelle en réalité la méthode -(void)nextTrack de la classe qui implémente le protocole BTPlayerProxy. Cette méthode réalise sans doute (en fait, sûrement) un appel AppleScript vers iTunes pour lui ordonner de changer de piste.

    Si tu veux réutiliser les thèmes, tu devras créer une classe dans ton appli qui implémente le protocole BTPlayerProxy. Or ce protocole n'est pas documenté.
    Un class-dump sur Bowtie nous donne les méthodes dont les noms restent explicites :
    @protocol BTPlayerProxy<br />- (int)iTunesRunning;<br />- (BOOL)canShow;<br />- (void)show;<br />- (void)play;<br />- (void)pause;<br />- (void)stop;<br />- (void)playPause;<br />- (void)nextTrack;<br />- (void)previousTrack;<br />- (void)playTrackWithID:(id)fp8;<br />- (int)shuffle;<br />- (void)setShuffle:(int)fp8;<br />- (int)repeat;<br />- (void)setRepeat:(int)fp8;<br />- (int)rating;<br />- (void)setRating:(int)fp8;<br />- (int)volume;<br />- (void)setVolume:(int)fp8;<br />- (int)playState;<br />- (int)playerPosition;<br />- (void)setPlayerPosition:(int)fp8;<br />- (id)currentTrack;<br />- (id)artwork;<br />- (id)uniqueString;<br />- (id)searchDataSource;<br />@end<br />
    

    mais ça reste du reverse-engineering (avec la problématique de la légalité de la chose), et tu marches quand même un peu dans la nuit.
  • mai 2009 modifié #7
    J'ai un peu regardé en effet (pas pu resister) et j'avais donc commencé à  implémenter des trucs genre "nextTrack".. le problème c'est que ça fait rien :|
    J'ai envoyé un mail au développeur pour savoir s'il pouvait faire un framework ou rendre la classe publique..

    Au moment où je fais un register de ma classe sur le javascript, il faut utiliser quel clé? Car aucune des méthodes (nextTrack) n'est renvoyée vers mon controller.
    <br />id jswindow=[webView windowScriptObject];<br />	<br />	// enregistrement de self (mon objet controleur) dans cet objet javascript &quot;window&quot;<br />	[jswindow setValue:self forKey:Clé???];<br /><br />
    

    Au pire des cas je pense que je ferai mon propre JS à  partir de 2-3 themes avec l'accord des graphistes respectifs :)
  • NoNo Membre
    02:49 modifié #8
    dans 1242152806:

    Au moment où je fais un register de ma classe sur le javascript, il faut utiliser quel clé? Car aucune des méthodes (nextTrack) n'est renvoyée vers mon controller.
    <br />id jswindow=[webView windowScriptObject];<br />	<br />	// enregistrement de self (mon objet controleur) dans cet objet javascript &quot;window&quot;<br />	[jswindow setValue:self forKey:Clé???];<br /><br />
    



    La clé, c'est iTunes :
    <br />id jswindow=[webView windowScriptObject];<br /><br />// enregistrement de self (mon objet controleur) dans cet objet javascript &quot;window&quot;<br />[jswindow setValue:self forKey:@&quot;iTunes&quot;];<br />
    


    Mais attention, il faut autoriser les méthodes Obj-C pour être appeler depuis javascript en implantant la méthode de classe +(BOOL)isSelectorExcludedFromWebScript:(SEL)aSelector
    (dans la même classe que self) :
    <br />+ (BOOL)isSelectorExcludedFromWebScript:(SEL)aSelector<br />{<br />&nbsp;  return NO;<br />}<br />
    
  • 02:49 modifié #9
    Super  :o
    Par contre t'as une idée de ce qu'il envoie quand il fait "trackUpdate(track)" ? C'est ce "track" qui m'intrigue.
    D'ailleurs faut-il bien utiliser la méthode "callWebScriptMethode:@laMethode withArguments:" dans le cas où je dois communiquer de mon Object vers le Javascript?
  • mai 2009 modifié #10

    BTWrapper Interface

    [BTWrapper] obj.property([string] prop) " (multiple return types)

    The BTWrapper object is used to wrap dictionaries (“associative arrays”, or just normal objects in JavaScript) used in Bowtie for access via WebKit. It has a single method, property, which takes a single parameter, “prop”, which is a string representing the requested property. The return type varies depending on the property requested. For instance, BTWrapper's wrapping track information contain the following properties:

    title (string)
    artist (string)
    album (string)
    genre (string)
    length (float)



    Le truc c'est que j'ai beau mettre - (NSString*)property:(id)prop ça ne marche pas... j'ai loupé quelque chose ?
  • AliGatorAliGator Membre, Modérateur
    02:49 modifié #11
    Heu j'ai rien compris et trop rien suivi à  la conversation, mais du peu que je lis de ton extrait, c'est le paramètre qui est un NSString et le type de retour qui est anything donc id, non ?
    -(id)property:(NSString*)prop;
  • 02:49 modifié #12
    dans 1242199992:

    Heu j'ai rien compris et trop rien suivi à  la conversation, mais du peu que je lis de ton extrait, c'est le paramètre qui est un NSString et le type de retour qui est anything donc id, non ?
    -(id)property:(NSString*)prop;

    Oui au temps pour moi. Mais la méthode n'est pas appelée quand meme... je comprend pas trop sur ce coup :D
  • NoNo Membre
    02:49 modifié #13
    Tu dois créer/modifier une classe pour répondre répondre à  la méthode property: :
    <br />- (id)property:(id)prop<br />{<br />&nbsp;  if ([prop isEqual:@&quot;title&quot;]) return @&quot;le titre&quot;;<br />&nbsp;  if ([prop isEqual:@&quot;artist&quot;]) return @&quot;l&#39;artiste&quot;;<br />&nbsp;  if ([prop isEqual:@&quot;album&quot;]) return @&quot;l&#39;album&quot;;<br /><br />&nbsp;  return nil;<br />}
    


    Ensuite, tu dois appeler la méthode javascript trackUpdate() depuis ton prog Obj-C lorsque la piste lue par iTunes change (je pense que tu utilises la distributed notification pour détecter ça), avec comme unique argument l'objet dont la classe répond à  property: :
    <br />- (void)trackChangedNotification:(NSNotification *)notif<br />{<br />&nbsp;  // récupération du &quot;javascript bridge&quot;<br />&nbsp;  id js=[webView windowScriptObject];<br /> <br />&nbsp;  // création du tableau des arguments de la fonction javascript trackUpdate()&nbsp;  <br />&nbsp;  NSArray *arg=[NSArray arrayWithObjects:self,&nbsp; nil];<br /><br />&nbsp;  // appel de la fonction javascript trackUpdate() <br />&nbsp;  [js callWebScriptMethod:@&quot;trackUpdate&quot; withArguments:arg];<br />}<br />
    

    Ici, j'ai modifié ta classe précédente (celle qui répond aux méthodes nextTrack, etc...) pour implanter property:.
    C'est cette même classe qui est abonnée au distributed notification center pour recevoir les infos depuis iTunes.
    Enfin, c'est elle qui va appeller la fonction javascript trackUpdate().
  • mai 2009 modifié #14
    C'est exactement ce que j'avais fait mais il ne répond pas :|
    Si je fais :
    <br />- (id)property:(id)prop<br />{<br /> return @&quot;test&quot;;<br />}<br />
    

    Les champs du theme ne sont pas peuplés

    En revanche si je ne passe pas "prop" :
    <br />- (id)property<br />{<br /> return @&quot;lol&quot;;<br />}<br />
    


    J'ai bien "lol" à  tous les champs...
  • 02:49 modifié #15
    Oublie ce que j'avais mis après le "J'ai bien "lol" à  tous les champs...", j'avais oublié d'implémenter :
    <br />+ (BOOL)isSelectorExcludedFromWebScript:(SEL)aSelector<br />{<br />	return NO;<br />}<br />
    

    dans "Test"
  • NoNo Membre
    02:49 modifié #16
    J'ai trouvé !
    Là  je suis dans le train. Dès que je suis arrivé, je te poste la solution.
  • 02:49 modifié #17
    dans 1242231086:

    J'ai trouvé !
    Là  je suis dans le train. Dès que je suis arrivé, je te poste la solution.

    :| No, me fait plus jamais des coups pareils! Je vais devoir faire le ménage pour patienter sans m'impatienter  :o :o ;D
  • NoNo Membre
    02:49 modifié #18
    En fait, les gars de Bowtie sont un peu tordus.

    Normalement le javascript bridge effectue une correspondance entre nom de méthode js et nom de méthode Obj-C.
    Cette correspondance fait que chaque : (2 points) en Obj-C devient un _ (underscore) en js :



    Objective-C
    javascript


    [unObjet property]
    unObjet.property()


    [unObjet property:unParametre]
    unObjet.property_(unParametre)


    [unObjet property:unParametre et:autreParametre]
    unObjet.property_et_(unParametre, autreParametre)



    Donc logiquement, ce n'est pas track.property("title") qu'on devrait voir dans les scripts js des thèmes, mais track.property_("title"). Et là  effectivement ça marche.

    En fait dans Bowtie, c'est la méthode invokeUndefinedMethodFromWebScript:withArguments qui est appelée quand js appelle une méthode inconnue sur ton objet Obj-C.

    Donc à  implanter dans self :
    <br />- (id)invokeUndefinedMethodFromWebScript:(NSString *)name withArguments:(NSArray *)args<br />{<br />&nbsp;  // élimination des appels qui n&#39;ont pas comme nom &quot;property&quot; ou qui n&#39;ont pas d&#39;argument<br />&nbsp;  if (![name isEqual:@&quot;property&quot;]) return nil;<br />&nbsp;  if ([args count]&lt;1) return nil;<br /><br />&nbsp;  // récupération du premier argument<br />&nbsp;  NSString *property=[args objectAtIndex:0];<br /><br />&nbsp;  // selon cet argument, on retourne une chaine au script js<br />&nbsp;  if ([property isEqual:@&quot;title&quot;]) return @&quot;le titre&quot;;<br />&nbsp;  if ([property isEqual:@&quot;artist&quot;]) return @&quot;l&#39;artiste&quot;;<br />&nbsp;  if ([property isEqual:@&quot;album&quot;]) return @&quot;l&#39;album&quot;;<br /><br />&nbsp;  return nil;<br />}<br />
    
  • 02:49 modifié #19
    :| Et tu pense qu'il y a une raison précise du pourquoi qu'il aurait fait ça le mec?  ;D
    En tout cas merci beaucoup pour l'aide, vraiment content de pouvoir implémenter les magnifiques themes Bowtie!
    Special credits to No & OSX-Dev :p
Connectez-vous ou Inscrivez-vous pour répondre.