XMLRPC Request in ASObjC

I need some help if someone could be so kind.

I’m trying to do XMLRPC request using ASObjC, but I have always problem with completionHandler and most of the time I never use it. The code is based on the same
example I have in code-exchange. To get a copy of xmlrpc server python script its in code-exchange.

I have never used this method before…

Reference:XMLRPC Reference

Thanks

use framework "Foundation"
use scripting additions

set post to current application's NSString's stringWithFormat:"metodName=add&params={2,3}"
set postData to post's dataUsingEncoding:(current application's NSASCIIStringEncoding) allowLossyConversion:true
set postLength to current application's NSString's stringWithFormat_("%d", postData's |length|())
set theURL to current application's |NSURL|'s URLWithString:"http://localhost:8000/RPC2"
set request to current application's NSMutableURLRequest's alloc()'s init()
request's setURL:theURL
request's setHTTPMethod:"POST"
request's setValue:postLength forHTTPHeaderField:"Content-Length"
request's setHTTPBody:postData

set theConfiguration to current application's NSURLSessionConfiguration's defaultSessionConfiguration()
set session to current application's NSURLSession's sessionWithConfiguration:theConfiguration
session's dataTaskWithRequest:request completionHandler:(missing value)
-- set requestReply to current application's NSString's alloc()'s initWithData:object() encoding:(current application's NSASCIIStringEncoding)

The completionHandler argument takes a block, which ASObjC doesn’t support – it’s essentially asking for a block of Objective-C code to run when the action is completed. NSURLSession fortunately offers versions of these methods without the need for blocks, so just use them.

Thanks, Shane

I could see a message on the server but it say: code 501, message Unsupported method (‘GET’)
And that is wrong. The correct message should be: “POST /RPC2 HTTP/1.1” 200 -
So postData should be wrong, to be honest I did a guess from xmlrpc specification.
XMLRPC include both XML and HTTP data.

Maybe I could save everything to a string to see what it send.

Some examples I have seen use dataTask’s resume()

use framework "Foundation"
use scripting additions

