Looks like no one’s replied in a while. To start the conversation again, simply ask a new question.

AppleScript Drag & Drop Help Xcode

Hi There,

Here is my issue. I have a script inside of an Xcode project that is used when a file is dropped onto the selected object. What this script does is get the path information from the file (where its located), (With single or multiple files) and uses it in the script to copy them to a temp folder for use by another script at a later time. The script works, however its SLOW. when an item is dropped it takes about 10 seconds for it to finish doing whatever it needs to do or is doing. The files being dropped are usually PDF's, or EPS's Does anyone know of a better way to maybe speed it up? Thanks for your help and time!

-Nate

--------------------------
Here Is The Script:

on drop theObject drag info dragInfo
set dataTypes to types of pasteboard of dragInfo
set doclist1 to {}
display dialog "What Is The Ad Number Of The Item To Be Spooled?" default answer "Enter Ad Number Here..." buttons {"Cancel", "Enter"} default button 2
set theadNumber to text returned of result
set contents of text field "adnumber" of window "SafeLaunch" to theadNumber
set preferred type of pasteboard of dragInfo to "file names"
set doclist1 to contents of pasteboard of dragInfo
set dropped to doclist1 is not {}
set items_dropped to doclist1 is not {}
return true
end drop

on conclude drop theObject drag info dragInfo
set mycount to (count of every item of doclist1)
tell progress indicator "progressbar" of window "SafeLaunch"
start
end tell
tell progress indicator "progressbar" of window "SafeLaunch" to increment by 10
set contents of text field "statusfield" of window "SafeLaunch" to "Adding Artwork To List..."
tell progress indicator "progressbar" of window "SafeLaunch" to increment by 30
tell progress indicator "progressbar" of window "SafeLaunch"
start
end tell
tell progress indicator "progressbar" of window "SafeLaunch" to increment by 10
set contents of text field "statusfield" of window "SafeLaunch" to "Adding Artwork To List..."
repeat with repeatVar from 1 to (mycount)
set doclist to item repeatVar of doclist1
set item_reference to (doclist as POSIX file) as alias
set doclist to doclist as POSIX file as alias
set pathTospool to "/private/var/tmp/slspooler/"
do shell script "mkdir -p " & pathTospool & theadNumber
tell progress indicator "progressbar" of window "SafeLaunch" to increment by 40
do shell script "chmod 777 " & pathTospool & theadNumber
tell progress indicator "progressbar" of window "SafeLaunch" to increment by 50
try
set tmpMacPathAd to (path to startup disk as string) & "private:var:tmp:slspooler:" & theadNumber & ":"
tell application "Finder"
duplicate file doclist to alias tmpMacPathAd without replacing
end tell
on error errorMsg number errorNum
tell progress indicator "progressbar" of window "SafeLaunch"
stop
end tell
set theSoundERROR to load sound "WARNING"
play theSoundERROR
tell progress indicator "progressbar" of window "SafeLaunch" to increment by 100
tell progress indicator "progressbar" of window "SafeLaunch" to increment by -100
set contents of text field "statusfield" of window "SafeLaunch" to "idle... (However A List Error Occured)"
delete every image of image view "drop" of window "SafeLaunch"
display dialog "Safe Launch Error #: " & errorMsg
end try
end repeat
tell progress indicator "progressbar" of window "SafeLaunch" to increment by 100
set theSound1 to load sound "adaccepted"
play theSound1
delay 1
say "Art Added" using "Bruce"
set contents of text field "statusfield" of window "SafeLaunch" to "One Art Element Waiting..."
set {visible of button "box" of window "SafeLaunch"} to {true}
if mycount is greater than 1 then
set {visible of button "box2" of window "SafeLaunch"} to {true}
set contents of text field "statusfield" of window "SafeLaunch" to "Multiple Art Elements Waiting..."
end if
set enabled of button "spoolbutton" of window "SafeLaunch" to true
tell progress indicator "progressbar" of window "SafeLaunch"
stop
end tell
tell progress indicator "progressbar" of window "SafeLaunch" to increment by -100
set contents of text field "statusfield" of window "SafeLaunch" to "idle..."
delete every image of image view "drop" of window "SafeLaunch"
end conclude drop


