5 Replies
      Latest reply: Nov 3, 2016 9:31 AM by hhas01 RSS
      Macho Man Randy Savage Level 3 Level 3 (305 points)

        How do I pass a file url or path, to a script potentially placed in my app's NSApplicationScriptsDirectory?

         

        I admit I haven't used Applescripts much. Normally I'm able to write what I what to do in regular ObjC but it seems scripting is the only way to achieve what I'm after here. So I drop a script in my apps app script directory and do:

         

        
        NSURL *urlToPassToScript = //...
        
        NSAppleEventDescriptor *event = [NSAppleEventDescriptor descriptorWithString:urlToPassToScript.path];
        
        NSUserAppleScriptTask *task = [[NSUserAppleScriptTask alloc]initWithURL:script error:&error];
        
        [task executeWithAppleEvent:event
                          completionHandler:^(NSAppleEventDescriptor * _Nullable result,
                                              NSError * _Nullable error)
                 {
                    NSLog(@"Error: %@",error);
                 }];
        

         

        I get:

        NSLocalizedFailureReason=/usr/bin/osascript: input data for -E was not an event

         

        So what's the proper way to pass a script an argument?

        • Re: Pass an argument to NSUserAppleScriptTask
          eskimo Apple Staff Apple Staff (6,975 points)

          I haven’t looked into this in detail but it would seem that NSUserAppleScriptTask is expecting an event descriptor rather than a data descriptor.  You’d construct that with +appleEventWithEventClass:eventID:targetDescriptor:returnID:transactionID:.  The event class and ID are then mapped to a handler to call within your script.  In this case you probably want kCoreEventClass and kAEOpenDocuments respectively, which translates to the AppleScript on open handler.  For example:

          on open docList
              set docCount to count of docList
              display dialog "count = " & docCount
          end open
          

          You supply the list of things to open via the keyDirectObject parameter, which you set via -setParamDescriptor:forKeyword:.

          Share and Enjoy

          Quinn “The Eskimo!”
          Apple Developer Relations, Developer Technical Support, Core OS/Hardware
          let myEmail = "eskimo" + "1" + "@apple.com"

            • Re: Pass an argument to NSUserAppleScriptTask
              Macho Man Randy Savage Level 3 Level 3 (305 points)

              Thanks a lot for responding with this helpful information. I was able to get it to work after playing with it a bit. My script had an on run function:

              on run argv
              --stuff
              end run
              
              

               

              This worked fine when running the script from terminal using osascript, but I wasn't able to get this to work calling it from ObjC. After changing on run to on open I was able to get this to work.

               

              int pid = [NSProcessInfo processInfo].processIdentifier;
              
              NSAppleEventDescriptor *targetDescriptor = [NSAppleEventDescriptor
                                                             descriptorWithDescriptorType:typeKernelProcessID
                                                                                         bytes:&pid
                                                                                        length:sizeof(pid)];
              
              NSAppleEventDescriptor *appleEventDescriptor = [NSAppleEventDescriptor
                                                                      appleEventWithEventClass:kCoreEventClass
                                                                      eventID:kAEOpenDocuments
                                                                      targetDescriptor:targetDescriptor
                                                                      returnID:kAutoGenerateReturnID
                                                                      transactionID:kAnyTransactionID];
              
              NSAppleEventDescriptor *list = [[NSAppleEventDescriptor alloc]initListDescriptor];
              
              
              
              [list insertDescriptor:[NSAppleEventDescriptor descriptorWithString:path] atIndex:1];
              
              
              [appleEventDescriptor setParamDescriptor:list forKeyword:keyDirectObject];
              
              
              //pass appleEventDescriptor to the task in when calling executeWithAppleEvent:completionHandler:
              
              
              
              

               

              How would you call a function with an arbitrary name, or is that not supported? The header file of NSAppleEventDescriptor and documentation seems a little hard to piece together.

               

              Thanks!

            • Re: Pass an argument to NSUserAppleScriptTask
              hhas01 Level 1 Level 1 (0 points)

              I see Apple forum software is still utterly broken and incompetent.