set post to current application's NSString's stringWithFormat:"metodname=add&param=2&param=3}"
set postData to post's dataUsingEncoding:(current application's NSASCIIStringEncoding) allowLossyConversion:true
set postLength to current application's NSString's stringWithFormat_("%d", postData's |length|())
set theURL to current application's |NSURL|'s URLWithString:"http://localhost:8000/RPC2"
set request to current application's NSMutableURLRequest's alloc()'s initWithURL:theURL
request's setHTTPMethod:"POST"
request's setValue:postLength forHTTPHeaderField:"Content-Length"
request's setHTTPBody:postData

set theConfiguration to current application's NSURLSessionConfiguration's defaultSessionConfiguration()
set session to current application's NSURLSession's sessionWithConfiguration:theConfiguration
set dataTask to session's dataTaskWithURL:theURL
if (dataTask's state()) is 1 then
	log "Session Task State Suspended"
end if

Since can’t use block need to use the delegate methods of the NSURLSession.
Also need to use the request not the URL when setting up the task

set session to current application's NSURLSession's sessionWithConfiguration:theConfiguration delegate:(me) delegateQueue:(missing value)

set dataTask to session's dataTaskWithRequest:request

dataTask's resume() --Start URL Session

and then include in your script the required delegate method:

on URLSession:tmpSession dataTask:tmpTask didReceiveData:tmpData

set aStat to (tmpTask's state()) as list of string or string

set aRes to tmpTask's response()

set (my retCode) to aRes's statusCode()

set (my retHeaders) to aRes's allHeaderFields()

set resStr to NSString's alloc()'s initWithData:tmpData encoding:(NSUTF8StringEncoding)

set jsonString to NSString's stringWithString:(resStr)

set jsonData to jsonString's dataUsingEncoding:(NSUTF8StringEncoding)

set aJsonDict to NSJSONSerialization's JSONObjectWithData:jsonData options:**0** |error|:(*missing value*)

set retData to aJsonDict as list of string or string

end URLSession:dataTask:didReceiveData:

Thanks, @technomorph

After include this I got the right respond on the server “POST /RPC2 HTTP/1.1” 200 -
Your handler confuse me… in other words I did.

dataTask’s status() → 0 → NSURLSessionTaskStateRunning
The response return missing value so statusCode() do not work.
Its same for allHeaderFields()

So there is something wrong with the respond.

From:XMLRPC specification
It say a User-Adgent and Host need to be included so maybe the default configuration is
the wrong approach. When Apple’s documentation a user could make that configuration in
the session NSURLSessionConfiguration

I’m checking this code to see if I get any clue how it works.
XMLRPC framework

Did you notice the misspelling of “methodname”

I’m not sure if the stringWithFormat is correct. I have try many variants and its not so easy to
find useful information about it. The only reference I have is this.

POST /RPC2 HTTP/1.0
User-Agent: Frontier/5.1.2 (WinNT)
Host: betty.userland.com
Content-Type: text/xml
Content-length: 181

<?xml version="1.0"?>
<methodCall>
    <methodName>examples.getStateName</methodName>
    <params>
        <param>
            <value><i4>41</i4></value>
            </param>
        </params>
    </methodCall>

In my case to test with XMLRPC Server in Python (from code-exchange)
I believe the above code should be.

POST /RPC2 HTTP/1.0
User-Agent: Frontier/5.1.2 (WinNT)
Host: localhost:8000
Content-Type: text/xml
Content-length: (request's setValue:postLength forHTTPHeaderField:"Content-Length")

<?xml version="1.0"?>
<methodCall>
    <methodName>add</methodName>
    <params>
        <param>
            <value><i4>2</i4></value>
        </param>
		<param>
            <value><i4>3</i4></value>
        </param>
	</params>
</methodCall>

The XMLRPC use a mix of XML and HTTP.

You could try yourself, the XMLRPC server code is in code-exchange, maybe you are more lucky and me. :slight_smile:

I find more info about XMLRPC: XMLRPC HowTo

I will try to make XML to NSData and see if that works.

And of course it didn’t work :slight_smile:

set theHTTPBody to "<?xml version=\"1.0\"?>
<methodCall>
	<methodName>add</methodName>
		<params>
		<param>
			<value><i4>2</i4></value>
		</param>
		<param>
			<value><i4>3</i4></value>
		</param>
        </params>
</methodCall>
"

set theString to current application's NSString's stringWithString:theHTTPBody
set theData to theString's dataUsingEncoding:(current application's NSASCIIStringEncoding)

-- set post to current application's NSString's stringWithFormat:"methodName=add&param=2&param:3"
-- set postData to post's dataUsingEncoding:(current application's NSASCIIStringEncoding) allowLossyConversion:true
set postLength to current application's NSString's stringWithFormat_("%d", theData's |length|())
set theURL to current application's |NSURL|'s URLWithString:"http://localhost:8000/RPC2"
set request to current application's NSMutableURLRequest's alloc()'s initWithURL:theURL
request's setHTTPMethod:"POST"
-- request's setValue:"localhost" forHTTPHeaderField:"Host"
request's setValue:postLength forHTTPHeaderField:"Content-Length"
request's setHTTPBody:theData

set theConfiguration to current application's NSURLSessionConfiguration's defaultSessionConfiguration()
set session to current application's NSURLSession's sessionWithConfiguration:theConfiguration delegate:(me) delegateQueue:(missing value)
set dataTask to session's dataTaskWithRequest:request
dataTask's resume()

Here is an edited version of the function with global properties and added in the correct current application’s where needed

  -- classes, constants, and enums used

property retData : missing value
property retStatusCode : 0
property retStatusCodeInfo : ""
property retHeaders : missing value

on URLSession:tmpSession dataTask:tmpTask didReceiveData:tmpData
	set aState to tmpTask's state()
	set aResponse to tmpTask's response()
	set (my retStatusCode) to aResponse's statusCode()
	set (my retStatusCodeInfo) to current application's NSHTTPURLResponse's localizedStringForStatusCode:(my retStatusCode)
	set (my retHeaders) to aResponse's allHeaderFields()
	
	set resStr to current application's NSString's alloc()'s initWithData:tmpData encoding:(current application's NSUTF8StringEncoding)
	set jsonString to current application's NSString's stringWithString:resStr
	
	set jsonData to jsonString's dataUsingEncoding:(current application's NSUTF8StringEncoding)
	set aJsonDict to current application's NSJSONSerialization's JSONObjectWithData:jsonData options:0 |error|:(missing value)
	if aJsonDict's isKindOfClass:(current application's NSDictionary's |class|()) then
		set my retData to aJsonDict as record
	else
		set my retData to aJsonDict as list
	end if
end URLSession:dataTask:didReceiveData:

Thanks for trying… did you succed with my example?

When I look at your handler, the variable tmpData confuse me…
How do I set that one?

@technomorph

Here is the code I try to run, and it include XMLRPC server in python code.
The respond of the POST to the server should return the number 5

Try it and maybe you get it to work.

use framework "Foundation"
use scripting additions

property retData : missing value
property retStatusCode : 0
property retStatusCodeInfo : ""
property retHeaders : missing value

set post to current application's NSString's stringWithFormat:"methodName=add&param=2&param=3"
set postData to post's dataUsingEncoding:(current application's NSASCIIStringEncoding) allowLossyConversion:true
set postLength to current application's NSString's stringWithFormat_("%d", postData's |length|())
set theURL to current application's |NSURL|'s URLWithString:"http://localhost:8000/RPC2"
set request to current application's NSMutableURLRequest's alloc()'s initWithURL:theURL
request's setHTTPMethod:"POST"
request's setValue:postLength forHTTPHeaderField:"Content-Length"
request's setHTTPBody:postData

set theConfiguration to current application's NSURLSessionConfiguration's defaultSessionConfiguration()
set session to current application's NSURLSession's sessionWithConfiguration:theConfiguration delegate:(me) delegateQueue:(missing value)
set dataTask to session's dataTaskWithRequest:request
dataTask's resume()

its URLSession:session dataTask:dataTask didReceiveData:tmpData

on URLSession:tmpSession dataTask:tmpTask didReceiveData:tmpData
	set aState to tmpTask's state()
	set aResponse to tmpTask's response()
	set (my retStatusCode) to aResponse's statusCode()
	set (my retStatusCodeInfo) to current application's NSHTTPURLResponse's localizedStringForStatusCode:(my retStatusCode)
	set (my retHeaders) to aResponse's allHeaderFields()
	
	set resStr to current application's NSString's alloc()'s initWithData:tmpData encoding:(current application's NSUTF8StringEncoding)
	set jsonString to current application's NSString's stringWithString:resStr
	
	set jsonData to jsonString's dataUsingEncoding:(current application's NSUTF8StringEncoding)
	set aJsonDict to current application's NSJSONSerialization's JSONObjectWithData:jsonData options:0 |error|:(missing value)
	if aJsonDict's isKindOfClass:(current application's NSDictionary's |class|()) then
		set my retData to aJsonDict as record
	else
		set my retData to aJsonDict as list
	end if
