Decoding Nested JSON Elements (SwiftUI) - decode

I am trying to parse the JSON data below into the structs that are shown. I am having a helluva time trying to figure out how to get at the "nested" elements, such as elements "title:", "content:", and "excerpt:". Whenever the code runs, it barfs while parsing the nested elements.
I've looked at the Apple Developer stuff and reviewed the Playground here: https://developer.apple.com/documentation/foundation/archives_and_serialization/using_json_with_custom_types
I also tried using quicktype.io to create the data models from the sample JSON, however, in the header of the exported file from quicktype it has the line: "let blogItem = try? newJSONDecoder().decode(BlogItem.self, from: jsonData)", however, I get a compile error that jsonData is not recognized and I'm not able to find any reference to it.
struct BlogSection: Codable, Identifiable {
var id: Int
var slug: String
var link: String
var title: [BlogTitle]
var content: [ContentData]
}
struct BlogTitle: Codable, Equatable, Identifiable {
var id: UUID
var rendered: String
}
struct ContentData: Codable, Identifiable{
var id: UUID
var rendered: String
}
/**************** JSON Data ***************/
[
{
"id": 10960,
"date": "2019-10-02T01:00:07",
"date_gmt": "2019-10-02T05:00:07",
"guid": {
"rendered": "example.com/blog-template-copy-copy/"
},
"modified": "2019-09-20T07:08:41",
"modified_gmt": "2019-09-20T11:08:41",
"slug": "relationships-matter",
"status": "publish",
"type": "post",
"link": "example.com/relationships-matter/",
"title": {
"rendered": "Relationships Matter"
},
"content": {
"rendered": "<h1>Page content</h1>",
"protected": false
},
"excerpt": {
"rendered": "<p>By: Joe Schmoe<br />\nFirst Author",
"protected": false
},
"author": 57,
"featured_media": 10958,
"comment_status": "open",
"ping_status": "open",
"sticky": false,
"template": "",
"format": "standard",
"meta": [],
"categories": [
613
],
"tags": [],
"_links": {
"self": [
{
"href": "example.com/wp-json/wp/v2/posts/10960"
}
],
"collection": [
{
"href": "example.com/wp-json/wp/v2/posts"
}
],
"about": [
{
"href": "example.com/wp-json/wp/v2/types/post"
}
],
"author": [
{
"embeddable": true,
"href": "example.com/wp-json/wp/v2/users/57"
}
],
"replies": [
{
"embeddable": true,
"href": "example.com/wp-json/wp/v2/comments?post=10960"
}
],
"version-history": [
{
"count": 5,
"href": "example.com/wp-json/wp/v2/posts/10960/revisions"
}
],
"predecessor-version": [
{
"id": 10971,
"href": "example.com/wp-json/wp/v2/posts/10960/revisions/10971"
}
],
"wp:featuredmedia": [
{
"embeddable": true,
"href": "example.com/wp-json/wp/v2/media/10958"
}
],
"wp:attachment": [
{
"href": "example.com/wp-json/wp/v2/media?parent=10960"
}
],
"wp:term": [
{
"taxonomy": "category",
"embeddable": true,
"href": "example.com/wp-json/wp/v2/categories?post=10960"
},
{
"taxonomy": "post_tag",
"embeddable": true,
"href": "example.com/wp-json/wp/v2/tags?post=10960"
}
],
"curies": [
{
"name": "wp",
"href": "https://api.w.org/{rel}",
"templated": true
}
]
}
}
]
'

In the JSON you do not have arrays for title and content, so just remove the brackets
struct BlogSection: Codable, Identifiable {
var id: Int
var slug: String
var link: String
var title: BlogTitle
var content: ContentData
}
struct BlogTitle: Codable, Equatable, Identifiable {
var id: UUID
var rendered: String
}
struct ContentData: Codable, Identifiable{
var id: UUID
var rendered: String
}

Title and Content are not Arrays in the json provided so should be declared as entities. Your BlogTitle and ContentData are declared as Identifiable and have a variable for id, but both do not have an id in the json provided, so you will get a decoding error because of that as well.
The error you are getting points to a completely different problem though. How is your jsonData declared?

Related

Why are my posts content not showing on my admin dashboard?

