NSURL From NSImageView Error

Hi,

I’m another newbie with moderate AppleScript experience but picked up ASOC a month or so ago.

I have written an app that works and I’m currently dropping files into it with a text Field in IB. I want replace the Text Field with an DropBox/Drop Area of some description.

All I want is the Posix Path of a file or a folder passed back to the delegate

Currently I’ve followed other posts and added an Imagewell to my IB and added a second script to the project and linked up (property parent : class “NSImageView”). The Drag and drop works. If I include a display dialog it returns the POSiX Path.

As I try to set the variable back to the delegate I get a “coercal” error.

“draggingPasteboard]: unrecognized selector sent to object”

Script for the Image well as below:

script Dropzone
property parent : class “NSImageView”
property candidatePath : “”

on draggingEntered_(sender)
    set theURL to sender's draggingPasteboard()'s readObjectsForClasses_options_({|NSURL|}, missing value)'s lastObject()
   log theURL --  <returns URL
   set candidatePath to "" & theURL's |path|()
   log candidatePath -- <returns Posix Path
   return current application's NSDragOperationCopy
end draggingEntered_

on performDragOperation_(sender)
        
    return true
    Dropzone's setItemPath2_(candidatePath) -- This is where the error occurs
end performDragOperation_

end script

I expect this is because I am calling NSImageView and not NSObject? I’ve been banging my head against the wall now for over a week, I bought Shane Stanleys Everyday Applescript yesterday but still struggling so any advice would be really appreciated.

Alternatively a simple Xcode project that contains the delegate and other elements required to perform the task?

Thanks
N

I’m not sure why you’re using an image view unless you want to see the images, but one part rings alarm bells: you’re trying to call a method on something called Dropzone inside a script called Dropzone. I can’t see that ending well. Do you mean my instead?

Hi Shane,

Thankyou so much for your reply.

You’re correct. Apologies Dropzone was a historic element of my trial and error. I have made many many different attempts to crack this.

From the image below: youl’ll see that when I drag an image into the image well (A) it displays. This is not the result I require I actually only want a box to act as an area to drag to that sends the path of file or folder to a property like item path 2 (B). I don’t actually want to display anything eg the Image.

https://www.dropbox.com/sh/co80ip4a2qrtn9g/AAAnIpEjJPFxe73v8_186fIia?dl=0

I am currently using just the Text Field (C) which I can pull the value from via the delegate script but want something more fit for purpose.

I have updated the original script as below:

It looks like the return true is where I am getting an error:
2019-08-01 10:17:58.954579+0100 weds2_3107[4281:176415] *** -[Dropzone draggingPasteboard]: unrecognized selector sent to object <Dropzone @0x600000187290: OSAID(8) ComponentInstance(0x810000)>
2019-08-01 10:17:58.954884+0100 weds2_3107[4281:176415] *** -[Dropzone draggingEntered:]: *** -[Dropzone draggingPasteboard]: unrecognized selector sent to object <Dropzone @0x600000187290: OSAID(8) ComponentInstance(0x810000)> (error -10000)

I have tried turning off the return true although as expected I get further
“2019-08-01 10:10:50.921644+0100 weds2_3107[3780:150645] *** Canceling drag because exception ‘NSInvalidArgumentException’ (reason ‘unable to set argument -1 - the AppleScript value (null) could not be coerced to type B*.’) was raised during a dragging session”

Updated script:

property |NSURL| : class “NSURL”

script Dropzone
property parent : class “NSImageView”
property itemPath : “test”
property ItemPath2 : “test2”
property candidatePath : “”

on draggingEntered_(sender)
    -- Get the URL of the dragged item
    set theURL to sender's draggingPasteboard()'s readObjectsForClasses_options_({|NSURL|}, missing value)'s lastObject()
   log theURL
   set candidatePath to "" & theURL's |path|()
   log candidatePath
   return current application's NSDragOperationCopy
end draggingEntered_

on performDragOperation_(sender)