end URLSession:dataTask:didReceiveData:


(** XMLRPC Server, copy to textfile.py and run it. (Python3)

from xmlrpc.server import SimpleXMLRPCServer
from xmlrpc.server import SimpleXMLRPCRequestHandler

# Restrict to a particular path.
class RequestHandler(SimpleXMLRPCRequestHandler):
    rpc_paths = ('/RPC2',)

# Create server
with SimpleXMLRPCServer(('localhost', 8000),
                        requestHandler=RequestHandler) as server:
    server.register_introspection_functions()

    # Register pow() function; this will use the value of
    # pow.__name__ as the name, which is just 'pow'.
    server.register_function(pow)

    # Register a function under a different name
    def adder_function(x, y):
        return x + y
    server.register_function(adder_function, 'add')

    # Register an instance; all the methods of the instance are
    # published as XML-RPC methods (in this case, just 'mul').
    class MyFuncs:
        def mul(self, x, y):
            return x * y

    server.register_instance(MyFuncs())

    # Run the server's main loop
    server.serve_forever()
	
*)

I tested other approach to see some errors. I was able to return XML from the response
and it complain about what I believe is the postData. To edit the postData I could see
other type of error…

use framework "Foundation"
use scripting additions

set {methodString, paramNumber1, paramNumber2} to {"add", 2, 3}
set thePost to current application's NSString's ¬
	stringWithFormat_("methodName=%@param=%@param=%@", methodString, paramNumber1, paramNumber2)