PowerMac G5, iBook G4, Intel MacMini, PowerMac G3 B&W, iMac DV, iBook Tangerine Mac OS X (10.4.7)

PowerMac G5, iBook G4, Intel MacMini, PowerMac G3 B&W, iMac DV Blueberry Mac OS X (10.4.6)

Posted on Jul 7, 2006 11:41 AM

Reply
Question marked as Best reply

Posted on Jul 7, 2006 6:31 PM

Hi macintosh_tech,

It takes a long time because the Finder is talking to your app, I think. What you can do is set a flag with data and conclude the drop handler. Then, when the idle handler sees the flag as true it does somehting. Here's an example in plain AppleScript. You save it as stay open application. When you drop an item on it, the idle handler does its thing.

property do_something : false
property the_something : "hello"
--
on idle
if do_something then
activate
display dialog the_something
set do_something to false
end if
return 1
end idle
--
on open these_files
set n to name of (info for (item 1 of these_files))
set the_something to n
set do_something to true
end open

gl,
11 replies
Question marked as Best reply

Jul 7, 2006 6:31 PM in response to macintosh_tech

Hi macintosh_tech,

It takes a long time because the Finder is talking to your app, I think. What you can do is set a flag with data and conclude the drop handler. Then, when the idle handler sees the flag as true it does somehting. Here's an example in plain AppleScript. You save it as stay open application. When you drop an item on it, the idle handler does its thing.

property do_something : false
property the_something : "hello"
--
on idle
if do_something then
activate
display dialog the_something
set do_something to false
end if
return 1
end idle
--
on open these_files
set n to name of (info for (item 1 of these_files))
set the_something to n
set do_something to true
end open

gl,

Jul 17, 2006 1:18 PM in response to macintosh_tech

Thanks for the response.

I had thought about putting it in the idle handler, but for the odd work flow we have it wouldn't necessarily help, im kinda saving it as a last ditch effort.

Is there a better way to get the separate paths of the files dropped and nothing else so they could be used elsewhere later in a repeat command? Im new to the drag and drop in Xcode and not sure what the most efficient way is.

Thanks again 🙂

Jul 17, 2006 2:36 PM in response to macintosh_tech

You can use plist file to store you info. plist file can be accessed with defaults, see defaults man pages for details.

But looking at your code, you have theadNumber associates with file paths.
That makes it a little bit more complicate, because defaults doesn't handle plist's complex keys structure very well.
The simple thing to do is keep plist's keys flat and use pointer method, here is an example:

spool_count = 2

theadNumber_1 = 1234
theadNumber_2 = 5678

1234_count = 4

1234_1 = "59878F4A-FF01-4748-A8D3-21EC1ECCF850"
1234_2 = "A12ACDDC-8530-4C0E-B6C9-D0BB494820D3"
1234_3 = "FCF13386-B0A0-4DA7-8E76-AD92EDFAB605"
1234_4 = "EEB0DC34-86C5-4398-AC8C-0E5BE0104F3E"

5678_count = 2

5678_1 = "25E930C8-848B-4CCB-B1A6-FE107588E440"
5678_2 = "6F9C346B-E141-4C33-B45C-0C92A76899D5"

So you see, it starts with one pointer, points to two keys, and from those: one points to four and one points to two other keys.

The other option is to play with System Events' Property List Suite, it can handle complex key structure, but not very friendly to use.

Jul 17, 2006 3:21 PM in response to kel

Hey kel,

