xCode 4, AppleScript: hide & show windows, remote script execution

Problem:
From within AppleScript I need to ask for 5 Parameters.

  • solution a): 5 display dialog … Not really nice
  • solution b): create a nice looking dialog in xCode 4

I have a project up and running as an App. I have a nice UI. It all works from within the App via AppleScript. But I need to call it remotely and pass some info from / to this app. I did some search on Google but still could not figure it out…

Further more: If I get it working, how can I display 2 different dialogs, depending on the parameters provided by the calling script ?

Thanks for any info,
DC

I’m sure there would be no difficulty in displaying 2 different dialogs based on the passed parameters.

You say you need to call it remotely --what do you mean by remotely? Please elaborate.

Ric

Thanks for the quick reply !

Opening/closing windows:
It might be easy, but I am from old days of scripting and the cocoa framework is new to me. I did not find a straight forward tutorial that covers xCode 4, AppleScript AND windows…

Remote calling:
Source:
an AppleScript generated script which resides outside of the app bundle, but on the same computer
(getting invoked via AppleScript Menu from within an other application)

Destination:
an AppleScript based App compiled in xCode 4

It works when both scripts are from AppleScript Editor, but once xCode is involved it breaks
(because the AppleScript handlers are no longer available)

So, if I’m understanding this correctly, you want to run an ASOC (ApplescriptObjectiveC) based program by starting it from an applescript in another app. You want this ASOC app to collect input for 5 things from the user with some kind of nice interface and then send that info back to the calling app? And, what is it that you need to pass from the calling app to the ASOC app?

Ric

Correct !!

Input depends on possible workflows and limitations. Ideal scenario:

  • list of tagged items as input
  • list of tagged items as output

(list like “myToys : {car=“Toyota”,bike=“Kawasaki”,sneakers=“Adidas”}” )

One part of the problem is synchronization. If the sender waits for completion of the receiver’s script most of the work is on the sender’s side and things are easy. If execution on sender side does not wait things get more complicated and a longer list has to be passed to the receiver.

Of course things could be done by writing some files somewhere and using semaphores, but since it is quite a generic question I hope there is an easy generic answer - and file IO for this kind of things can break.

Unfortunately, I think this is a fairly hard thing to do. I could be wrong about this, but I think you would have to make the ASOC app scriptable, and that’s not so easy to do (but doable). Is the sending app a third party app or something you wrote? Could the whole thing be re-written in ASOC?

Ric

Both are mine, and unfortunately the AppleScript Menu only accepts AppleScript Editor files.
ASOC files are .app and are ignored - no option.

Any ideas on how to get stuff from ASOC to regular AppleScript ?
How do I handle multiple windows in ASOC ?

The launching of an ASOC-app via the scriptmenu is the easy part. You can make a small script with the sole function of launching the ASOC-app. If you save the slave-script as a script bundle, you can even ‘hide’ the ASOC-app in it’s resource bundle, so both stay together allways and the path to launch the app from is easy to calculate.

regards,
Cliff

Great trick ! Might help a bit, but then I still need to get the parameters from the launcher to the ASOC-app.

So, if the calling app is something that you wrote, why not re-write it in ASOC, then you don’t need to be calling any outside app.

I’m not sure what you mean here – do you mean translate an ASOC app to an applescript one, or how to pass data from ASOC to an applescript?

There are several ways to do this. You can create multiple windows in Interface Builder, and then open and close them with various commands. It isn’t clear to me why you would need multiple windows anyway. It sounds like you just need one window with multiple text fields or a table where you can enter data.

Ric

Because the original caller expects AS, not ASOC. There always hast to be some data moved from regular AS to ASOC.

Move info/data

I need more than one window. I have 2 window definitions in my project, same name but different IDs. If it is so easy please tell me how to do it. Thats why I asked.

But why does the AS script have to pass data to the ASObjC app? Why can’t the AS code that assembles the data be put in the ASObjC app?

We have 3 instances involved:
1): a regular Mac OS X application from 3rd party which only supports regular AS (via a menu)
2): a regular AS which receives data from 1) but has no UI
3): an ASOC with a beautiful UI but needs to receive data from and/or deliver data to 2)

I can modify 2) and 3) but 1) is beyond control.

    1. is unable to communicate with 3)
    1. has no UI due to language restrictions
  • Data source is always 1)
  • communication between 2) and 3) depends on communication complexity. If communication is complicated, processing workload is in 2). If communication is easy processing workload can move between 2) and 3) wherever it is more convenient and faster.

I’m not sure what you mean by different id’s here, but if you have 2 windows you need 2 properties that are IBOutlets to them, say win1 and win2 for example. To make win1 appear you just call “win1’s makeKeyAndOrderFront_(me)” (this also makes the window key as might guess from the name – there are also orderFront() and orderFrontRegardless() methods which are all documented in the NSWindow class description). “Me” here refers to the script, but it’s not really important what you put there. To remove a window from the screen you can call “win1’s orderOut()” or “win1’s close()”. If you don’t want a window to show up automatically when you open the app you need to uncheck the box in the inspector in IB that says “Visible At Launch”.

When you answered my question before with “both are mine”, I thought that meant that everything we were talking about here was something you wrote, but I see now that’s not true, which brings me back to my original statement that I think you would have to make your ASOC app scriptable to make this work.

Ric

Is there some technical reason why you can’t move the data gathering of 1 and whatever 2 does into the ASObjC app, so that all 1 does is trigger the ASObjC app?

There is no other way implemented by the developer of 1)

So the application can only be scripted from its script menu?

The developer of 1) intended this as the main interface.

There is an other way (which I did not try) which has a strong risk to break on slower systems due to the time it takes to launch ASOC thru AS.

So what I have learned:

  • communication between AS and ASOC is very limited without providing the code yourself
  • ASOC, while based on AS, behaves like a regular Mac app, not like an AS

I don’t want to go thru teaching ASOC an external AS api. Now I will try to solve this by writing the parameters into a temp file.

Thanks for the input anyway…

That was the key ! Googled it with AppleScript and found a nice tutorial in the last chapter of:

Learn AppleScript
The Comprehensive Guide to Scripting and Automation on Mac OS X
Hamish Sanderson | Hanaan Rosenthal
THIRD EDITION

Currently available for free at
http://www.docstoc.com/docs/75276246/Learn-AppleScript-The-Comprehensive-Guide-to-Scripting-and-Automation-on-Mac-OS-X-3rd-Edition

Thanks for the tip, Ric !

Well, if you want to try the scripting route, I think I’ve got that figured out with a little help from previous posts and Shane. I have an app that has 4 text fields that I can set and get from the AS, and I can choose one of two windows to open with a flag set from the AS.

Ric