• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Scriptable ASOC app and records, Part 2
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Scriptable ASOC app and records, Part 2


  • Subject: Scriptable ASOC app and records, Part 2
  • From: Ron Reuter <email@hidden>
  • Date: Sat, 31 Jan 2015 22:21:41 -0600

In part 2, a scriptable ASOC application implements a command that returns a record NOT specified in the SDEF, also known as a user-field record.
This is somewhat trickier than an SDEF-defined record, but it is also more flexible.

In the SDEF file:

<suite name="Test Suite" code="TEST">
<command name="retrieve usrf info" code="TESTusrf">
<cocoa class="UserFieldCommand"/>
<result type="any"/>
</command>
</suite>

Then in the implementation file:

script UserFieldCommand
property parent : class "NSScriptCommand"


property aedClass  : class "NSAppleEventDescriptor"
property nssClass  : class "NSString"
property nsnClass  : class "NSNumber"


on performDefaultImplementation()


-- For demo purposes, the data is just hard-coded here


set theAuthor to "Mark Twain"
set birthYear  to 1835
set isFavorite to true


-- return an NSDictionary whose keys are NOT defined in an sdef record-type (aka, user fields)
-- in this example, Spanish words are used just for fun

set aDict to current application's NSDictionary's ¬
dictionaryWithDictionary:{autor:theAuthor, nacio:birthYear, favorito:isFavorite}


return makeUserRecordDescriptor(aDict)
end

# ASOC implementation of - (NSAppleEventDescriptor *)scriptingRecordDescriptor for an NSDictionary
# Creates an empty record descriptor and an empty list descriptor, then
# Iterates over the dictionary and inserts descriptors for each key and each value into the list descriptor
# Finally, populates the record descriptor with the type 'usrf' and the list descriptor

on makeUserRecordDescriptor(aDict)

log aDict

set recordDescriptor to aedClass's recordDescriptor()
set listDescriptor   to aedClass's listDescriptor()


set typeUserField to 1970500198 -- 'usrf'


set itemIndex to 1 -- AS records are 1-based


repeat with aKey in aDict's allKeys()


set aVal to aDict's valueForKey_(aKey)


-- The values can be several different types. This code DOES NOT handle them all.


set isStringValue  to aVal's isKindOfClass_(nssClass's |class|) = 1
set isNumericValue to aVal's isKindOfClass_(nsnClass's |class|) = 1
set isBooleanValue to aVal's className()'s containsString_("Boolean") = 1

-- Insert a descriptor for the key into the list descriptor


set anItem to aedClass's descriptorWithString_(aKey)
listDescriptor's insertDescriptor_atIndex_(anItem, itemIndex)
set itemIndex to itemIndex + 1

-- Insert a descriptor (of the correct type for the value) into the list descriptor


if isStringValue
set anItem to aedClass's descriptorWithString_(aVal)
else if isBooleanValue
set anItem to aedClass's descriptorWithBoolean_(aVal's boolValue())
else if isNumericValue
set intValue to aVal's intValue()
set fpValue to aVal's doubleValue()


if intValue = fpValue
set anItem to  aedClass's descriptorWithInt32_(aVal's intValue())
else
set anItem to  aedClass's descriptorWithString_(aVal's stringValue) # TODO: 'doub'
end
else
set anItem to  aedClass's descriptorWithString_("Unhandled Data Type")
end


listDescriptor's insertDescriptor_atIndex_(anItem, itemIndex)
set itemIndex to itemIndex + 1

end


recordDescriptor's setDescriptor_forKeyword_(listDescriptor, typeUserField)


return recordDescriptor
end
end


And finally the test script:

tell application "TestRecordReturn"
retrieve usrf info --> {autor:"Mark Twain", nacio:1835, favorito:true}
end tell

Notes: 
The command handler is very similar to the SDEF-based command; an NSDictionary is again used to create the data for the record.
However, since the ASOC engine has no SDEF info to go on, we have to implement our own method to convert the NSDictionary into
the correct NSAppleEventDescriptor to represent the record. This is what -scriptingRecordDescriptor would do in a Objective-C implementation. 

The returned descriptior must be a record with a single key/value pair. 
The key is 'usrf', in the form of an integer.
The value is a list descriptor containing a key descriptor followed by its value descriptor, which together encode the key/value of each dictionary pair.
While the dictionary keys are always strings here, the associated values can be almost anything. The sample implements string, boolean, and integer types.
Other value types are more difficult, and perhaps impossible in a script-only based implementation.
For instance, to fix the implementation of a double value above, you could add an Objective-C class with this method:

+ (NSAppleEventDescriptor *)descriptorWithDouble:(double)aDouble
{
double val = aDouble;


return [NSAppleEventDescriptor descriptorWithDescriptorType:'doub' bytes:&val length:sizeof(val)];
}

How much work you have to do is based on how complex your returned record is. Keep it simple if you can!

— Ron



 _______________________________________________
Do not post admin requests to the list. They will be ignored.
applescriptobjc-dev mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:

This email sent to email@hidden

  • Follow-Ups:
    • Re: Scriptable ASOC app and records, Part 2
      • From: Takaaki Naganoya <email@hidden>
  • Prev by Date: Scriptable ASOC app and records, Part 1
  • Next by Date: Re: Scriptable ASOC app and records, Part 2
  • Previous by thread: Re: Files with full stop preceding not readable.
  • Next by thread: Re: Scriptable ASOC app and records, Part 2
  • Index(es):
    • Date
    • Thread