it looks like maybe the idle may work, now the "First Responder" is the only part of the Xcode environment that allows the "on idle" (as far as I know) so if I linked the drop script and the first responder's on idle in the same script that should work in the background not tying up the application making users wait. All I need is on the sucessful drop set do_something to true and when the idle goes by looking and sees a true it will perform the operation. Right? Thanks again for your help!!! 🙂

PowerMac G5, iBook G4, Intel MacMini, PowerMac G3 B&W, iMac DV Blueberry Mac OS X (10.4.6)

Jul 17, 2006 3:26 PM in response to Jon Lopiano

If you look at the OP's codes, you see that he is doing a lot of things in on conclude drop theObject drag info dragInfo, including tell Finder to duplicate and delete files, that probably take the most time.

What he should had done is to write the info to a plist file, set an idle flag, then have the idle handler process the info in the background.

Jul 18, 2006 3:57 AM in response to Cyclosaurus

Hi Cylcl,

Isn't that what I said to do or are you talking about something I don't know about. Are you talking about running something in the background behind (or above) the idle handler? If this can be done then It sounds very good. Like you'll call something and it runs in the background. How do you do this?

gl,

Jul 18, 2006 9:36 AM in response to kel

kel,

It's the same thing, but AppleScript Studio app is little bit tricky to setup, because only Application object can run idle handler.

Also, because there may be large piece of info to process (reading back from plist) you don't want to waste time reading null data.

so the OP should:

1) link Application or File's Owner in IB to idle handler
2) declare a global or property idle_run, in the script contains idle handler.
3) in on drop theObject drag info dragInfo handler, must do:

a. update the plist to change spool_count, threadNumber index, etc...
b. set idle_run to true

4) in idle handler

on idle
if idle_run then
-- process the data
end if
end idle

that is basically it, however, there is potential problem:
what if the user drop new file path while idle is processing the data?

Jul 31, 2006 5:19 PM in response to macintosh_tech

Well guys i figured it out....here is what fixes the script and makes it lightning fast...

OLD
on drop theObject drag info dragInfo
set dataTypes to types of pasteboard of dragInfo
set doclist1 to {}
display dialog "What Is The Ad Number Of The Item To Be Spooled?" default answer "Enter Ad Number Here..." buttons {"Cancel", "Enter"} default button 2
set theadNumber to text returned of result
set contents of text field "adnumber" of window "SafeLaunch" to theadNumber
set preferred type of pasteboard of dragInfo to "file names"
set doclist1 to contents of pasteboard of dragInfo
set dropped to doclist1 is not {}
set items_dropped to doclist1 is not {}
return true
end drop

NEW
on drop theObject drag info dragInfo
delay .01
set dataTypes to types of pasteboard of dragInfo
delay .01
set doclist1 to {}
delay .01
display dialog "What Is The Ad Number Of The Item To Be Spooled?" default answer "Enter Ad Number Here..." buttons {"Cancel", "Enter"} default button 2
set theadNumber to text returned of result
set contents of text field "adnumber" of window "SafeLaunch" to theadNumber
set preferred type of pasteboard of dragInfo to "file names"
delay .01
set doclist1 to contents of pasteboard of dragInfo
delay .01
set dropped to doclist1 is not {}
delay .01
set items_dropped to doclist1 is not {}
delay .01
return true
end drop

It seems adding thoes delays makes it run insantanious and without takes up to 30 second.

This was a last ditch effort after the idle command had the same problem....so make a note people! Thanks again everyone for your assistance 🙂

Jul 31, 2006 7:16 PM in response to Cyclosaurus

Well, the wierd part was when I decided to put in "beep 1" in between all the lines to see where it was getting hung up and when I went "Build & Go" it ran at the speed of light, switched out a few with delays and worked like a charm....my theory is it frees up the finder and or the app somehow by making it do something else....but who knows...it is wierd though. :\

AppleScript Drag & Drop Help Xcode

Welcome to Apple Support Community
A forum where Apple customers help each other with their products. Get started with your Apple ID.