Question

Je suis en train d'apprendre comment utiliser ScriptingBridges. J'ai fait une méthode qui se fane lentement le volume sur iTunes, et je voudrais en faire une catégorie pour que je puisse faire ce qui suit:

iTunesApplication* iTunes = [SBApplication applicationWithBundleIdentifier:@"com.apple.iTunes"];
[iTunes lowerVolume:50 speed:1];

J'ai fait une autre catégorie pour NSSpeechSynthesizer qui fonctionne, mais je ne peux pas obtenir celui-ci à. Je continue à obtenir l'erreur de génération suivante:

"_OBJC_CLASS_$_iTunesApplication", referenced from:
l_OBJC_$_CATEGORY_iTunesApplication_$_iTunesApplicationAdditions in iTunesApplication.o
objc-class-ref-to-iTunesApplication in iTunesApplication.o
ld: symbol(s) not found
collect2: ld returned 1 exit status

Y at-il spécial quelque chose que je peux faire pour le faire fonctionner puisque je ne peux pas inclure les symboles?

Merci,
Ryan Pendleton

Mise à jour: Je ne trouve une solution, ce qui est inférieur. Elle implique MethodSwizzling, donc je suis ouvert à de meilleures réponses, mais pour maintenant il est tout ce que j'ai.

Était-ce utile?

La solution

La solution que j'ai trouvé était d'utiliser l'API d'exécution Objective-C. Je suis sûr qu'il ya une meilleure façon d'organiser, mais voici comment je l'ai fait:

Voici mes fichiers .h .m pour la création de la catégorie. Remarquez comment lowerVolume est pas une méthode réelle, mais une fonction C avec les arguments id self et SEL _CMD. Vous remarquerez également une fonction de setupCategories. Nous appellerons plus tard.

// iTunes+Volume.h

#import <objc/runtime.h>
#import "iTunes.h"

void lowerVolume(id self, SEL _cmd, int dest, float speed);
void setupCategories();

@interface iTunesApplication (Volume)

- (void)lowerVolume:(int)dest speed:(float)speed;

@end

// iTunes+Volume.m

#import "iTunes+Volume.h"

void lowerVolume(id self, SEL _cmd, int dest, float speed)
{
    NSLog(@"Lower Volume: %i, %f", dest, speed);
}

void setupCategories()
{
    id object = [[SBApplication alloc] initWithBundleIdentifier:@"com.apple.iTunes"];
    Class class = [object class];
    [object release];

    class_addMethod(class, @selector(lowerVolume:speed:), (IMP)lowerVolume, "@:if");
}

Maintenant que je l'ai fait les fonctions, je dois les ajouter en fait à la classe de pont de script en utilisant l'API d'exécution Objective-C. Je vais le faire en main.m pour vous assurer que les méthodes sont prêts à être utilisés au démarrage de la boucle d'exécution.

// main.m

#import <Cocoa/Cocoa.h>
#import "iTunes+Volume.h"

int main(int argc, char *argv[])
{
    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];

    setupCategories();
    return NSApplicationMain(argc,  (const char **) argv);

    [pool drain];
}

Maintenant, je peux utiliser ma méthode où je veux aussi longtemps que j'inclure les fichiers d'en-tête:

- (void)mute
{
    iTunesApplication* iTunes = [[SBApplication alloc] initWithBundleIdentifier:@"com.apple.iTunes"];
    [iTunes lowerVolume:0 speed:1];
    [iTunes release];
}

Si tout cela n'a pas de sens, juste me dire et je vais essayer de l'expliquer mieux.

Autres conseils

Je pense que vous devez inclure -framework ScriptingBridge à vos arguments gcc. Cela a obtenu le compiler pour moi!

Comme indiqué ci-dessus, vous ne pouvez pas faire facilement une catégorie sur iTunesApplication parce qu'il n'existe pas au moment de la compilation, et aussi parce que le nom de la classe d'exécution est ITunesApplication ( « I » majuscule).

La meilleure solution que j'ai trouvé est de faire votre catégorie de la classe qui existe, SBApplication. Voici le code je l'ai testé qui fonctionne et fait ce que l'exemple initial essayait de faire:

//  SBApplication+Extensions.h

@import ScriptingBridge;

@interface SBApplication (Extensions)

- (void)lowerVolume:(int)dest speed:(float)speed;

@end

//  SBApplication+Extensions.m

#import "iTunes.h"
#import "SBApplication+Extensions.h"

@implementation SBApplication (Extensions)

- (void)lowerVolume:(int)dest speed:(float)speed
{
    NSLog(@"Lower Volume: %i, %f", dest, speed);
}

@end

// Caller, say in AppDelegate

#import "SBApplication+Extensions.h"

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{

    iTunesApplication *iTunesApp =
        [SBApplication applicationWithBundleIdentifier:@"com.apple.iTunes"];

    [iTunesApp lowerVolume:4 speed:3.3f];
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top