set postData to (thePost's dataUsingEncoding:(current application's NSASCIIStringEncoding))

set postLength to current application's NSString's stringWithFormat_("%d", postData's |length|())
set theURL to current application's |NSURL|'s URLWithString:"http://localhost:8000/RPC2"
set request to current application's NSMutableURLRequest's alloc()'s initWithURL:theURL
request's setHTTPMethod:"POST"
-- request's setValue:"text/xml" forHTTPHeaderField:"content-type"
request's setValue:postLength forHTTPHeaderField:"Content-Length"
request's setHTTPBody:postData

set response to current application's NSHTTPURLResponse's alloc()'s init()

set theConnectionData to (current application's NSURLConnection's sendSynchronousRequest:request returningResponse:response |error|:(missing value))
set responseBody to current application's NSString's alloc()'s initWithData:theConnectionData encoding:(current application's NSASCIIStringEncoding)

Maybe I'm missing something, or thought it was to simple. Many times the difficult part isn't to
convert Objective-C code to ASObjC its to understand how things are working when documentation is so poorly in many ways or how to get it with examples.

responseBody as string

Sorry I forgot about a few things since I’ve been mainly working with Objective-C Block methods.

Need to incorporate the one other delegate method. Which informs the delegate that the task is done:

on URLSession:aSession task:aTask didCompleteWithError:aError

As the other method will be called with partial data and it may not be complete.
So we have to collect and append the data

on URLSession:aSession dataTask:aTask didReceiveData:someData
	(retData's appendData:someData)
end URLSession:dataTask:didReceiveData:

And may as well add another delegate method that gets called when it fails

on URLSession:aSession didBecomeInvalidWithError:aError

See next reply with modified functions

Updated Code:::: Does not included the full request and session set up

-- classes, constants, and enums used
property retData : missing value
property retStatusCode : 0
property retStatusCodeInfo : ""
property retHeaders : missing value

property requestDone : false
property parsedData : missing value

on setUpAndSendRequest()
	-- TRIMMED ALL OTHER request and theConiguration setUps
	set session to current application's NSURLSession's sessionWithConfiguration:theConfiguration delegate:(me) delegateQueue:(missing value)
	set dataTask to session's dataTaskWithRequest:request
	my resetRecievedData()
	dataTask's resume()
	
	-- SET UP AND RUN A LOOP THAT CHECKS IF REQUEST IS DONE
	repeat 10000 times
		if (requestDone) then exit repeat
		current application's NSThread's sleepForTimeInterval:("0.001" as real) --delay 0.001
	end repeat
	
	-- REQUEST IS DONE NOW CHECKS IF retData IS OK
	if retData is not equal to missing value then
		set parsedData to my parseRecievedData:retData
	end if
	my logAllVariables()
end setUpAndSendRequest

-- RESET ALL BASE RECIEVED DATA VARIABLES
on resetRecievedData()
	set retData to current application's NSMutableData's alloc()'s init()
	set retStatusCode to 0
	set retStatusCodeInfo to ""
	set retHeaders to missing value
	set requestDone to false
	set parsedData to missing value
end resetRecievedData

on URLSession:aSession dataTask:aTask didReceiveData:someData
	(retData's appendData:someData)
end URLSession:dataTask:didReceiveData:

on URLSession:aSession didBecomeInvalidWithError:aError
	my logError:aError
	set requestDone to true
end URLSession:didBecomeInvalidWithError:

on URLSession:aSession task:aTask didCompleteWithError:aError
	if (aError ≠ missing value) then
		my logError:aError
		set requestDone to true
		return
	end if
	set aState to aTask's state()
    log {"aTask's state is", aState}
	set aResponse to aTask's response()
	set (my retStatusCode) to aResponse's statusCode()
	set (my retStatusCodeInfo) to current application's NSHTTPURLResponse's localizedStringForStatusCode:(my retStatusCode)
	set (my retHeaders) to aResponse's allHeaderFields()
	set requestDone to true
end URLSession:task:didCompleteWithError:

on parseRecievedData:someData
	set parsedInfo to missing value
	set resStr to current application's NSString's alloc()'s initWithData:someData encoding:(current application's NSUTF8StringEncoding)
	set jsonString to current application's NSString's stringWithString:resStr
	
	set jsonData to jsonString's dataUsingEncoding:(current application's NSUTF8StringEncoding)
	set jsonDict to current application's NSJSONSerialization's JSONObjectWithData:jsonData options:0 |error|:(missing value)
	if jsonDict's isKindOfClass:(current application's NSDictionary's |class|()) then
		set parsedInfo to jsonDict as record
	else
		set parsedInfo to jsonDict as list
	end if
	return parsedInfo
