Lisp HUG Maillist Archive

objc and applescript

I want to call AppleScript from LW Objective-C.

What I have to do is about (from 
https://developer.apple.com/library/mac/technotes/tn2084/_index.html):

- (IBAction)addLoginItem:(id)sender
{
     NSDictionary* errorDict;
     NSAppleEventDescriptor* returnDescriptor = NULL;

     NSAppleScript* scriptObject = [[NSAppleScript alloc] initWithSource:
                 @"\
                 set app_path to path to me\n\
                 tell application \"System Events\"\n\
                 if \"AddLoginItem\" is not in (name of every login 
item) then\n\
                 make login item at end with properties {hidden:false, 
path:app_path}\n\
                 end if\n\
                 end tell"];

     returnDescriptor = [scriptObject executeAndReturnError: &errorDict];
     [scriptObject release];

     if (returnDescriptor != NULL)
     {
         // successful execution
         if (kAENullEvent != [returnDescriptor descriptorType])
         {
             // script returned an AppleScript result
             if (cAEList == [returnDescriptor descriptorType])
             {
                  // result is a list of other descriptors
             }
             else
             {
                 // coerce the result to the appropriate ObjC type
             }
         }
     }
     else
     {
         // no script result, handle error here
     }
}

My function looks like this

(defun applescript (text)
   (let (err
         (nsas (objc:invoke (objc:invoke "NSAppleScript" "alloc") 
"initWithSource:" text)))
     (objc:invoke nsas "executeAndReturnError:" err)
     (objc:release nsas)
     err))

and it works. I can execute AppleScript code. But I get no error 
information back. I tried:


(defun applescript (text)
   (let ((err (objc:invoke (objc:invoke "NSDictionary" "alloc") "init"))
         (nsas (objc:invoke (objc:invoke "NSAppleScript" "alloc") 
"initWithSource:" text)))
     (objc:invoke nsas "executeAndReturnError:" err)
     (objc:release nsas)
     err))

But I get an error

Error: #<Pointer: OBJC:OBJC-OBJECT-POINTER = #x0015D400> cannot be 
converted to foreign type (:POINTER OBJC:OBJC-OBJECT-POINTER).

This makes no sense to me.

[In a former life I tried to learn C and never completely grasped this 
pointer stuff. In my later lisp life I am very happy that there are no 
pointers at all.]

Thanks for enlightment.

~jens

_______________________________________________
Lisp Hug - the mailing list for LispWorks users
lisp-hug@lispworks.com
http://www.lispworks.com/support/lisp-hug.html


Re: objc and applescript

In the obj-c code you have this:

NSDictionary* errorDict; 
[scriptObject executeAndReturnError: &errorDict]; 

Notice that you are passing a pointer to the local stack address where a pointer (*errorDict) is held; you are passing a pointer to a pointer.

When you do:

(objc:invoke nsas "executeAndReturnError:" err)

Your 'err' variable is set to nil. While this is a valid objc-object-pointer (it points to the obj-c value nil), it isn't a valid pointer to one. And hence you get your error:

#<Pointer: OBJC:OBJC-OBJECT-POINTER = #x0015D400> cannot be converted to foreign type (:POINTER OBJC:OBJC-OBJECT-POINTER). 

What you need to do is create a pointer to an objc-object-pointer with FLI:MAKE-POINTER first, and pass *that* to your function. Try something like this:

(let ((err (fli:make-pointer :address 0 :type 'objc:objc-object-pointer)))
  (when (fli:null-pointer-p (objc:invoke nsas "executeAndReturnError:" err))   ; check for error
    (let ((dict (fli:dereference err)
      (unwind-protect
          ;; dict is now an NSDictionary you can look at...
        (objc:release dict)))))

The above is untested as I'm not at my Mac to ensure that it works, but if it doesn't it's on the right track and someone here will likely correct me quickly. ;-)

Jeff M.

Jens Teich
Friday, March 14, 2014 9:08 AM

I want to call AppleScript from LW Objective-C.

What I have to do is about (from https://developer.apple.com/library/mac/technotes/tn2084/_index.html):

- (IBAction)addLoginItem:(id)sender
{
    NSDictionary* errorDict;
    NSAppleEventDescriptor* returnDescriptor = NULL;

    NSAppleScript* scriptObject = [[NSAppleScript alloc] initWithSource:
                @"\
                set app_path to path to me\n\
                tell application \"System Events\"\n\
                if \"AddLoginItem\" is not in (name of every login item) then\n\
                make login item at end with properties {hidden:false, path:app_path}\n\
                end if\n\
                end tell"];

    returnDescriptor = [scriptObject executeAndReturnError: &errorDict];
    [scriptObject release];

    if (returnDescriptor != NULL)
    {
        // successful execution
        if (kAENullEvent != [returnDescriptor descriptorType])
        {
            // script returned an AppleScript result
            if (cAEList == [returnDescriptor descriptorType])
            {
                 // result is a list of other descriptors
            }
            else
            {
                // coerce the result to the appropriate ObjC type
            }
        }
    }
    else
    {
        // no script result, handle error here
    }
}

My function looks like this

(defun applescript (text)
  (let (err
        (nsas (objc:invoke (objc:invoke "NSAppleScript" "alloc") "initWithSource:" text)))
    (objc:invoke nsas "executeAndReturnError:" err)
    (objc:release nsas)
    err))

and it works. I can execute AppleScript code. But I get no error information back. I tried:


(defun applescript (text)
  (let ((err (objc:invoke (objc:invoke "NSDictionary" "alloc") "init"))
        (nsas (objc:invoke (objc:invoke "NSAppleScript" "alloc") "initWithSource:" text)))
    (objc:invoke nsas "executeAndReturnError:" err)
    (objc:release nsas)
    err))

But I get an error

Error: #<Pointer: OBJC:OBJC-OBJECT-POINTER = #x0015D400> cannot be converted to foreign type (:POINTER OBJC:OBJC-OBJECT-POINTER).

This makes no sense to me.

[In a former life I tried to learn C and never completely grasped this pointer stuff. In my later lisp life I am very happy that there are no pointers at all.]

Thanks for enlightment.

~jens

_______________________________________________
Lisp Hug - the mailing list for LispWorks users
lisp-hug@lispworks.com
http://www.lispworks.com/support/lisp-hug.html

Updated at: 2020-12-10 08:34 UTC