Re: Scriptable ASOC app and records, Part 2
Re: Scriptable ASOC app and records, Part 2
- Subject: Re: Scriptable ASOC app and records, Part 2
- From: Takaaki Naganoya <email@hidden>
- Date: Sun, 01 Feb 2015 15:53:15 +0900
Thank you Ron!
I confirmed your samples and studied how it works.
I spent very meaningful weekend.
--
Takaaki Naganoya
email@hidden
http://piyocast.com/as/
> 2015/02/01 13:21、Ron Reuter <email@hidden> のメール:
>
> 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
_______________________________________________
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