end parseRecievedData:

on logError:aError
	error aError's localizedDescription() as text
end logError:

on logAllVariables()
	log {"requestDone is", requestDone}
	log {"retData is", retData}
	log {"retStatusCode is", retStatusCode}
	log {"retStatusCodeInfo is", retStatusCodeInfo}
	log {"retHeaders is", retHeaders}
	log {"parsedData is", parsedData}
end logAllVariables

@technomorph
I’m very thanksful that you take the time to teach me new thing.

I took your code and change little in the log handler to give me more useful info.
It looks like the code do POSTand the return is: faultCode:8002

From the Twisted API I could see its wrong arguments to XMLRPC
Reference: Error handler XMLRPC
The server I have test on is Twisted (python module)

So text step is to get the method name, arguments correct.

use framework "Foundation"
use scripting additions

-- classes, constants, and enums used
property retData : missing value
property retStatusCode : 0
property retStatusCodeInfo : ""
property retHeaders : missing value

property requestDone : false
property parsedData : missing value

set {methodString, paramNumber1} to {"type", {a:1, b:5}}
set thePost to current application's NSString's ¬
	stringWithFormat_("methodName=%@param=%@param=%@", methodString, paramNumber1)
set postData to (thePost's dataUsingEncoding:(current application's NSASCIIStringEncoding))