I have added an application to my WordPress site with a plug in that am using to automatically add posts with a python scripts. My API is working just fine even after testing on postman.
However the post Meta Desc and Key Phrase columns don't show anything as in a post added manually. (See screenshot; the first post is the one added via an api). I will appreciate any idea as to why this is.
post = {
'title': question_title,
'status': 'publish',
"content": question,
"type": "post",
"categories": [2],
"focus_keyphrase": question_title,
}
gradeboosts_url = "https://gradeboosts.com/wp-json/wp/v2"
user = 'aloy'
password = '****************'
creds = user + ':' + password
token = base64.b64encode(creds.encode())
headers = {'Authorization': 'Basic ' + token.decode('utf-8')}
r = requests.post(gradeboosts_url + '/posts', json=post, headers=headers)
A full postman get request that is displaying all columns on wordpress:
response = {
"id": 1692997,
"date": "2021-08-13T12:43:38",
"date_gmt": "2021-08-13T12:43:38",
"guid": {
"rendered": "https://gradeboosts.com/health-sciences-homework-help-3/"
},
"modified": "2021-08-13T12:43:38",
"modified_gmt": "2021-08-13T12:43:38",
"slug": "health-sciences-homework-help-3",
"status": "publish",
"type": "post",
"link": "https://gradeboosts.com/health-sciences-homework-help-3/",
"title": {
"rendered": "Health Sciences homework help"
},
"content": {
"rendered": "<p>Health Sciences homework help. An ion is an atom that has gained or lost one or more electrons.</p>\n<p> I don’t think that this is maths, but more chemistry.<br />\nAn ion is an atom that has a charge due to a lost or gain of electrons. Usually, ions occur when the atom tries to get a full outershell, either by losing electrons (and thus gaining a positive charge) or by gaining electrons (and thus getting a negative charge).</p>\n<p>Health Sciences homework help</p>\n",
"protected": false
},
"excerpt": {
"rendered": "<p>What’s an ion?</p>\n",
"protected": false
},
"author": 2,
"featured_media": 0,
"comment_status": "open",
"ping_status": "open",
"sticky": false,
"template": "",
"format": "standard",
"meta": {
"spay_email": ""
},
"categories": [],
"tags": [],
"yst_prominent_words": [],
"jetpack_featured_media_url": "",
"_links": {
"self": [
{
"href": "https://gradeboosts.com/wp-json/wp/v2/posts/1692997"
}
],
"collection": [
{
"href": "https://gradeboosts.com/wp-json/wp/v2/posts"
}
],
"about": [
{
"href": "https://gradeboosts.com/wp-json/wp/v2/types/post"
}
],
"author": [
{
"embeddable": true,
"href": "https://gradeboosts.com/wp-json/wp/v2/users/2"
}
],
"replies": [
{
"embeddable": true,
"href": "https://gradeboosts.com/wp-json/wp/v2/comments?post=1692997"
}
],
"version-history": [
{
"count": 190,
"href": "https://gradeboosts.com/wp-json/wp/v2/posts/1692997/revisions"
}
],
"predecessor-version": [
{
"id": 1698135,
"href": "https://gradeboosts.com/wp-json/wp/v2/posts/1692997/revisions/1698135"
}
],
"wp:attachment": [
{
"href": "https://gradeboosts.com/wp-json/wp/v2/media?parent=1692997"
}
],
"wp:term": [
{
"taxonomy": "category",
"embeddable": true,
"href": "https://gradeboosts.com/wp-json/wp/v2/categories?post=1692997"
},
{
"taxonomy": "post_tag",
"embeddable": true,
"href": "https://gradeboosts.com/wp-json/wp/v2/tags?post=1692997"
},
{
"taxonomy": "yst_prominent_words",
"embeddable": true,
"href": "https://gradeboosts.com/wp-json/wp/v2/yst_prominent_words?post=1692997"
}
],
"curies": [
{
"name": "wp",
"href": "https://api.w.org/{rel}",
"templated": true
}
]
}
}

How to get the register device name from OKTA API

