I would like to post a json and I wrote the function:
/**
* Post JSON object
*/
public func testPostJsonString(var url:String,
parameters: AnyObject![],
success: (response:String?) ->(),
error: (response:Exception?) ->()) ->() {
let content = HttpRequestContent();
let request = HttpRequest( Url(url) );
request.Mode=HttpRequestMode.Post;
request.FollowRedirects = true;
request.Content=content;
//request.Headers = ["User-Agent" : "swift-test"];
let httpContentResponseBlock: HttpContentResponseBlock<Sugar.Json.JsonDocument!>! = { response in
if response.Success {
// Json Object Response
let jsonObject:Sugar.Json.JsonObject = response.Content.RootObject;
success( jsonObject.ToJson() );
}
else {
error(response.Exception);
}
}
Http.ExecuteRequestAsJson( request, httpContentResponseBlock)
} //testPostJsonString
Looking at the sources - https://github.com/remobjects/sugar/blob/master/Sugar/HTTP.pas
I’m not sure how to pass the Dictionary / String of the contents (supposed to post a JSON / form) using the writable property of type HttpRequestContent
.
The typical json to post would be a valid nest json like:
{
"timestamp" : 1455205092,
"data" : {
"name" : "data"
"type" : "event"
}
}
Also I see that the headers property is not writable so how to set up custom headers like:
request.Headers = [["User-Agent" : "swift-test"]];
This would help for server that need specific headers like Accept
etc.
According to the HTTP.pas
:
method ExecuteRequestAsJson(aRequest: not nullable HttpRequest; contentCallback: not nullable HttpContentResponseBlock<JsonDocument>);
I’m doing
let request = HttpRequest( Url(url) );
request.Mode=HttpRequestMode.Post;
request.FollowRedirects = true;
request.Content=content;
//...
I get an Exception:
Type: NSException Message: An exception of type: NSException occurred: Invalid Cast Exception Detached
when calling
Http.ExecuteRequestAsJson( request, httpContentResponseBlock)
mh
(marc hoffman)
February 11, 2016, 6:24pm
3
ExecuteRequestAsJson
does a get and handles the result as Json. I don’t think we have explicit support for posting Json data yet, you’d have to post it as binary or string for now. I’ll look at expanding the API (iirc there is a basic mechanism for hooking custom data types into the post data, but I’ll need to check, it’s been a while). I’ll also look at the headers and why those aren writable. That sounds like a bug.
mh:
headers
Great! Regarding the headers I see that the property is readonly
:
property Headers: not nullable Dictionary<String,String> := new Dictionary<String,String>; readonly;
In the meanwhile I can use the HttpRequestMode.Post
with String. Where I put the String, and how make the request (which method of Http
or HttpRequest
instance to use)?
Thank you!
mh
(marc hoffman)
February 11, 2016, 6:40pm
5
Well, yes. but that applies to assigning a different dictionary to the property (you can’t and should not). it doesn’t mean you can’t change the one that’d there, and add new values to it?
mh
(marc hoffman)
February 11, 2016, 6:42pm
6
something like
let body = yourJson.ToString()
request.Content = HttpBinaryRequestContent(body, Encoding.UTF8)
right. And then I can use Http.ExecuteRequestAsBinary
or even ExecuteRequestAsString
?
mh
(marc hoffman)
February 11, 2016, 10:21pm
8
Yes.
Latest commit adds an overload for HttpBinaryRequestContent that takes a Json. As for which execute request you wanna run, that depends on what kind of data you expect to get back. If you expect back Json as well, use ExecuteRequestAsJson, for example.
mh:
atest commit adds an overload for HttpBinaryRequestContent that takes a Json. As for which execute request you wanna run, that depends on what kind of data you expect to get back. If you expect back Json as well, use ExecuteRequestAsJson, for example.
Super! Is in in the develop
tree already?
So, I have tried the Http.ExecuteRequest
plus headers modifications:
let body = "name=test&value=pippo"//yourJson.ToString()
let request = HttpRequest( Url(url) );
request.Mode=HttpRequestMode.Post;
request.FollowRedirects = true;
request.Headers["User-Agent"]="switft-example";
request.Content = HttpBinaryRequestContent(body, Encoding.UTF8)
Http.ExecuteRequest(request, { response in
if response.Success {
response.GetContentAsString(nil) { content in
if content.Success {
success( content.Content )
}
else {
error(response.Exception);
}
}
}
});
The dumped response was - http://www.posttestserver.com/data/2016/02/12/swift-promise/01.37.08192355800
Time: Fri, 12 Feb 16 01:37:08 -0800
Source ip: 89.97.90.230
Headers (Some may be inserted by server)
REQUEST_URI = /post.php?dir=swift-promise
QUERY_STRING = dir=swift-promise
REQUEST_METHOD = POST
GATEWAY_INTERFACE = CGI/1.1
REMOTE_PORT = 59093
REMOTE_ADDR = 89.97.90.230
HTTP_ACCEPT_ENCODING = gzip, deflate
CONTENT_LENGTH = 21
HTTP_ACCEPT_LANGUAGE = it-it
HTTP_USER_AGENT = SampleiOSApp/1.0 CFNetwork/758.2.8 Darwin/15.0.0
HTTP_ACCEPT = */*
HTTP_CONNECTION = close
CONTENT_TYPE = application/x-www-form-urlencoded
HTTP_HOST = posttestserver.com
SSL_TLS_SNI = posttestserver.com
HTTPS = on
UNIQUE_ID = Vr2nxEBaMGUAAE7Xd3AAAAAG
REQUEST_TIME_FLOAT = 1455269828.2091
REQUEST_TIME = 1455269828
Post Params:
key: 'name' value: 'test'
key: 'value' value: 'pippo'
Empty post body.
Upload contains PUT data:
name=test&value=pippo
The request url was on a test server apiEndpoint="https://posttestserver.com/post.php?dir=swift-promise"
It was the right way to modify headers in
request.Headers["User-Agent"]="switft-example";
It seems that the server is not getting the change. Tested on both Fire / Xcode iOS apps.
mh
(marc hoffman)
February 12, 2016, 1:24pm
10
So looks like it’s all working?
The post is working but the headers are not being modified doing request.Headers["User-Agent"]="switft-example";
(maybe it’s not the right way…)
mh
(marc hoffman)
February 16, 2016, 12:40pm
12
Ah, ok. i’ll check. this happens on iOS only, or al all platforms?
mh
(marc hoffman)
February 16, 2016, 12:51pm
13
Looks like indeed the leaders are never being set. Fixing.
mh:
this
@mh I was not able to test on Android. I will try as soon as I have Fire to get back working!
mh
(marc hoffman)
February 16, 2016, 2:46pm
15
No need to, i don’t think any platform currently sets them… will fix all — retesting with next would be appreciated though.
Absolutely I’m checking that, thank you!
@mh I have updated Sugar to the latest commit 74be2596d003349e5c6b9ee8fe4e58d8e60766a6
and checkout out, it seems the headers are not modified yet:
Time: Mon, 22 Feb 16 07:22:34 -0800
Source ip: 5.90.77.25
Headers (Some may be inserted by server)
REQUEST_URI = /post.php?dir=swift-promise
QUERY_STRING = dir=swift-promise
REQUEST_METHOD = POST
GATEWAY_INTERFACE = CGI/1.1
REMOTE_PORT = 1221
REMOTE_ADDR = 5.90.77.25
HTTP_ACCEPT_ENCODING = gzip, deflate
CONTENT_LENGTH = 21
HTTP_ACCEPT_LANGUAGE = it-it
HTTP_USER_AGENT = iOSSilverSampleApp/1.0 CFNetwork/758.2.8 Darwin/15.0.0
HTTP_ACCEPT = */*
HTTP_CONNECTION = close
CONTENT_TYPE = application/x-www-form-urlencoded
HTTP_HOST = posttestserver.com
SSL_TLS_SNI = posttestserver.com
HTTPS = on
UNIQUE_ID = VssnukBaMGUAAEA1LckAAAAH
REQUEST_TIME_FLOAT = 1456154554.4659
REQUEST_TIME = 1456154554
Post Params:
key: 'name' value: 'test'
key: 'value' value: 'pippo'
Empty post body.
Upload contains PUT data:
name=test&value=pippo
setting
request.Headers["User-Agent"]="switft-example";
mh
(marc hoffman)
February 22, 2016, 8:01pm
18
Yes, this fix isn’t in yet, sorry. Didn’t get chance to fully do it for all platforms yet.
1 Like
mh
(marc hoffman)
March 1, 2016, 4:44pm
20
Are you mixing threads here? is this about HTTP Headers or JSON?
I just wrote a response supposed to be in Sugar.json.JsonObject.getKeys: java.lang.ClassCastException here, don’t tell me why…removing!