set postLength to current application's NSString's stringWithFormat_("%d", postData's |length|())
set theURL to current application's |NSURL|'s URLWithString:"http://localhost:7080/"
set request to current application's NSMutableURLRequest's alloc()'s initWithURL:theURL
request's setHTTPMethod:"POST"
request's setValue:"text/xml" forHTTPHeaderField:"content-type"
request's setValue:postLength forHTTPHeaderField:"Content-Length"
request's setHTTPBody:postData

set theConfiguration to current application's NSURLSessionConfiguration's defaultSessionConfiguration()

its setUpAndSendRequest()

on setUpAndSendRequest()
	-- TRIMMED ALL OTHER request and theConiguration setUps
	set session to current application's NSURLSession's sessionWithConfiguration:(its theConfiguration) delegate:(me) delegateQueue:(missing value)
	set dataTask to session's dataTaskWithRequest:(its request)
	my resetRecievedData()
	dataTask's resume()
	
	-- SET UP AND RUN A LOOP THAT CHECKS IF REQUEST IS DONE
	repeat 10000 times
		if (requestDone) then exit repeat
		current application's NSThread's sleepForTimeInterval:("0.001" as real) --delay 0.001
	end repeat
	
	-- REQUEST IS DONE NOW CHECKS IF retData IS OK
	if retData is not equal to missing value then
		set parsedData to my parseRecievedData:retData
	end if
	my logAllVariables()
end setUpAndSendRequest

-- RESET ALL BASE RECIEVED DATA VARIABLES
on resetRecievedData()
	set retData to current application's NSMutableData's alloc()'s init()
	set retStatusCode to 0
	set retStatusCodeInfo to ""
	set retHeaders to missing value
	set requestDone to false
	set parsedData to missing value
end resetRecievedData

on URLSession:aSession dataTask:aTask didReceiveData:someData
	(retData's appendData:someData)
end URLSession:dataTask:didReceiveData:

on URLSession:aSession didBecomeInvalidWithError:aError
	my logError:aError
	set requestDone to true
end URLSession:didBecomeInvalidWithError:

on URLSession:aSession task:aTask didCompleteWithError:aError
	if (aError ≠ missing value) then
		my logError:aError
		set requestDone to true
		return
	end if
	set aState to aTask's state()
	log {"aTask's state is", aState}
	set aResponse to aTask's response()
	set (my retStatusCode) to aResponse's statusCode()
	set (my retStatusCodeInfo) to current application's NSHTTPURLResponse's localizedStringForStatusCode:(my retStatusCode)
	set (my retHeaders) to aResponse's allHeaderFields()
	set requestDone to true
end URLSession:task:didCompleteWithError:

on parseRecievedData:someData
	set parsedInfo to missing value
	set resStr to current application's NSString's alloc()'s initWithData:someData encoding:(current application's NSUTF8StringEncoding)
	set jsonString to current application's NSString's stringWithString:resStr
	
	set jsonData to jsonString's dataUsingEncoding:(current application's NSUTF8StringEncoding)
	set jsonDict to current application's NSJSONSerialization's JSONObjectWithData:jsonData options:0 |error|:(missing value)
	if jsonDict is missing value then return "JSON Dictionary is missing value"
	if jsonDict's isKindOfClass:(current application's NSDictionary's |class|()) then
		set parsedInfo to jsonDict as record
	else
		set parsedInfo to jsonDict as list
	end if
	return parsedInfo
end parseRecievedData:

on logError:aError
	error aError's localizedDescription() as text
end logError:

on logAllVariables()
	set theString to current application's NSString's alloc()'s initWithData:retData encoding:(current application's NSASCIIStringEncoding)
	log {"retData string is", theString as string}
	log {"requestDone is", requestDone}
	log {"retData is", retData's |description|() as string}
	log {"retStatusCode is", retStatusCode}
	log {"retStatusCodeInfo is", retStatusCodeInfo's |description|() as string}
	log {"retHeaders is", retHeaders's |description|() as string}
	log {"parsedData is", parsedData}
end logAllVariables

The eror code: Can’t deserialize input: not well-formed (invalid token): line 1, column 6
Its from this line: method=%@&args=%@

In looks to me it complain about ‘=’ in that line.

Your stringWithFormat is wrong, it’s expecting 3 values and you only provide 2.
For paramNumber1 your providing a Dictionary/Record

I think you need to provide two variables:
methodName
params

params seem like it can be a list
IE {param=2, param=3}

Usually when I create postBody data I create it from a Dictionary and convert to JSON.

@technomorph
Is this what you are talking about?
XMLRPC - JSON

I made a new script with json also I made e new function (echo) return the input

use framework "Foundation"
use scripting additions

-- classes, constants, and enums used
property retData : missing value
property retStatusCode : 0
property retStatusCodeInfo : ""
property retHeaders : missing value

property requestDone : false
property parsedData : missing value

set jsonString to "{
    \"methodCall\": {
        \"methodName\": \"echo\",
        \"params\": [
            1
            ]
        }
    }"