I have a requirement to display the OKTA register device name on the screen like the OKTA does for you.
In the picture above it display (Pixel 2 XL) where is the OKTA API to get the register device name
I am referring to OKTA dev API but didn't found anywhere
https://developer.okta.com/docs/reference/api/factors/
Any idea where can I find ???
Once you have the userid you can call the factors list API to get the enrolled MFA factors for the user.
Which will get you back a body like:
[
{
"id": "opffxq5v54xO5kdsa0x6",
"factorType": "push",
"provider": "OKTA",
"vendorName": "OKTA",
"status": "ACTIVE",
"created": "2020-05-07T20:49:49.000Z",
"lastUpdated": "2020-05-20T13:33:58.000Z",
"profile": {
"credentialId": "test#test.com",
"deviceType": "SmartPhone_Android",
"keys": [
{
"kty": "RSA",
"use": "sig",
"kid": "default",
"e": "AQAB",
"n": "j_rlzlG07lZy_TegQPjllleeaGxxDsrtFNaoQHhDowV1z54okXdDobyJo5B9rcCkP7-i0EniNdaCFDj8xugG7WSmcDRzr46AujT7nFVPI5Z7EZE9IaLdYLP0Hg0nRaC3qhHPdv8JGszle8t0Fej1eR-AqT1mrsNUM3-k44_Axj47xhAkIPoxCjyvvA8W1FWKQbECe_y-HtlcLksJlW03WDt_bCdKwx2uVqca1yiEIF3HwhHtpK1dfwosjyEvfpTtsUWtKJVsJiksLajDhu9dGN3JcOT9unsLbWcyWc-kfQ9_oiaMikZCvtbONGSgVjtBttc95-8CHMw-tpA4HCRlcw"
}
],
"name": "Pixel 4 XL",
"platform": "ANDROID",
"version": "29"
},
"_links": {
"self": {
"href": "https://<yourtenant>.oktapreview.com/api/v1/users/00u9ivp5ft7EHNTRW0x6/factors/opffxq5v54xO5kdsa0x6",
"hints": {
"allow": [
"GET",
"DELETE"
]
}
},
"verify": {
"href": "https://<yourtenant>.oktapreview.com/api/v1/users/00u9ivp5ft7EHNTRW0x6/factors/opffxq5v54xO5kdsa0x6/verify",
"hints": {
"allow": [
"POST"
]
}
},
"user": {
"href": "https://<yourtenant>.oktapreview.com/api/v1/users/00u9ivp5ft7EHNTRW0x6",
"hints": {
"allow": [
"GET"
]
}
}
}
},
{
"id": "ostgppjgvFiLfBv850x6",
"factorType": "token:software:totp",
"provider": "OKTA",
"vendorName": "OKTA",
"status": "ACTIVE",
"created": "2020-05-20T13:33:58.000Z",
"lastUpdated": "2020-05-20T13:33:58.000Z",
"profile": {
"credentialId": "test#test.com"
},
"_links": {
"self": {
"href": "https://<yourtenant>.oktapreview.com/api/v1/users/00u9ivp5ft7EHNTRW0x6/factors/ostgppjgvFiLfBv850x6",
"hints": {
"allow": [
"GET",
"DELETE"
]
}
},
"verify": {
"href": "https://<yourtenant>.oktapreview.com/api/v1/users/00u9ivp5ft7EHNTRW0x6/factors/ostgppjgvFiLfBv850x6/verify",
"hints": {
"allow": [
"POST"
]
}
},
"user": {
"href": "https://<yourtenant>.oktapreview.com/api/v1/users/00u9ivp5ft7EHNTRW0x6",
"hints": {
"allow": [
"GET"
]
}
}
}
}
]
The device information is shown under the factorProfile (profile.name) which is documented here but doesn't show an example of push.

Is there any way we can only validate field name not value in Pact json

The example below is the response. In this I just want to validate field not field value from the body.
When I do pact verify:
{
"provider": {
"name": "provider"
},
"consumer": {
"name": "consumer"
},
"interactions": [
{
"description": "A valid data read request",
"request": {
"method": "GET",
"path": "/v1/users",
"query": {
"user": [
"1"
]
}
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json"
},
"body": {
"name": "xyz",
"work": "gen",
"age": "29",
}
},
"providerStates": [
{
"name": "user exists state"
}
]
}
],
"metadata": {
"pactSpecification": {
"version": "3.0.0"
},
"pact-jvm": {
"version": "4.0.4"
}
}
}
Only i need to validate field such as name, age and work not field value.
got solution we can achieve this using
final DslPart body = new PactDslJsonBody()
.stringType("name", "xyz")
.stringType("work", "gen")
.integerType("age", 29)
or for only optional
DslPart body = new PactDslJsonBody()
.eachKeyLike("name", PactDslJsonRootValue.stringType("xyz"))
.eachKeyLike("work", PactDslJsonRootValue.stringType("gen"))
.eachKeyLike("age", PactDslJsonRootValue.integerType(29))
.asBody()
and set this body to PactDslWithProvider body and we can have matching rule generated in the json so that when we verify only the field type and field name

Actions-on-Google can not get UPDATES_USER_ID on Dialogflow SDK

