Tuesday, December 12, 2017

#1 2017-09-25 07:14:36 am

robdut
Member
Registered: 2009-09-02
Posts: 301

High Sierra NSDictionary woes

Hi All,

This line worked before:

Applescript:

set nsDict to current application's NSDictionary's dictionaryWithObjectsAndKeys_("value1", "key1", theValue, "key2", "value3", "key3", missing value)

But not in High Sierra so tried:

Applescript:

set nsDict to current application's class "NSDictionary"'s dictionaryWithObjectsAndKeys:{"value1", "key1", theValue, "key2", "value3", "key3", missing value}

both throw error:

+[NSDictionary dictionaryWithObjectsAndKeys:]: second object of each pair must be non-nil.  Or, did you forget to nil-terminate your parameter list? (error -10000)

I had to rewire all my NSArrays to use the new parameter method

Applescript:

set argArray to current application's class "NSArray"'s arrayWithArray:{helperPath, "5F67Hj", encstr, missing value}

which works but not sure how to redo NSDictionary here. It goes to notification center below.

Applescript:

on sendNotification_dat_tx_nt_d_dct_(aTitle, aSubtitle, aMessage, aActionButtonTitle, aOtherButtonTitle, aDict)
   my logInfo_var_lvl_("Begin Notification send","",1)
   set myNotification to current application's NSUserNotification's alloc()'s init()
   set myNotification's title to aTitle
   set myNotification's subtitle to aSubtitle
   set myNotification's informativeText to (aMessage) as text
   set myNotification's actionButtonTitle to aActionButtonTitle
   set myNotification's otherButtonTitle to aOtherButtonTitle
   set myNotification's soundName to "Boing"
   set myNotification's userInfo to aDict

   current application's NSUserNotificationCenter's defaultUserNotificationCenter's scheduleNotification_(myNotification)
end sendNotification_

Thx, Rob

Last edited by robdut (2017-09-25 07:18:39 am)

Offline

 

#2 2017-09-25 09:11:46 am

Shane Stanley
Member
From:: Australia
Registered: 2002-12-07
Posts: 5199

Re: High Sierra NSDictionary woes

What you're looking for is this:

Applescript:

set nsDict to current application's NSDictionary's dictionaryWithObjects:{"value1", theValue, "value3"} forKeys:{"key1", "key2", "key3"}

I'm not sure why you'd use the trailing-nil versions from ASObjC.

But then I'm even more bamboozled as to why you're not using interleaved syntax sad  It's been around since 10.9...


Shane Stanley <sstanley@myriad-com.com.au>
www.macosxautomation.com/applescript/apps/

Offline

 

#3 2017-09-25 10:12:52 am

robdut
Member
Registered: 2009-09-02
Posts: 301

Re: High Sierra NSDictionary woes

Thanks Shane,

Of course! Though dictionaryWithObjectsAndKeys is certainly valid in ObjC and did work before. With interleaving you don't need the nil terminator? I am always a few years behind...

I just never got around to rewriting (interleaving...) some of my old apps, which have worked fine till now. And now that I am using an external editor the interleaving gets translated though not in all cases as with the above line.

Cheers, Rob

Last edited by robdut (2017-09-25 10:13:43 am)

Offline

 

#4 2017-09-25 07:11:05 pm

Shane Stanley
Member
From:: Australia
Registered: 2002-12-07
Posts: 5199

Re: High Sierra NSDictionary woes

robdut wrote:

Though dictionaryWithObjectsAndKeys is certainly valid in ObjC and did work before.



Yes, and you should definitely log a bug on the issue, not least because these things often crop up elsewhere too.

I guess my surprise is because it's something you rarely see in Objective-C code any more -- it's a relic of a time when where there was no alternative.


Shane Stanley <sstanley@myriad-com.com.au>
www.macosxautomation.com/applescript/apps/

Offline

 

#5 2017-09-26 06:20:31 am

DJ Bazzie Wazzie
Member
From:: the Netherlands
Registered: 2004-10-20
Posts: 2727
Website

Re: High Sierra NSDictionary woes

robdut wrote:

With interleaving you don't need the nil terminator?



You still need it. It's an standard va_list and only a few functions will be handled special by the compiler (stringWithFormat, NSLog, Printf for example).