set thePost to current application's NSString's stringWithString:jsonString
set postData to (thePost's dataUsingEncoding:(current application's NSUTF8StringEncoding))
set jsonData to current application's NSJSONSerialization's JSONObjectWithData:postData options:0 |error|:(missing value)
log (current application's NSJSONSerialization's isValidJSONObject:jsonData)
set postLength to current application's NSString's stringWithFormat_("%d", postData's |length|())
set theURL to current application's |NSURL|'s URLWithString:"http://localhost:7080"
set request to current application's NSMutableURLRequest's alloc()'s initWithURL:theURL
request's setHTTPMethod:"POST"
-- request's setValue:"text/xml" forHTTPHeaderField:"content-type"
-- request's setValue:postLength forHTTPHeaderField:"Content-Length"
request's setHTTPBody:postData

set theConfiguration to current application's NSURLSessionConfiguration's defaultSessionConfiguration()

its setUpAndSendRequest()

on setUpAndSendRequest()
	-- TRIMMED ALL OTHER request and theConiguration setUps
	set session to current application's NSURLSession's sessionWithConfiguration:(its theConfiguration) delegate:(me) delegateQueue:(missing value)
	set dataTask to session's dataTaskWithRequest:(its request)
	my resetRecievedData()
	dataTask's resume()
	
	-- SET UP AND RUN A LOOP THAT CHECKS IF REQUEST IS DONE
	repeat 10000 times
		if (requestDone) then exit repeat
		current application's NSThread's sleepForTimeInterval:("0.001" as real) --delay 0.001
	end repeat
	
	-- REQUEST IS DONE NOW CHECKS IF retData IS OK
	if retData is not equal to missing value then
		set parsedData to my parseRecievedData:retData
	end if
	my logAllVariables()
end setUpAndSendRequest

-- RESET ALL BASE RECIEVED DATA VARIABLES
on resetRecievedData()
	set retData to current application's NSMutableData's alloc()'s init()
	set retStatusCode to 0
	set retStatusCodeInfo to ""
	set retHeaders to missing value
	set requestDone to false
	set parsedData to missing value
end resetRecievedData

on URLSession:aSession dataTask:aTask didReceiveData:someData
	(retData's appendData:someData)
end URLSession:dataTask:didReceiveData:

on URLSession:aSession didBecomeInvalidWithError:aError
	my logError:aError
	set requestDone to true
end URLSession:didBecomeInvalidWithError:

on URLSession:aSession task:aTask didCompleteWithError:aError
	if (aError ≠ missing value) then
		my logError:aError
		set requestDone to true
		return
	end if
	set aState to aTask's state()
	log {"aTask's state is", aState}
	set aResponse to aTask's response()
	set (my retStatusCode) to aResponse's statusCode()
	set (my retStatusCodeInfo) to current application's NSHTTPURLResponse's localizedStringForStatusCode:(my retStatusCode)
	set (my retHeaders) to aResponse's allHeaderFields()
	set requestDone to true
end URLSession:task:didCompleteWithError:

on parseRecievedData:someData
	set parsedInfo to missing value
	set resStr to current application's NSString's alloc()'s initWithData:someData encoding:(current application's NSUTF8StringEncoding)
	set jsonString to current application's NSString's stringWithString:resStr
	
	set jsonData to jsonString's dataUsingEncoding:(current application's NSUTF8StringEncoding)
	set jsonDict to current application's NSJSONSerialization's JSONObjectWithData:jsonData options:0 |error|:(missing value)
	if jsonDict is missing value then return "JSON Dictionary is missing value"
	if jsonDict's isKindOfClass:(current application's NSDictionary's |class|()) then
		set parsedInfo to jsonDict as record
	else
		set parsedInfo to jsonDict as list
	end if
	return parsedInfo
end parseRecievedData:

on logError:aError
	error aError's localizedDescription() as text
end logError:

on logAllVariables()
	set theString to current application's NSString's alloc()'s initWithData:retData encoding:(current application's NSUTF8StringEncoding)
	log {"retData string is", theString as string}
	log {"requestDone is", requestDone}
	log {"retData is", retData's |description|() as string}
	log {"retStatusCode is", retStatusCode}
	log {"retStatusCodeInfo is", retStatusCodeInfo's |description|() as string}
	log {"retHeaders is", retHeaders's |description|() as string}
	log {"parsedData is", parsedData}
end logAllVariables

You want to set that to jsonData not postData

You may also need. to set content-Type to JSON