I'm setting up an action which uses push notifications. Yet, on firebase I can't get "UPDATES_USER_ID" of user to save. It returns "undefined".
I followed the guide on this link and here is my code to get UPDATES_USER_ID.
app.intent('Setup', (conv, params) => {
conv.ask(new UpdatePermission({
intent: "notificationResponseIntent"
}));
});
app.intent("FinishNotificationSetup", (conv, params) => {
if (conv.arguments.get('PERMISSION')) {
conv.data.GoogleUserID = conv.arguments.get("UPDATES_USER_ID");
console.log(conv.data.GoogleUserID);
conv.ask("some response....");
}
});
And here is my webhook request when FinishNotificationSetup intent is invoked.
{
"responseId": "2f425fe5-db42-47dc-90a1-c9bc85f725d2",
"queryResult": {
"queryText": "actions_intent_PERMISSION",
"parameters": {},
"allRequiredParamsPresent": true,
"fulfillmentMessages": [
{
"text": {
"text": [
""
]
}
}
],
"outputContexts": [
{
"name": "projects/projectname/agent/sessions/ABwppHGD33Tyho41g9Mr2vzxePlskNmvOzCTxUiDGzENcl3C7RQs94aOQ8ae_DUlOApR0VBO9DuwAWdWr2frAA/contexts/actions_capability_screen_output"
},
{
"name": "projects/projectname-10c22/agent/sessions/ABwppHGD33Tyho41g9Mr2vzxePlskNmvOzCTxUiDGzENcl3C7RQs94aOQ8ae_DUlOApR0VBO9DuwAWdWr2frAA/contexts/actions_intent_permission",
"parameters": {
"PERMISSION": true,
"text": ""
}
},
{
"name": "projects/projectname-10c22/agent/sessions/ABwppHGD33Tyho41g9Mr2vzxePlskNmvOzCTxUiDGzENcl3C7RQs94aOQ8ae_DUlOApR0VBO9DuwAWdWr2frAA/contexts/_actions_on_google",
"lifespanCount": 98,
"parameters": {
"data": "{\"***":\"***",\"***":\"***"}"
}
},
{
"name": "projects/projectname-10c22/agent/sessions/ABwppHGD33Tyho41g9Mr2vzxePlskNmvOzCTxUiDGzENcl3C7RQs94aOQ8ae_DUlOApR0VBO9DuwAWdWr2frAA/contexts/actions_capability_account_linking"
},
{
"name": "projects/projectname-10c22/agent/sessions/ABwppHGD33Tyho41g9Mr2vzxePlskNmvOzCTxUiDGzENcl3C7RQs94aOQ8ae_DUlOApR0VBO9DuwAWdWr2frAA/contexts/actions_capability_audio_output"
},
{
"name": "projects/projectname-10c22/agent/sessions/ABwppHGD33Tyho41g9Mr2vzxePlskNmvOzCTxUiDGzENcl3C7RQs94aOQ8ae_DUlOApR0VBO9DuwAWdWr2frAA/contexts/google_assistant_input_type_keyboard"
},
{
"name": "projects/projectname-10c22/agent/sessions/ABwppHGD33Tyho41g9Mr2vzxePlskNmvOzCTxUiDGzENcl3C7RQs94aOQ8ae_DUlOApR0VBO9DuwAWdWr2frAA/contexts/actions_capability_web_browser"
},
{
"name": "projects/projectname-10c22/agent/sessions/ABwppHGD33Tyho41g9Mr2vzxePlskNmvOzCTxUiDGzENcl3C7RQs94aOQ8ae_DUlOApR0VBO9DuwAWdWr2frAA/contexts/actions_capability_media_response_audio"
}
],
"intent": {
"name": "projects/projectname-10c22/agent/intents/a12b6d3f-0f24-45e9-a1b2-5649083831b0",
"displayName": "FinishNotificationSetup"
},
"intentDetectionConfidence": 1,
"languageCode": "tr"
},
"originalDetectIntentRequest": {
"source": "google",
"version": "2",
"payload": {
"isInSandbox": true,
"surface": {
"capabilities": [
{
"name": "actions.capability.SCREEN_OUTPUT"
},
{
"name": "actions.capability.WEB_BROWSER"
},
{
"name": "actions.capability.ACCOUNT_LINKING"
},
{
"name": "actions.capability.MEDIA_RESPONSE_AUDIO"
},
{
"name": "actions.capability.AUDIO_OUTPUT"
}
]
},
"requestType": "SIMULATOR",
"inputs": [
{
"rawInputs": [
{
"inputType": "KEYBOARD"
}
],
"arguments": [
{
"textValue": "true",
"name": "PERMISSION",
"boolValue": true
},
{
"name": "text"
}
],
"intent": "actions.intent.PERMISSION"
}
],
"user": {
"lastSeen": "2019-04-30T07:23:23Z",
"permissions": [
"UPDATE"
],
"locale": "tr-TR",
"userId": "ABwppHHCEdtf23ZaNg0DaCv3fvshSUXUvYGXHe6kR7jbKacwIS6vDBBL7YXbN70jYa8KaXWZqbsyhFFSdsYLiw"
},
"conversation": {
"conversationId": "ABwppHGD33Tyho41g9Mr2vzxePlskNmvOzCTxUiDGzENcl3C7RQs94aOQ8ae_DUlOApR0VBO9DuwAWdWr2frAA",
"type": "ACTIVE",
"conversationToken": "[\"_actions_on_google\"]"
},
"availableSurfaces": [
{
"capabilities": [
{
"name": "actions.capability.AUDIO_OUTPUT"
},
{
"name": "actions.capability.SCREEN_OUTPUT"
},
{
"name": "actions.capability.WEB_BROWSER"
}
]
}
]
}
},
"session": "projects/projectname-10c22/agent/sessions/ABwppHGD33Tyho41g9Mr2vzxePlskNmvOzCTxUiDGzENcl3C7RQs94aOQ8ae_DUlOApR0VBO9DuwAWdWr2frAA"
}
To send notification, I've been using userID instead of UPDATES_USER_ID and it is working. Yet, it will be deprecated soon. So, I need to find a solution to get this ID and couldn't make it working. What do I need to do to get this ID?
I've found solution for this problem. While getting UPDATES_USER_ID conv.arguments.get() only works for first attempt. So, while building your action you must save it. If you didn't store or save, you can reset your profile and try again, you will be able to get.
app.intent("FinishNotificationSetup", (conv, params) => {
if (conv.arguments.get('PERMISSION')) {
if(!conv.user.storage.GoogleUserID)
{
conv.user.storage.GoogleUserID = conv.arguments.get("UPDATES_USER_ID");
//For best case
//store ID in your db.
}
console.log(conv.user.storage.GoogleUserID);
conv.ask("some response....");
}
});
For best case, try saving this to your database because conv.user.storage does not work sometimes.