The difference with High Sierra is your syntax. While with the old syntax you send an va_list with the new syntax you send an array (note the curly braces). I'm not even sure if you can use an va_list with the new ASObjC syntax at all so you should stick with the old syntax.

Offline

 

#6 2017-09-26 07:49:24 am

Shane Stanley
Member
From:: Australia
Registered: 2002-12-07
Posts: 5199

Re: High Sierra NSDictionary woes

DJ Bazzie Wazzie wrote:

I'm not even sure if you can use an va_list with the new ASObjC syntax at all so you should stick with the old syntax.



You're correct, but it in this case I think the syntax is a red herring (I was referring more to the syntax used in the longer snippet of script Rob posted).

My guess is that the scripting bridge relies on the relevant framework .bridgesupport file to be able to handle any methods using a va_list.

If you look at Foundation.bridgesupport in 10.12, you see this:

<method class_method='true' selector='dictionaryWithObjectsAndKeys:' sentinel='0' variadic='true'/>

In the equivalent in 10.13, the entry has disappeared. My guess is that the scripting bridge relies on those variadic and sentinel attributes.

There are other issues in the new .bridgesupport files, too. AppleScriptObjC doesn't cope with the new entry for NSRect, and the value for the NSNotFound enum is incorrect.

If anyone finds any others, please log bugs ASAP.


Shane Stanley <sstanley@myriad-com.com.au>
www.macosxautomation.com/applescript/apps/

Offline

 

#7 2017-09-26 08:23:53 am

Shane Stanley
Member
From:: Australia
Registered: 2002-12-07
Posts: 5199

Re: High Sierra NSDictionary woes

So man BridgeSupport says:

Optional attributes:

     variadic  Indicates whether the C function accepts a variable number of
               arguments. The default value is ``false''.

     sentinel  An integer value that specifies which argument (counting back-
               wards from the end of the argument list) must be a NULL value to
               indicate the end of a variable length argument list (thus, this
               is only legal for variadic functions).



A quick look through Foundation.bridgesupport in 10.13 shows all methods that previously required the sentinel attribute have been removed. Perhaps it was deliberate after all.


Shane Stanley <sstanley@myriad-com.com.au>
www.macosxautomation.com/applescript/apps/

Offline

 

#8 2017-09-26 10:36:32 am

robdut
Member
Registered: 2009-09-02
Posts: 301

Re: High Sierra NSDictionary woes

Interesting...

Yes my notification handler (with the old syntax ) was from an old utilities script that I hadn't edited externally like the others. Sorry to bamboozle you Shane!

I also see that AppleScript |size| is still not understood in the Hi Sierra. Of course I didn't report it either.

Cheers, Rob

Offline

 

#9 2017-09-26 08:08:25 pm

Shane Stanley
Member
From:: Australia
Registered: 2002-12-07
Posts: 5199

Re: High Sierra NSDictionary woes

robdut wrote:

I also see that AppleScript |size| is still not understood in the Hi Sierra.



I presume you mean when used with NSRects, because they're being returned as a list ({x, y}, {w, h}}) instead of a record.


Shane Stanley <sstanley@myriad-com.com.au>
www.macosxautomation.com/applescript/apps/

Offline

 

#10 2017-09-27 09:14:29 am

DJ Bazzie Wazzie
Member
From:: the Netherlands
Registered: 2004-10-20
Posts: 2727
Website

Re: High Sierra NSDictionary woes

Shane Stanley wrote:

My guess is that the scripting bridge relies on those variadic and sentinel attributes.



You're correct. Every ObjC method is actually an C-function (C symbols). These symbols are stored in an hash table and when you call an method the symbol is looked up and the right function is called. If the function doesn't exists you get a nice "Unrecognized selector send to instance" error instead of an BAD_EXEC crash like in C or C++. This is what the ObjC runtime does for you with the cost of a little performance. But I think I don't tell you anything new here.

When it comes to va_list it's a different story. va_list is an C macro, that is a set of predefined pre-processor code that will be replaced (similar too the old NSReleasePool) by real code before the code is compiled. Because variable arguments does't really exists the va_list macro is replaced with an struct that can hold the variable arguments. Therefore methods with variadic arguments are defined in the bridge like C functions so the bridge can handle it.

The sentinel is to indicate which argument is the va_list struct argument starting from back. 0 value is the default meaning the last argument. So when the last argument is an va_list struct then sentinel attribute doesn't have to be defined.

