Migration from "JSON Helper" to AppleScriptObjC :: Issues with JSON object

Please, could I ask you for some advice?

I am trying to substitute JSON Helper with AppleScriptObjC and the function JSONObjectWithData from the class NSJSONSerialization in order to create an JSON object.

tell application "JSON Helper"
	set properJSON to make JSON from {User:"Braeburn", AuthType:"plain", AuthData:"MyPassword", RequestType:"get_databases", RequestParams:{database_login:"DB_Name"}}
end tell

gives me the following (proper) JSON object (the excerpt below shows the content from source tab in SD):

"{
  \"RequestType\": \"get_databases\",
  \"RequestParams\": {
    \"database_login\": \"DB_Name\"
  },
  \"AuthType\": \"plain\",
  \"User\": \"Braeburn\",
  \"AuthData\": \"MyPassword\"
}"

This JSON object is used for an SOAP-Request (XML body with the above shown JSON object embedded) which works perfect.

I tried to generate the same object following Marc Alldritts how-to ([Subject as Hyperlinks are note allowed] Writing JSON data with NSJSONSerialization):

property NSJSONWritingPrettyPrinted : a reference to 1
property NSJSONSerialization : a reference to current application's NSJSONSerialization

set JSON_example1 to ¬
	{|User|:"Braeburn",¬
	 |AuthType|:"plain",¬
	 |AuthData|:"MyPassword",¬
	 |RequestType|:"get_databases",¬
	 |RequestParams|:{database_login:"DB_Name"}}


set JSON_example2¬
	{User:"Braeburn",¬
	 AuthType:"plain",¬
	 AuthData:"MyPassword",¬
	 RequestType:"get_databases",¬
	 RequestParams:{database_login:"DB_Name"}}

The source tab in SD shows the following for the variables JSON_example1 and/or JSON_example2:

{User:"Braeburn", AuthType:"plain", AuthData:"MyPassword", RequestType:"get_databases", RequestParams:{database_login:"DB_Name"}}

set X to NSJSONSerialization's dataWithJSONObject:JSON_example1 options:0 |error|:(missing value)
log (class X) ---> (*<BAGenericObjectNoDeleteOSAID @0x60000203d4e0: OSAID(4) ComponentInstance(0x8400a2)>*)

set Y to NSJSONSerialization's dataWithJSONObject:JSON_example1 options:1 |error|:(missing value)
log (class Y) ---> (*<BAGenericObjectNoDeleteOSAID @0x60000203d4e0: OSAID(4) ComponentInstance(0x8400a2)>*)

set Z to NSJSONSerialization's dataWithJSONObject:JSON_example2 options:NSJSONWritingPrettyPrinted |error|:(missing value)
log (class Z) ---> (*<BAGenericObjectNoDeleteOSAID @0x60000203d4e0: OSAID(4) ComponentInstance(0x8400a2)>*)

The Desc tab (there is no Source tab) in SD shows the following for the variables X, Y and Z:

(NSData) <7b225265 71756573 74547970 65223a22 6765745f 64617461 62617365 73222c22 52657175 65737450 6172616d 73223a7b 22646174 61626173 655f6c6f 67696e22 3a224442 5f4e616d 65227d2c 22417574 68547970 65223a22 706c6169 6e222c22 55736572 223a2242 72616562 75726e22 2c224175 74684461 7461223a 224d7950><<truncated at 128 bytes out of 137>>

Writing the JSON object to a file with the following code…

set theJSONData to (current application's NSJSONSerialization's dataWithJSONObject:Kas_JSON_Request options:1 |error|:(missing value))
log (class theJSONData)
theJSONData's writeToFile:("/Volumes/RAMDisk/Data.json") atomically:false

…produces a properly formatted JSON structure.

I admit the raw JSON object created by JSON Helper with all the backslashes looks strange, but it works when invoking the SOAP-Request:

	tell application "https://example.com/soap/Api.php"
		set XMLfile to call soap {method name:"Api", SOAPAction:"urn:xmethodsApi#Api", parameters:{parms:properJSON}}
	end tell

Your help is much appreciated.

B.

NSJSONSerialization is returning data, and your code wants an AppleScript string. So you need to convert it, something like this:

set theData to NSJSONSerialization's dataWithJSONObject:JSON_example2 options:NSJSONWritingPrettyPrinted |error|:(missing value)
set jsonText to (current application's NSString's alloc()'s initWithData:theData encoding:(current application's NSUTF8StringEncoding)) as text
1 Like

Dear Shane,

responding in no time with just two lines of code which did the trick. You really rock! :smiley: :pray:

Do you mind to to give a more in depth explanation what is the following code doing?

set jsonText to (current application's NSString's alloc()'s initWithData:theData encoding:(current application's NSUTF8StringEncoding)) as text

Especially alloc()'s goes far beyond my modest understanding of AppleScriptObjC. Furthermore, is encoding an option and (current application's NSUTF8StringEncoding) a kind of nested argument?

Thank you one more time for your kind advice.

It’s taking the raw data and turning it into a string that AppleScript understands.

he best answer is that you really need to seek out a primer to ASObjC – your questions can’t really be answered properly in a simple answer. But alloc() is used to allocate memory for an object before it’s initialized, and isn’t always required, while encoding: is a labelled argument.

Thank you one more time.

Although it would be quite impossible for me to write any code without the fundamentals described in your book Everyday AppleScriptObjC, it’s still difficult to grasp the idiosyncrasy of ASObjC. Everytime I think I got it, a different result/behaviour comes out.

So, keep writing books. Your knowledge is indispensable. :wink:

If you check Apple’s documentation you could see + and - before a method.
If its + before a method… its type method you could do NSString’s stringWithString:“hello”
if its - before a method its instance method you do NSString’s alloc()'s initWithString:“hello”
If its a type method you do not use alloc(), but instance method you need it and many times
it start with initWithXXXX

When you have pointer to a class in the memory you could call methods and properties.

1 Like