سؤال

أنا فقط أتعلم كيفية استخدام ScriptingBridges. لقد صنعت طريقة تتلاشى ببطء في مستوى الصوت على iTunes ، وأرغب في جعلها فئة حتى أتمكن من القيام بما يلي:

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

لقد صنعت فئة أخرى لـ NSSPEECHSYNTHESISER التي تعمل ، لكن لا يمكنني الحصول على هذا. ما زلت أحصل على خطأ في البناء التالي:

"_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

هل هناك شيء مميز يمكنني القيام به لجعله يعمل لأنه لا يمكنني تضمين الرموز؟

شكرًا،
ريان بندلتون

تحديث:لقد وجدت حل واحد فقط ، وهو أدناه. إنه يتضمن methodswizzling ، لذلك أنا منفتح على إجابات أفضل ، ولكن الآن كل ما لدي.

هل كانت مفيدة؟

المحلول

كان الحل الذي وجدته هو استخدام واجهة برمجة تطبيقات وقت تشغيل Objective-C. أنا متأكد من أن هناك طريقة أفضل لتنظيم هذا ، ولكن إليك كيف فعلت ذلك:

فيما يلي ملفات .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");
}

الآن بعد أن قمت بالوظائف ، أحتاج إلى إضافتها فعليًا إلى فئة جسر البرمجة النصية باستخدام واجهة برمجة تطبيقات وقت تشغيل Objective-C. سأفعل هذا في 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 إلى حججكم في مجلس التعاون الخليجي. التي حصلت عليها لتجميع بالنسبة لي!

كما هو مذكور أعلاه ، لا يمكنك بسهولة القيام بفئة على 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];
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top