Obj. C - how to deal with wrong written JSON - ios

I obtained some badly written JSON file that's totally not readable through any AFNetworking and/or any other JSON serializing library. I must underline that I am not able to force to change it on server-side so I have to parse it as is.
Unfortunately it has some minor errors (I will paste small part of it):
locations = [{
"city": "Tokio",
(...)
"link": "http://somethig.com",
"text": "Mon-Fr.",
}, {
(... same repeated mistakes, but they're not regular)
}]
Aaand to parse it correctly in XCode i need to change it to correct format e.g.:
{
"locations": [{
"city": "Tokio",
(...)
"link": "http://somethig.com",
"text": "Mon-Fr."
}, {
(...)
}]
}
Do you have any idea how to deal with that?
If I will have to write my own parser - please advice me how to. Any help will be appreciated. I download this JSON from http link.

It looks like the API is sending you a string of JavaScript code. In JavaScript, you would use JSON.stringify() to convert the object to valid JSON. Here's an example from an interactive node.js shell:
> locations = [{
... "city": "Tokio",
... "link": "http://somethig.com",
... "text": "Mon-Fr.",
... }]
[ { city: 'Tokio', link: 'http://somethig.com', text: 'Mon-Fr.' } ]
> JSON.stringify(locations)
'[{"city":"Tokio","link":"http://somethig.com","text":"Mon-Fr."}]'
If you really can't change this on the server side, you might try creating a hidden UIWebView, adding the JavaScript, calling JSON.stringify(), and extracting the result. However, this will use many more resources than are needed. It would be much better (in terms of computing power, memory, and your time) to have the API call JSON.stringify() and send you a valid JSON string.
You could also try porting some of json3.js to Objective-C or Swift. I would start with the section beginning // Public: `JSON.stringify`. if you attempt this.

Related

Remark: How to parse HTML tags and their content in MDAST

I'm trying to parse a GitHub-flavoured markdown file using Unified and Remark-Parse to generate a MDAST. I'm able to parse most of it correctly and easily, however I'm having trouble parsing the HTML tags and their content from the AST.
In the AST, HTML tags and their contents are represented as siblings, not parent-child. For example <sub>hi</sub> is parsed into
[
{
"type": "paragraph",
"children": [
{
"type": "html",
"value": "<sub>",
},
{
"type": "text",
"value": "hi",
},
{
"type": "html",
"value": "</sub>",
}
]
}
]
Ideally, I would want it to be parsed like
[
{
"type": "paragraph",
"children": [
{
"type": "html",
"value": "sub",
"children": [
{
"type": "text",
"value": "hi",
},
]
},
]
}
]
so that I can access the tag type and its content. (Specifically, my goal is to just skip over the tags and their content as they are not needed for my purposes)
This is the configuration I am using currently:
import unified from 'unified';
import markdown from 'remark-parse';
import type {Block} from '#notionhq/client/build/src/api-types';
import {parseRoot} from './internal';
import gfm from 'remark-gfm';
export function parseBody(body: string): Block[] {
const tokens = unified().use(markdown).use(gfm).parse(body);
return parseRoot(tokens);
}
So, my question is: Is there a way of configuring Remark to do so / is there a Remark plugin to do this? If not, how would I go about creating a plugin that does so?
Thanks.
first: why the AST looks as it does and why Remark most likely does not have an option to do it differently
The reason that the AST represents it that way is because that is what the CommonMark specification specifies for raw inline HTML and for HTML blocks. Specifically, CommonMark specifies that HTML tags are passed through, not parsed.
For inline HTML, the spec supports inline HTML tags, which is not the same as supporting inline HTML. Tags are simply passed through as-is. There is no matching of opening and closing tags. The reasons for this are:
performance
parser complexity
HTML tags are only supported as a "use at your own risk" "last resort" option when Markdown doesn't have a feature you need.
For a small number of HTML tags, open and close tag matching is supported at the block-level. pre, script, style, and textarea, the latter only added recently in v0.30 of the spec.
You can read the above linked parts of the spec, and search the discussions in the CommonMark forum to get more understanding of the whys, but to get right to the point, read:
This explanation within the spec for the choices made.
Skip to [the Raw HTML section of this forum]( the https://talk.commonmark.org/t/beyond-markdown/2787?u=vas) post by the CommonMark spec author and maintainer, John MacFarlane (#jgm).
This forum question and also this one and #jgm's answers.
second: what you can do about it
Remark is "part of the unified collective", which is an infrastructure centered around the processing of AST (abstract syntax trees). From your question, it sounds like you already get this.
There is lot's of help on unified's pages for how to write plugins:
https://github.com/unifiedjs/unified
https://unifiedjs.com/learn/guide/create-a-plugin/
But the best way to both learn how to do this and to get a quick jump on an implementation is to look at the many existing mdast-specific manipulators.

Outgoing Webhook what is the format of the response message?

I have created an outgoing webhook in MS Teams. At mentioning the name specified in the outgoing webhook, it will successfully cause an API call in my app - all fine and good.
According to the documentation, my app is required to respond to that request with a response message. But I absolutely can't find any documentation of the format that is accepted in this response.
The only reference, I can find is this one:
https://learn.microsoft.com/en-us/microsoftteams/platform/webhooks-and-connectors/how-to/add-outgoing-webhook
Unfortunately, it does not go into detail of what such a message can look like. It only gives an example that this would be acceptable:
{
"type": "message",
"text": "This is a reply!"
}
I would however not like to respond with a simple message, but much rather with something more rich formatted like a card or - in some cases a reaction instead of a message.
Is that possible? Is there any documentation, what other responses are acceptable? Are there other types than just "message" that can be returned?
Alright, here's a quick and dirty way to handle things for teams. For some reason this is not documented very clearly, but what teams requires is for the "Card" to be created as an attachment, instead of just getting the response directly.
What I've done is capture the boilerplate required to house the card first:
string TeamsAdaptiveCardBoilerplate =
#"
{
""type"":""message"",
""attachments"":[
{
""contentType"":""application/vnd.microsoft.card.adaptive"",
""contentUrl"":null,
""content"":{
""$schema"":""http://adaptivecards.io/schemas/adaptive-card.json"",
""type"":""AdaptiveCard"",
""version"":""1.2"",
""body"":[
##BODY##
]
}
}
]
}
";
Then, I build the body (usually, this would not be static text, but it serves well as an example)
string AdaptiveCardBody =
#"
{
""type"": ""TextBlock"",
""text"": ""Here is a ninja cat""
},
{
""type"": ""Image"",
""url"": ""http://adaptivecards.io/content/cats/1.png""
}
";
Next I simple swap out the placeholder with the real body:
var jsonPayload1 = TeamsAdaptiveCardBoilerplate.Replace("##BODY##", AdaptiveCardBody);
And finally, return the assembled payload (converted back into an object so the correct response headers get set):
var payload1 = JsonConvert.DeserializeObject(jsonPayload1);
return (ActionResult)new OkObjectResult(payload1);
From there, you should be good to go.
Note:
For convenience, the entirety of the "content" (and not "body") block is what you'd copy/paste into the adaptivecards.io designer. You might refactor the above to reflect that reality if it was important to you.
Could you please try this sample json { "$schema": "adaptivecards.io/schemas/adaptive-card.json", "type": "AdaptiveCard", "version": "1.2", "body": [ { "type": "Image", "url": "c.s-microsoft.com/en-us/CMSImages/…" }, { "type": "TextBlock", "text": "Sample image for Adaptive Card..", "wrap": true } ] }

Response Templating for a Static Json File

I am using WireMock in java to stub for a POST request. The request returns a json body file that is stored in my local. The stub looks like this:
wireMockServer.stubFor(get(urlMatching("/v1/invoices/.*"))
.willReturn(aResponse()
.withStatus(200)
.withBodyFile("testgetupgradeprorationamount/stubThree")));
Part of the response body file, "stubThree" looks like this:
"id": "ii_1EmM93Htp4Kkdrs8",
"object": "line_item",
"amount": 9600,
"currency": "usd",
"description": "Remaining time on 3 × Business after 17 Jun 2019",
"discountable": false,
"invoice_item": "ii_1EmM93HtpLyYzpmOC4Kkdrs8",
"livemode": false,
"metadata": {
},
"period": {
"end": 1563374954,
"start": 1560782957
}
The request url has a number of paramters and looks like this:
/v1/invoices/?subscription_items[0][quantity]=3&subscription_proration_date=1560892137&customer=cus_FHNIIE4b8LH7qL"
The stubbing works fine, but my goal is to give a dynamic response using response templating. I want to update the "start" field of the json file only, using the "subscription_proration_date" value from the request url.
I changed the start field and the stub like this:
"period": {
"end": 1566053354,
"start": "{{request.query.subscription_proration_date}}"
},
wireMockServer.stubFor(get(urlMatching("/v1/invoices/.*"))
.willReturn(aResponse()
.withStatus(200)
.withBodyFile("testgetupgradeprorationamount/stubThree")
.withTransformers("response-template")));
This is not working for me, so any directions would be really helpful. I also tried removing the quotations around the start field handlebar in the file, and that did not work either.
Thank you in advance!
so I was able to resolve my issue. The problem was that I did not add the proper extension to my WireMockServer instance:
.extensions(new ResponseTemplateTransformer(false));
If the boolean value is false, you additionally need to specify the transformer on a per stub basis like I did above. Otherwise, the extension is applied to all stubs.

Handling better response from Aws::Route53::Client.new

First time trying to use the Ruby AWS ADK V2 and I am trying to format the data i am getting back and it seems quiet hard getting it into useable format.
All I want to do is get a list of Hosted Zones and display in a table.
I have a helper that has:
def hosted_zones
r53 = Aws::Route53::Client.new
#convert to hash first so we can parse and covert to json
h = (r53.list_hosted_zones).to_hash
j = JSON.parse((h.to_json))
end
which then returns me the following JSON:
{
"hosted_zones": [{
"id": "/hostedzone/Z1HSDGASSSME",
"name": "stagephil.com.",
"caller_reference": "2016-07-12T15:33:45.277646707+01:00",
"config": {
"comment": "Private DNS zone for stage",
"private_zone": true
},
"resource_record_set_count": 10
}, {
"id": "/hostedzone/ZJDGASSS0ZN3",
"name": "stagephil.com.",
"caller_reference": "2016-07-12T15:33:41.290143511+01:00",
"config": {
"comment": "Public DNS zone for stage",
"private_zone": false
},
"resource_record_set_count": 7
}],
"is_truncated": false,
"max_items": 100
}
To which I am running a really but while statement to interact through all the hosted_zone entries into a table.
Is this the best way to get the response or can you request the response to be json already?
Why are you converting a hash to JSON, only to convert it to a hash again? JSON.parse(some_hash.to_json) will just give you some_hash.
That being said, I don't think it is possible to get JSON directly from AWS, mainly due to the fact that their API responds with XML. I think that your solution is ideal if that's all you're doing, but if you want, you can make a request with an HTTP client and then take the XML that you receive and use something like ActiveSupport's Hash.from_xml to create a hash that you can then convert to JSON.

Why is Mandrill-api for Node expecting multiple callbacks

This question is mainly addressed to the creators of Mandrill, but anyone who have something to add are of course free to answer!
Why are the mandrill-api expecting two callbacks in the send messages functions? One to handle the result, and a second one to handle errors. I don't know all that much about other programming language, but I do know that in NodeJs there is a wide spread convention of using one callback, with 2 (sometimes more...) parameters. The first parameter is the error (null if non-existent), and the second parameter is the result.
I agree with you completely, Anders!
When I started using this node API, I got a bit fed up with just that. For one thing.
I cloned the latest version (at the time 1.0.39, now its 1.0.40) and transformed the double callback to a "standard" err, res-callback.
This is not tested for all parts of the API but has been working flawlessly for message part of the API
I also converted some of the input arguments to conform to native JS when it comes to taking arguments for e.g. mergevars. This change is made for Messages.prototype.send and Messages.prototype.sendTemplate
Core Mandrill API way:
"global_merge_vars": [{
"name": "merge1",
"content": "merge1 content"
}],
"merge_vars": [{
"rcpt": "recipient.email#example.com",
"vars": [{
"name": "merge2",
"content": "merge2 content"
}]
}],
The expected way (and the way I changed it, naturally ;-)
"global_merge_vars": [{
"merge1": "merge1 content"
}],
"merge_vars": [{
"rcpt": "recipient.email#example.com",
"vars": [{
"merge2": "merge2 content"
}]
}],
If you like it, feel free to use it or clone it:
https://bitbucket.org/mraxus/mandrill-api-node/src
Cheers!

Resources