Using Pact.eachLike() when array contents vary for each item

Hi I have a Consumer test produced using Pact NPM https://www.npmjs.com/package/pact
I use the following code to generate a pact.json:
provider
.addInteraction({
state: 'test',
uponReceiving: 'a test,
withRequest: {
method: 'GET',
path: '/test'
},
willRespondWith: {
status: 200,
headers: { 'Content-Type': 'application/json' }
body: {
"company": like("My big company"),
"factories": eachLike({
"location": like("Sydney"),
"capacity": like(5)
},{min:1})
}
}
})
.then(function(){ done(); });
It generates the following testconsumer-testprovider.json file:
{
"consumer": {
"name": "TestConsumer"
},
"provider": {
"name": "TestProvider"
},
"interactions": [
{
"description": "a request for loans",
"providerState": "broker is logged in, list all loans",
"request": {
"method": "GET",
"path": "/test"
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/vnd.hal+json"
},
"body": {
"company": "My big company",
"factories": [
{
"location": "Sydney",
"capacity": 5
}
]
},
"matchingRules": {
"$.headers.Content-Type": {
"match": "regex",
"regex": "application\\/.*json.*"
},
"$.body.company": {
"match": "type"
},
"$.body.factories": {
"min": 1
},
"$.body.factories[*].*": {
"match": "type"
},
"$.body.factories[*].location": {
"match": "type"
},
"$.body.factories[*].capacity": {
"match": "type"
}
}
}
}
],
"metadata": {
"pactSpecification": {
"version": "3.0.0"
}
}
}
However when we test against the following provided output we get an error with the geographicCoords because it's an unexpected key/value:
{
"company": "My Company",
"factories": [
{
"location": "Sydney",
"capacity": 5
},
{
"location": "Sydney",
"geographicCoords": "-0.145,1.4445",
"capacity": 5,
}
]
}
So is there a was to allow unexpected key/values in arrays because we're only test for required key/values and we don't want out pact tests to fail in future when new values are added to our providers.
The scenario you are describing is supported, see https://github.com/pact-foundation/pact-js/tree/master/examples/e2e for an example.
If you were to remove, say the eligibility object and run the tests everything still works.
If you are still having troubles, please raise a defect on the pact-js repository and we'll get to the bottom of it.

Resources