Search code examples
objective-cswiftapplescriptapplescript-objc

Unrecognized Selector in Swift/Objective-C/Applescript project


I'm getting the following message when running this simple ASObjc program interfaced with Swift:

 *** -[ASMyObject foo:]: unrecognized selector sent to object <ASMyObject @0x60c000226fe0: OSAID(4) ComponentInstance(0x810000)>

The code works as expected if I remove the parameters from foo. I realize there must be something wrong with the way I'm creating foo with a parameter.

Here's the code, based on this answer:

AppDelegate.swift

func applicationDidFinishLaunching(_ aNotification: Notification) {
    ASObjC.shared().myObject.foo(5)
}

ASMyObject.applescript

script ASMyObject
property parent : class "NSObject"

on foo(value)
    log value * 2
    return "Success!"
end foo

end script

ASObjC.h

@import Cocoa;
@import AppleScriptObjC;

@interface NSObject (MyObject)
    - (NSString *)foo:(int)value;
@end

@interface ASObjC : NSObject
    + (ASObjC *)shared;
    @property NSObject * MyObject;
@end

ASObjC.m

#import "ASObjC.h"

@implementation ASObjC

+ (void)initialize
{
    if (self == [ASObjC class]) {
        [[NSBundle mainBundle] loadAppleScriptObjectiveCScripts];
    }
}

+ (ASObjC *)shared
{
    static id shared = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        shared = [[ASObjC alloc] init];
    });

    return shared;
}

- (instancetype)init
{
    self = [super init];
    if (self) {
        _MyObject = [NSClassFromString(@"ASMyObject") new];
    }
    return self;
}

@end

Bridging-Header.h

#import "ASObjC.h"

Solution

  • You have to add an underscore character to represent the colon in ObjC

    on foo_(value)
        log value * 2
        return "Success!"
    end foo
    

    alternatively

    on foo:value
        log value * 2
        return "Success!"
    end foo
    

    and in the category you have to declare the method to pass an object, an ObjC primitive does not work.

    - (NSString *)foo:(NSNumber *)value;
    

    To assign the value on the AppleScript side you have to coerce it

    on foo:value
        log (value as integer) * 2
        return "Success!"
    end foo