set candidatePath to candidatePath as text
#display dialog candidatePath
return true
setItemPath2_(candidatePath)
end performDragOperation_
end script

In my exhaustive hunt for information I’ve found reference to Chapter 8: Drag and Drop in your Book “AppleScriptObjC Explored” but cannot find any location to purchase it? The link in http://www.macosxautomation.com errors.

Any further pointers or advice people can give is warmly welcomed. Also if you can suggest a better method than an Imagewell this would be great.

Many thanks
N

Create a new script class called DragAndDropView, a subclass of NSView, and add it to your project:

script DragAndDropView
	property parent : class "NSView"
	
	on draggingEntered:sender
		-- Get the URL of the dragged item
		set theURL to (sender's draggingPasteboard()'s readObjectsForClasses:{current application's |NSURL|} options:(missing value))'s lastObject()
		-- check if valid (right extension, whatever) and return accordingly
		if theURL is missing value then return current application's NSDragOperationNone
		return current application's NSDragOperationCopy
	end draggingEntered:
	
	on prepareForDragOperation:sender
		return true
	end prepareForDragOperation:
	
	on performDragOperation:sender
		set theURL to (sender's draggingPasteboard()'s readObjectsForClasses:{current application's |NSURL|} options:(missing value))'s lastObject()
		set candidatePath to theURL's |path|() as text
		display dialog candidatePath
		return true
	end performDragOperation:
	
end script

In your AppDelegate class, add this property:

    property dropView : missing value

And this handler (if it’s there already, just add the line of code):

    on applicationDidFinishLaunching:aNotification
        dropView's registerForDraggedTypes:{current application's NSPasteboardTypeURL}
    end applicationDidFinishLaunching:

Now add a box (NSBox) to your window. Select the NSView it contains and change its class to DragAndDropView (no extension). Control-click on your delegate object and drag from dropView to connect it to the view.

That’s it.

Hi Shane,

Thankyou so much for your suggestion of using the NSBox. This has helped me to understand the concept of Drag and drop better.

I have a new blank project using the NSBox which displays the path of my dragged item although I am still experiencing exactly the same issue.

I have added a new property and new setter into the script but it will not write the value as per the output of “display dialog candidatePath”? My end goal is to write the path into a property in my delegate but I can’t get the value out?

script DragAndDropView
property parent : class “NSView”
Property TestExample : “” ———<<<<<<<<<<<<<NEW LINE

on draggingEntered:sender
– Get the URL of the dragged item set theURL to (sender’s draggingPasteboard()'s readObjectsForClasses:{current application’s |NSURL|} options:(missing value))'s lastObject()
– check if valid (right extension, whatever) and return accordingly if theURL is missing value then return current application’s NSDragOperationNone
return current application’s NSDragOperationCopy
end draggingEntered:

on prepareForDragOperation:sender
return true
end prepareForDragOperation:

on performDragOperation:sender
set theURL to (sender’s draggingPasteboard()'s readObjectsForClasses:{current application’s |NSURL|} options:(missing value))'s lastObject()
set candidatePath to theURL’s |path|() as text
display dialog candidatePath
setTestExample_(candidatePath) ———<<<<<<<<<<<<<NEW LINE
return true
end performDragOperation:

end script

Any suggestions you can provide would be fantastic.

Thanks
N

A minor thing: don’t name variables and properties with an uppercase letter.

So if your app delegate has a property called testExample, you could set it like this:

current application's NSApp's delegate()'s setTextExample:candidatePath

Hi Shane,

I’m literally going on holiday in 3 minutes time… I tried your suggestion which didn’t work?

current application’s NSApp()'s delegate()'s setTextExample:candidatePath

I removed the () and now it works beautifully. What are the brackets for?

Beyond this I may not reply for 2 weeks but… THANKYOU SO MUCH.

When I return I’ll be able to input the replacement code into my project

:):):):):):):):):slight_smile:

Yeah, sorry – I was typing from memory. No parens after NSApp.

Enjoy the holiday…