How do I add Applescript support to my Cocoa application?

后端 未结 3 1209
感动是毒
感动是毒 2020-12-22 19:20

I am new to the world of Cocoa programming, and I want to add Applescript support to my application. The examples at Apple\'s website seem out of date.

How do I add

相关标签:
3条回答
  • 2020-12-22 19:21

    A simple example to get you started,

    place a script (named dialog) into the documents folder then you can run it from Xcode

    NSArray *arrayPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString *docDirectory = [arrayPaths objectAtIndex:0];
        NSString *filePath = [docDirectory stringByAppendingString:@"/dialog.scpt"];
    
         NSAppleScript *scriptObject = [[NSAppleScript alloc] initWithContentsOfURL:[NSURL fileURLWithPath:filePath] error:nil];
    
     [scriptObject executeAndReturnError:nil];
    

    The nice thing about keeping the script external is the ability to edit it outside of Xcode. I would recommend adding the error checking if you did start editing as the applescript may not compile

    maybe check with

    if(scriptObject.isCompiled){
    
    0 讨论(0)
  • 2020-12-22 19:44

    Modern versions of Cocoa can directly interpret the scripting definition (.sdef) property list, so all you need to do for basic AppleScript support is to create the sdef per the docs, add it to your "copy bundle resources" phase and declare AppleScript support in your Info.plist. To access objects other than NSApp, you define object specifiers, so each object knows its position in the scripting world's hierarchy. That gets you kvc manipulation of object properties, and the ability to use object methods as simple script commands.

    0 讨论(0)
  • 2020-12-22 19:48
    1. If you want to send AppleScript from your application and need a sandboxed app, you need to create a temporary entitlement

    2. You need to add those two keys in your info.plist

      <key>NSAppleScriptEnabled</key>
      <true/>
      <key>OSAScriptingDefinition</key>
      <string>MyAppName.sdef</string>
      

    ...of course you have to change "MyAppName" to your app's name

    1. Create a .sdef file and add it to your project. The further course now greatly depends on the needs of your application, there are:

      1. Class Elements (create an object from AppleScript)
      2. Command Elements (override NSScriptCommand and execute "verb-like" commands)
      3. Enumeration Elements
      4. Record-Type Elements
      5. Value-Type Elements (KVC)
      6. Cocoa Elements

      -

      Go here to find a detailed description and many details on their implementation: https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/ScriptableCocoaApplications/SApps_script_cmds/SAppsScriptCmds.html

    2. I found working with Class and KVC Elements very complicated, as I just wanted to execute a single command, nothing fancy. So in order to help others, here's an example of how to create a new simple command with one argument. In this example it'll "lookup" one string like this:

      tell application "MyAppName"
          lookup "some string"
      end tell
      
    3. The .sdef file for this command looks like this:

      <?xml version="1.0" encoding="UTF-8"?>
      <!DOCTYPE dictionary SYSTEM "file://localhost/System/Library/DTDs/sdef.dtd">
      
      <dictionary title="MyAppName">
          <suite name="MyAppName Suite" code="MApN" description="MyAppName Scripts">
              <command name="lookup" code="lkpstrng" description="Look up a string, searches for an entry">
                  <cocoa class="MyLookupCommand"/>
                  <direct-parameter description="The string to lookup">
                      <type type="text"/>
                  </direct-parameter>
              </command>
          </suite>
      </dictionary>
      
    4. Create a subclass of NSScriptCommand and name it MyLookupCommand

      The MyLookupCommand.h

      #import <Foundation/Foundation.h>
      
      @interface MyLookupCommand : NSScriptCommand
      
      @end
      

      The MyLookupCommand.m

      #import "MyLookupCommand.h"
      
      @implementation MyLookupCommand
      
      -(id)performDefaultImplementation {
      
          // get the arguments
          NSDictionary *args = [self evaluatedArguments];
          NSString *stringToSearch = @"";
          if(args.count) {
              stringToSearch = [args valueForKey:@""];    // get the direct argument
          } else {
              // raise error
              [self setScriptErrorNumber:-50];
              [self setScriptErrorString:@"Parameter Error: A Parameter is expected for the verb 'lookup' (You have to specify _what_ you want to lookup!)."];
          }
          // Implement your code logic (in this example, I'm just posting an internal notification)
          [[NSNotificationCenter defaultCenter] postNotificationName:@"AppShouldLookupStringNotification" object:stringToSearch];
          return nil;
      }
      
      @end
      

      That's basically it. The secret to this is to subclass NSScriptCommand and override performDefaultImplementation. I hope this helps someone to get it faster...

    0 讨论(0)
提交回复
热议问题