Расширить класс iTunesApplication с категориями
Вопрос
Я просто изучаю, как использовать ScriptingBridges. Я сделал метод, который медленно исчезает громкость на iTunes и хотел бы сделать его категорией, поэтому я могу сделать следующее:
iTunesApplication* iTunes = [SBApplication applicationWithBundleIdentifier:@"com.apple.iTunes"];
[iTunes lowerVolume:50 speed:1];
Я сделал другую категорию для NsspeechsyntheSizer, которая работает, но я не могу получить это. Я продолжаю получать следующую ошибку сборки:
"_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
Есть ли что-то особенное, я могу сделать, чтобы сделать его работать, так как я не могу включить символы?
Спасибо,
Райан Пендлтон
ОБНОВИТЬ:Я нашел только одно решение, которое ниже. Это включает в себя методы, поэтому я открыт для лучших ответов, но сейчас это все, что у меня есть.
Решение
Раствор, который я обнаружил, было использование API Objective-C Runtime API. Я уверен, что есть лучший способ организовать это, но вот как я это сделал:
Вот мои файлы .h и .m для создания категории. Обратите внимание, как lowerVolume
это не фактический метод, а функция C с аргументами id self
, и SEL _CMD
. Отказ Вы также заметите setupCategories
функция Мы позвоним это позже.
// 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");
}
Теперь, когда я выполнил функции, мне нужно действительно добавить их в класс сценариев, используя API Objective-C Stime. Я сделаю это в main.m
Чтобы убедиться, что методы готовы к использованию при запуске цикла пробега.
// 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];
}
Теперь я могу использовать свой метод, где бы я ни хотел, пока я включаю файлы заголовков:
- (void)mute
{
iTunesApplication* iTunes = [[SBApplication alloc] initWithBundleIdentifier:@"com.apple.iTunes"];
[iTunes lowerVolume:0 speed:1];
[iTunes release];
}
Если что -то из этого не имеет смысла, просто скажите мне, и я постараюсь объяснить это лучше.
Другие советы
Я думаю, тебе нужно включить -framework ScriptingBridge
к вашим аргументам GCC. Это заставило его скомпилировать для меня!
Как отмечалось выше, вы не можете легко сделать категорию на iTunesApplication, потому что она не существует во время компиляции, а также потому, что имя класса выполнения - iTunesApplication (капитал «I»).
Лучшее решение, которое я обнаружил, - это сделать вашу категорию в классе, который существует, Sbapplication. Вот код, который я проверил, который работает и делает то, что пытался сделать первоначальный пример:
// 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];
}