Shane Stanley wrote:

A quick look through Foundation.bridgesupport in 10.13 shows all methods that previously required the sentinel attribute have been removed. Perhaps it was deliberate after all.



I think it more an error than deliberate. Maybe there is an bug in the tool that creates the bridge support files because it is so consistent. It doesn't only affect AppleScriptObjC but also PyObjC and the latter supports variadic arguments.

Last edited by DJ Bazzie Wazzie (2017-09-27 09:16:40 am)

Offline

 

#11 2017-09-27 10:52:10 pm

Shane Stanley
Member
From:: Australia
Registered: 2002-12-07
Posts: 5199

Re: High Sierra NSDictionary woes

DJ Bazzie Wazzie wrote:

I think it more an error than deliberate. Maybe there is an bug in the tool that creates the bridge support files because it is so consistent. It doesn't only affect AppleScriptObjC but also PyObjC and the latter supports variadic arguments.



Could be -- however the variadic methods that don't require a trailing nil are still there.


Shane Stanley <sstanley@myriad-com.com.au>
www.macosxautomation.com/applescript/apps/

Offline

 

#12 2017-09-30 07:37:01 am

robdut
Member
Registered: 2009-09-02
Posts: 301

Re: High Sierra NSDictionary woes

Shane Stanley wrote:
robdut wrote:

I also see that AppleScript |size| is still not understood in the Hi Sierra.



I presume you mean when used with NSRects, because they're being returned as a list ({x, y}, {w, h}}) instead of a record.



Ah yes. I saw your post on Hi Sierra bugs yesterday and looked again at console:

{{177.0, 463.0}, {583.0, 382.0}} doesn’t understand the “size” message.

Didn't connect at first that it wasn't showing the expected record. Duh.



On another note I am seeing many console messages:

AppleEvents: received mach msg which wasn't complex type as expected in getMemoryReference.

and it seems to not like "tell application Finder".

Applescript:

Log "pre finder tell"
tell application "Finder"
set diskName to name of startup disk & " (Boot Volume)" as string
Log "post finder tell"

2017-09-30 08:23:37.272120-0400 backupList+[2664:143798] pre finder tell
2017-09-30 08:23:37.294663-0400 backupList+[2664:143798] AppleEvents: received mach msg which wasn't complex type as expected in getMemoryReference.
2017-09-30 08:23:37.297013-0400 backupList+[2664:143798] post finder tell

Offline

 

#13 2017-09-30 08:03:20 am

Shane Stanley
Member
From:: Australia
Registered: 2002-12-07
Posts: 5199

Re: High Sierra NSDictionary woes

robdut wrote:

On another note I am seeing many console messages:
AppleEvents: received mach msg which wasn't complex type as expected in getMemoryReference.



Please make up a simple project that produces it, and log a bug with Apple ASAP.


Shane Stanley <sstanley@myriad-com.com.au>
www.macosxautomation.com/applescript/apps/

Offline

 

#14 2017-11-14 10:24:26 am

jcwelch
Member
Registered: 2009-09-11
Posts: 3

Re: High Sierra NSDictionary woes

I hit the same bug, sent it off to apple with a sample. Is there a cocoa framework that lets you get information about a volume, i.e. format, volume name?

Offline

 

#15 2017-11-14 05:49:02 pm

Shane Stanley
Member
From:: Australia
Registered: 2002-12-07
Posts: 5199

Re: High Sierra NSDictionary woes

jcwelch wrote:

Is there a cocoa framework that lets you get information about a volume, i.e. format, volume name?



You can use NSURL:

Applescript:

use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
use scripting additions

set theFolder to POSIX path of (path to desktop)

set theURL to current application's |NSURL|'s fileURLWithPath:theFolder
set {theResult, theValue, theError} to theURL's getResourceValue:(reference) forKey:(current application's NSURLVolumeNameKey) |error|:(reference)

set {theResult, theValue, theError} to theURL's getResourceValue:(reference) forKey:(current application's NSURLVolumeLocalizedFormatDescriptionKey) |error|:(reference)

NSWorkspace also has -getFileSystemInfoForPath:isRemovable:isWritable:isUnmountable:description:type:.


Shane Stanley <sstanley@myriad-com.com.au>
www.macosxautomation.com/applescript/apps/

Offline

 

Board footer

Powered by FluxBB

RSS (new topics) RSS (active topics)