Pulling JSON data with a 3rd party library swift 4 - json

I am using a 3rd party GitHub library in my Xcode folder. Its giving me access to Yelps API where i would like to get search results within my app. I am successfully downloading converting the data into a JSON string.
But i'm stuck on the logic of Decoding the JSON string so that i can access the actual parameters, such as name, display_address and price. I have use "Decode" before, but never through a 3rd party library. I'm sure its possible and i'm probably just a step or two steps away, but my inexperience is impeding that right now. Any help. Thank you
Here is my function to get the JSON data and below is the response i get
func getYelp() {
let yelpAPIClient = CDYelpAPIClient(apiKey: "MY_API_KEY")
yelpAPIClient.cancelAllPendingAPIRequests()
CDYelpFusionKitManager.shared.apiClient = yelpAPIClient
CDYelpFusionKitManager.shared.apiClient.searchBusinesses(byTerm: "Bars",
location: "Hollywood, California",
latitude: nil,
longitude: nil,
radius: 10000,
categories: [CDYelpBusinessCategoryFilter.bars],
locale: CDYelpLocale.english_unitedStates,
limit: 5,
offset: 0,
sortBy: CDYelpBusinessSortType.distance,
priceTiers: [CDYelpPriceTier.twoDollarSigns],
openNow: true,
openAt: nil,
attributes: nil) { (response) in
if let response = response,
let businesses = response.businesses?.toJSONString(),
businesses.count > 0 {
print(businesses)
}
}
}
Here's the data:
[
{
"name" : "The Know Where Bar",
"coordinates" : {
"latitude" : 34.101480000000002,
"longitude" : -118.3127424
},
"rating" : 4.5,
"price" : "$$",
"review_count" : 170,
"display_phone" : "(323) 871-4108",
"location" : {
"state" : "CA",
"address3" : "",
"address1" : "5634 Hollywood Blvd",
"city" : "Los Angeles",
"display_address" : [
"5634 Hollywood Blvd",
"Los Angeles, CA 90028"
],
"zip_code" : "90028",
"country" : "US"
},
"id" : "KOj4TvBuvRLXlBuG2vrZeQ",
"categories" : [
{
"title" : "Cocktail Bars",
"alias" : "cocktailbars"
},
{
"title" : "Jazz & Blues",
"alias" : "jazzandblues"
},
{
"title" : "Pubs",
"alias" : "pubs"
}
],
"transactions" : [
],
"distance" : 2232.7094070718849,
"phone" : "+13238714108",
"image_url" : "https:\/\/s3-media3.fl.yelpcdn.com\/bphoto\/Ehus0C-bAoA-6fNbwGpSYA\/o.jpg",
"is_closed" : false,
"url" : "https:\/\/www.yelp.com\/biz\/the-know-where-bar-los-angeles?adjust_creative=xVfmfDi4k3F3Jm9zaJU1CA&utm_campaign=yelp_api_v3&utm_medium=api_v3_business_search&utm_source=xVfmfDi4k3F3Jm9zaJU1CA"
},
{
"name" : "Lost Property Bar",
"coordinates" : {
"latitude" : 34.1019182,
"longitude" : -118.32650390000001
},
"rating" : 4.5,
"price" : "$$",
"review_count" : 143,
"display_phone" : "(323) 987-4445",
"location" : {
"state" : "CA",
"address3" : "",
"address1" : "1704 N Vine St",
"city" : "Hollywood",
"address2" : "",
"display_address" : [
"1704 N Vine St",
"Hollywood, CA 90028"
],
"zip_code" : "90028",
"country" : "US"
},
"id" : "CBYwPYYEFbpCefJ4rdiyPw",
"categories" : [
{
"title" : "Pubs",
"alias" : "pubs"
},
{
"title" : "Cocktail Bars",
"alias" : "cocktailbars"
}
],
"transactions" : [
],
"distance" : 1145.5564586880064,
"phone" : "+13239874445",
"image_url" : "https:\/\/s3-media1.fl.yelpcdn.com\/bphoto\/pswDPAX_3p73JbPEXwThag\/o.jpg",
"is_closed" : false,
"url" : "https:\/\/www.yelp.com\/biz\/lost-property-bar-hollywood?adjust_creative=xVfmfDi4k3F3Jm9zaJU1CA&utm_campaign=yelp_api_v3&utm_medium=api_v3_business_search&utm_source=xVfmfDi4k3F3Jm9zaJU1CA"
},
{
"name" : "Sunset & Vinyl",
"coordinates" : {
"latitude" : 34.098346200000002,
"longitude" : -118.32679779999999
},
"rating" : 4.5,
"price" : "$$",
"review_count" : 42,
"display_phone" : "(424) 646-3375",
"location" : {
"state" : "CA",
"city" : "Los Angeles",
"address1" : "1521 Vine St",
"address2" : "",
"display_address" : [
"1521 Vine St",
"Los Angeles, CA 90028"
],
"zip_code" : "90028",
"country" : "US"
},
"id" : "RKSPAI90ITxbnq1-L_F5NA",
"categories" : [
{
"title" : "Cocktail Bars",
"alias" : "cocktailbars"
},
{
"title" : "Speakeasies",
"alias" : "speakeasies"
},
{
"title" : "Lounges",
"alias" : "lounges"
}
],
"transactions" : [
],
"distance" : 916.67964443671087,
"phone" : "+14246463375",
"image_url" : "https:\/\/s3-media3.fl.yelpcdn.com\/bphoto\/w91DLpKmUGuXTF-zauYAWA\/o.jpg",
"is_closed" : false,
"url" : "https:\/\/www.yelp.com\/biz\/sunset-and-vinyl-los-angeles?adjust_creative=xVfmfDi4k3F3Jm9zaJU1CA&utm_campaign=yelp_api_v3&utm_medium=api_v3_business_search&utm_source=xVfmfDi4k3F3Jm9zaJU1CA"
},
{
"name" : "A Simple Bar",
"coordinates" : {
"latitude" : 34.129899999999999,
"longitude" : -118.34882
},
"rating" : 5,
"price" : "$$",
"review_count" : 168,
"display_phone" : "(323) 378-5388",
"location" : {
"state" : "CA",
"address3" : "",
"address1" : "3256 Cahuenga Blvd W",
"city" : "Los Angeles",
"display_address" : [
"3256 Cahuenga Blvd W",
"Los Angeles, CA 90068"
],
"zip_code" : "90068",
"country" : "US"
},
"id" : "qD3-5yqSyPiz-VpJtPsnkg",
"categories" : [
{
"title" : "Bars",
"alias" : "bars"
}
],
"transactions" : [
],
"distance" : 4136.336282884502,
"phone" : "+13233785388",
"image_url" : "https:\/\/s3-media2.fl.yelpcdn.com\/bphoto\/JYcRYDteiyjLh3dSAj7fCg\/o.jpg",
"is_closed" : false,
"url" : "https:\/\/www.yelp.com\/biz\/a-simple-bar-los-angeles?adjust_creative=xVfmfDi4k3F3Jm9zaJU1CA&utm_campaign=yelp_api_v3&utm_medium=api_v3_business_search&utm_source=xVfmfDi4k3F3Jm9zaJU1CA"
},
{
"name" : "The Woods",
"coordinates" : {
"latitude" : 34.098860000000002,
"longitude" : -118.34478
},
"rating" : 4,
"price" : "$$",
"review_count" : 456,
"display_phone" : "(323) 876-6612",
"location" : {
"state" : "CA",
"address3" : "",
"address1" : "1533 N La Brea Ave",
"city" : "Hollywood",
"address2" : "",
"display_address" : [
"1533 N La Brea Ave",
"Hollywood, CA 90028"
],
"zip_code" : "90028",
"country" : "US"
},
"id" : "UEim6Xi_sm78yDUpSfI-OQ",
"categories" : [
{
"title" : "Lounges",
"alias" : "lounges"
}
],
"transactions" : [
],
"distance" : 968.92997694605617,
"phone" : "+13238766612",
"image_url" : "https:\/\/s3-media3.fl.yelpcdn.com\/bphoto\/wUQYIlojm2d41ZL38zDMgg\/o.jpg",
"is_closed" : false,
"url" : "https:\/\/www.yelp.com\/biz\/the-woods-hollywood?adjust_creative=xVfmfDi4k3F3Jm9zaJU1CA&utm_campaign=yelp_api_v3&utm_medium=api_v3_business_search&utm_source=xVfmfDi4k3F3Jm9zaJU1CA"
}
]

The 3rd party library already does all the decoding for you. Don't convert the response back to a JSON string.
response.businesses is an array of CDYelpBusiness objects, which are defined like this:
public var id: String?
public var name: String?
public var imageUrl: URL?
public var isClosed: Bool?
public var url: URL?
public var price: String?
public var phone: String?
public var displayPhone: String?
public var photos: [String]?
public var hours: [CDYelpHour]?
public var rating: Double?
public var reviewCount: Int?
public var categories: [CDYelpCategory]?
public var distance: Double?
public var coordinates: CDYelpCoordinates?
public var location: CDYelpLocation?
public var transactions: [String]?
Try iterating over them and accessing their properties like this:
for business in response.businesses {
print(business.name)
}

Related

How to parse data from large json in Jmeter with Regular expresion or json path extractor

I have the following JSON body. How can I parse it to get the values of StudentId, TermID, etc.?
JSON body:
[ { "Key" : "Results", "ResultsCollection" : [ { "Key" : "IS.S2.SES.FSA.LoadStudentProfile(%27%2751483081%27%27,%20%27%27HCOL%27%27,%27%27JC%27%27,%27%270%27%27)", "Name" : "Josh Josephy-Zack", "LinkURL" : "IS.S2.SES.FSA.LoadStudentProfile(%27%2751483081%27%27,%20%27%27HCOL%27%27,%27%27JC%27%27,%27%270%27%27)", "Title" : "Josh Josephy-Zack", "EnhancedSponsored" : false, "OriginalURL" : "IS.S2.SES.FSA.LoadStudentProfile(%27%2751483081%27%27,%20%27%27HCOL%27%27,%27%27JC%27%27,%27%270%27%27)", "HasActions" : false, "IsPeoplesoft" : false, "SearchKey" : "h0tlbi9WGlr1hZs1AEEhVhF7qlY=", "Sponsored" : false, "Removed" : false, "Description" : "51483081HCOLJC", "Score" : 1, "Modified" : "2022-08-28 22:59:02.000000", "ACAD_CAREER" : "HCOL", "ACAD_PROG" : "JC", "STDNT_CAR_NBR" : "0", "FIRST_NAME" : "Josh", "LAST_NAME" : "Josephy-Zack", "IS_FSA_DESCR_IS_FSA_ACAD_PROG" : "JC", "NAME_DISPLAY" : "Josh Josephy-Zack", "ACAD_LEVEL_BOT" : "30", "IS_FSA_DESCR100_IS_FSA_ACAD_LEVEL" : "Junior", "EMPLID" : "51483081", "IS_SCL_DESCR_IS_SCL_DESCRI" : "Harvard College", "IS_FSA_DESCR_IS_FSA_ACAD_PLAN" : [ "Physics", "Mathematics" ], "PHONE" : "203/645-7134", "ACAD_PROG_DUAL" : "", "EMAIL_ADDR" : [ "test.jjosephyzack-college.harvard.edu#harvard.edu", "test.joshuajosephyzack-gmail.com#harvard.edu" ], "PRIVACY_FLG" : "Y", "FERPA" : "N", "IS_FSA_DESCR100_IS_FSA_ACAD_PROG" : "Joint Concentration", "IS_FSA_DESCR_IS_FSA_HOUSE" : "Quincy House", "IS_FSA_DESCR_HU_FSA_STATUS" : "Enrollment", "IS_SCL_DESCR_IS_SCL_DESCRM" : [ "Physics", "Mathematics" ], "HU_HASH_EMPLID" : "5evPzmXFIpLp8zdDtt5NGTgtAq6VKtbqp09S6SIivMY6", "HU_HASH_FOLDER" : "nZ2DnkQ3gccBTtKpE8MAxU7gabJ4cGdh9O9b7Ow7F846", "IS_FSA_DESCR_HU_FSA_PLN_DPT_DSP" : [ "Physics", "Mathematics" ], "HU_EMPLID_CAREER" : "51483081HCOL", "IS_FSA_PHOTO" : "/Photos/nZ2DnkQ3gccBTtKpE8MAxU7gabJ4cGdh9O9b7Ow7F846/5evPzmXFIpLp8zdDtt5NGTgtAq6VKtbqp09S6SIivMY6.png?ver=764077" }, { "Key" : "IS.S2.SES.FSA.LoadStudentProfile(%27%2791403870%27%27,%20%27%27HCOL%27%27,%27%27JC%27%27,%27%270%27%27)", "Name" : "Kiran Linsuain", "LinkURL" : "IS.S2.SES.FSA.LoadStudentProfile(%27%2791403870%27%27,%20%27%27HCOL%27%27,%27%27JC%27%27,%27%270%27%27)", "Title" : "Kiran Linsuain", "EnhancedSponsored" : false, "OriginalURL" : "IS.S2.SES.FSA.LoadStudentProfile(%27%2791403870%27%27,%20%27%27HCOL%27%27,%27%27JC%27%27,%27%270%27%27)", "HasActions" : false, "IsPeoplesoft" : false, "SearchKey" : "HASgm6RyJebfxiEYSivPt7MM_og=", "Sponsored" : false, "Removed" : false, "Description" : "91403870HCOLJC", "Score" : 1, "Modified" : "2022-08-28 23:47:55.000000", "ACAD_CAREER" : "HCOL", "ACAD_PROG" : "JC", "STDNT_CAR_NBR" : "0", "FIRST_NAME" : "Kiran", "LAST_NAME" : "Linsuain", "IS_FSA_DESCR_IS_FSA_ACAD_PROG" : "JC", "NAME_DISPLAY" : "Kiran Linsuain", "ACAD_LEVEL_BOT" : "30", "IS_FSA_DESCR100_IS_FSA_ACAD_LEVEL" : "Junior", "EMPLID" : "91403870", "IS_SCL_DESCR_IS_SCL_DESCRI" : "Harvard College", "IS_FSA_DESCR_IS_FSA_ACAD_PLAN" : [ "Physics", "Mathematics" ], "PHONE" : "412/926-8923", "ACAD_PROG_DUAL" : "", "EMAIL_ADDR" : [ "test.kiranlinsuain-college.harvard.edu#harvard.edu", "test.kiranlinsuain-gmail.com#harvard.edu" ], "PRIVACY_FLG" : "Y", "FERPA" : "N", "IS_FSA_DESCR100_IS_FSA_ACAD_PROG" : "Joint Concentration", "IS_FSA_DESCR_IS_FSA_HOUSE" : "Leverett House", "IS_FSA_DESCR_HU_FSA_STATUS" : "Enrollment", "IS_SCL_DESCR_IS_SCL_DESCRM" : [ "Physics", "Mathematics" ], "HU_HASH_EMPLID" : "2DPDP7mU8eTwDHduaUwQquBIlSlscOFKr1PraqxInuo6", "HU_HASH_FOLDER" : "SIw3HxekiSltVLRlQ9wDhJpkGdzXP1PBHG3XVbBHnXc6", "IS_FSA_DESCR_HU_FSA_PLN_DPT_DSP" : [ "Physics", "Mathematics" ], "HU_EMPLID_CAREER" : "91403870HCOL", "IS_FSA_PHOTO" : "/Photos/SIw3HxekiSltVLRlQ9wDhJpkGdzXP1PBHG3XVbBHnXc6/2DPDP7mU8eTwDHduaUwQquBIlSlscOFKr1PraqxInuo6.png?ver=749905" } ] }, { "Key" : "Facets", "Facets" : [ ] }, { "Key" : "SearchProperties", "HitCount" : 2, "DocumentCount" : 2, "PageSize" : 999, "PageNumber" : 1, "TotalPages" : 1, "ResultStart" : 1, "ResultEnd" : 2, "SearchText" : "", "SearchQuery" : "", "SearchTextOriginal" : "(HU_EMPLID_CAREER:51483081HCOL | HU_EMPLID_CAREER:91403870HCOL)", "BoostEnabled" : false, "BoostMode" : "", "BoostScoreMode" : "", "BoostExcludeNonBoosted" : "" }, { "Key" : "SignerInfo", "Signers" : [ { "Key" : "51483081", "StudentID" : "51483081", "Srvindreseaon" : "HCOL", "Srvsindicator" : "H01", "SrvcIndDttm" : "2022-08-07 23:03:55.000000", "SignerName" : "Arthur Jaffe", "AuditAction" : "D", "AuditDttm" : "2022-08-25 06:47:05.609115", "IsPrimary" : "Y", "HasComments" : "N", "Denied" : "N" }, { "Key" : "91403870", "StudentID" : "91403870", "Srvindreseaon" : "HCOL", "Srvsindicator" : "H01", "SrvcIndDttm" : "2022-08-07 23:03:46.000000", "SignerName" : "Arthur Jaffe", "AuditAction" : "D", "AuditDttm" : "2022-08-25 09:12:24.620026", "IsPrimary" : "Y", "HasComments" : "N", "Denied" : "N" } ], "TermID" : "2232", "TermDescr" : "2023 Spring", "TermDescrshort" : "2023 Spr" } ]
Using JSON Extractor:
StudentId:
$..Signers[0].StudentID
TermID:
$..TermID
Configuration would be:

How to Parse JSON object in SWIFT properly

I have tried to parse this JSON object but it's not working.. I'm not getting an error message either.
What I'm trying to do is fetch recipe details from an API to an array but I'm unable to make it work. I can see from the console that the API call has been successful and able to print the json file.
See below the json file, object class & the parse code.
Json file
{
"recipes" : [
{
"veryHealthy" : false,
"preparationMinutes" : 20,
"vegan" : false,
"aggregateLikes" : 8,
"veryPopular" : false,
"imageType" : "jpg",
"diets" : [
"lacto ovo vegetarian"
],
"creditsText" : "BBC Good Food",
"extendedIngredients" : [
{
"originalString" : "200g unsalted butter, softened",
"name" : "unsalted butter",
"measures" : {
"metric" : {
"amount" : 200,
"unitLong" : "grams",
"unitShort" : "g"
},
"us" : {
"unitLong" : "ounces",
"amount" : 7.0549999999999997,
"unitShort" : "oz"
}
},
"consitency" : "solid",
"aisle" : "Milk, Eggs, Other Dairy",
"meta" : [
"unsalted",
"softened"
],
"image" : "butter-sliced.jpg",
"metaInformation" : [
"unsalted",
"softened"
],
"original" : "200g unsalted butter, softened",
"amount" : 200,
"originalName" : "unsalted butter, softened",
"unit" : "g",
"id" : 1145
},
{
"originalString" : "125g soft brown sugar",
"name" : "brown sugar",
"measures" : {
"us" : {
"unitLong" : "ounces",
"unitShort" : "oz",
"amount" : 4.4089999999999998
},
"metric" : {
"unitLong" : "grams",
"unitShort" : "g",
"amount" : 125
}
},
"consitency" : "solid",
"aisle" : "Baking",
"meta" : [
"soft"
],
"image" : "dark-brown-sugar.png",
"metaInformation" : [
"soft"
],
"original" : "125g soft brown sugar",
"amount" : 125,
"originalName" : "soft brown sugar",
"unit" : "g",
"id" : 19334
},
{
"originalString" : "1 tsp ground cinnamon",
"name" : "ground cinnamon",
"measures" : {
"us" : {
"unitLong" : "teaspoon",
"unitShort" : "tsp",
"amount" : 1
},
"metric" : {
"unitLong" : "teaspoon",
"unitShort" : "tsp",
"amount" : 1
}
},
"consitency" : "solid",
"aisle" : "Spices and Seasonings",
"meta" : [
],
"image" : "cinnamon.jpg",
"metaInformation" : [
],
"original" : "1 tsp ground cinnamon",
"amount" : 1,
"originalName" : "ground cinnamon",
"unit" : "tsp",
"id" : 1012010
},
{
"originalString" : "1½ tsp vanilla bean paste",
"name" : "vanilla bean paste",
"measures" : {
"us" : {
"unitLong" : "teaspoons",
"unitShort" : "tsps",
"amount" : 1.5
},
"metric" : {
"unitLong" : "teaspoons",
"unitShort" : "tsps",
"amount" : 1.5
}
},
"consitency" : "solid",
"aisle" : "Gourmet",
"meta" : [
],
"image" : "molasses.jpg",
"metaInformation" : [
],
"original" : "1½ tsp vanilla bean paste",
"amount" : 1.5,
"originalName" : "vanilla bean paste",
"unit" : "tsp",
"id" : 93813
},
{
"originalString" : "1 pineapple, peeled, cut into quarters, core removed, then cut into 2cm slices",
"name" : "pineapple",
"measures" : {
"us" : {
"unitLong" : "",
"unitShort" : "",
"amount" : 1
},
"metric" : {
"unitShort" : "",
"unitLong" : "",
"amount" : 1
}
},
"consitency" : "solid",
"aisle" : "Produce",
"meta" : [
"peeled",
"cut into quarters, core removed, then cut into 2cm slices"
],
"image" : "pineapple.jpg",
"metaInformation" : [
"peeled",
"cut into quarters, core removed, then cut into 2cm slices"
],
"original" : "1 pineapple, peeled, cut into quarters, core removed, then cut into 2cm slices",
"amount" : 1,
"originalName" : "pineapple, peeled, cut into quarters, core removed, then cut into 2cm slices",
"unit" : "",
"id" : 9266
},
{
"originalString" : "140g golden caster sugar",
"name" : "golden brown sugar",
"measures" : {
"us" : {
"unitShort" : "oz",
"unitLong" : "ounces",
"amount" : 4.9379999999999997
},
"metric" : {
"unitLong" : "grams",
"unitShort" : "g",
"amount" : 140
}
},
"consitency" : "solid",
"aisle" : "Baking",
"meta" : [
],
"image" : "dark-brown-sugar.png",
"metaInformation" : [
],
"original" : "140g golden caster sugar",
"amount" : 140,
"originalName" : "golden caster sugar",
"unit" : "g",
"id" : 19334
},
{
"originalString" : "2 large eggs, plus 1 egg white, beaten",
"name" : "eggs",
"measures" : {
"us" : {
"unitLong" : "larges",
"unitShort" : "large",
"amount" : 2
},
"metric" : {
"unitShort" : "large",
"amount" : 2,
"unitLong" : "larges"
}
},
"consitency" : "solid",
"aisle" : "Milk, Eggs, Other Dairy",
"meta" : [
"beaten"
],
"image" : "egg.png",
"metaInformation" : [
"beaten"
],
"original" : "2 large eggs, plus 1 egg white, beaten",
"amount" : 2,
"originalName" : "eggs, plus 1 egg white, beaten",
"unit" : "large",
"id" : 1123
},
{
"originalString" : "1½ tsp baking powder",
"name" : "baking powder",
"measures" : {
"us" : {
"unitShort" : "tsps",
"amount" : 1.5,
"unitLong" : "teaspoons"
},
"metric" : {
"unitLong" : "teaspoons",
"unitShort" : "tsps",
"amount" : 1.5
}
},
"consitency" : "solid",
"aisle" : "Baking",
"meta" : [
],
"image" : "white-powder.jpg",
"metaInformation" : [
],
"original" : "1½ tsp baking powder",
"amount" : 1.5,
"originalName" : "baking powder",
"unit" : "tsp",
"id" : 18371
},
{
"originalString" : "200g plain flour",
"name" : "plain flour",
"measures" : {
"us" : {
"unitLong" : "ounces",
"unitShort" : "oz",
"amount" : 7.0549999999999997
},
"metric" : {
"unitLong" : "grams",
"unitShort" : "g",
"amount" : 200
}
},
"consitency" : "solid",
"aisle" : "Baking",
"meta" : [
"plain"
],
"image" : "flour.png",
"metaInformation" : [
"plain"
],
"original" : "200g plain flour",
"amount" : 200,
"originalName" : "plain flour",
"unit" : "g",
"id" : 20081
},
{
"originalString" : "75ml whole milk",
"name" : "whole milk",
"measures" : {
"us" : {
"unitLong" : "fl. ozs",
"unitShort" : "fl. oz",
"amount" : 2.536
},
"metric" : {
"unitLong" : "milliliters",
"unitShort" : "ml",
"amount" : 75
}
},
"consitency" : "liquid",
"aisle" : "Milk, Eggs, Other Dairy",
"meta" : [
"whole"
],
"image" : "milk.png",
"metaInformation" : [
"whole"
],
"original" : "75ml whole milk",
"amount" : 75,
"originalName" : "whole milk",
"unit" : "ml",
"id" : 1077
}
],
"cuisines" : [
],
"cheap" : false,
"ketogenic" : false,
"sourceUrl" : "https:\/\/www.bbcgoodfood.com\/recipes\/cinnamon-pineapple-upside-down-cake",
"sustainable" : false,
"healthScore" : 5,
"weightWatcherSmartPoints" : 20,
"sourceName" : "BBC Good Food",
"whole30" : false,
"instructions" : "Heat oven to 180C\/160C fan\/gas 4. Put 4 tbsp of the butter into a 22cm springform cake tin and place in the oven to melt. Remove and stir in the brown sugar, cinnamon and tsp of the vanilla paste. Arrange the pineapple in the buttery sugar mixture, tossing a little to coat. Try to fill all the gaps, so you cant see much of the base.\nIn a mixing bowl, beat the caster sugar and remaining butter using an electric hand whisk for 2-3 mins until light and fluffy. Add the eggs and egg white, one at a time, and the remaining vanilla. Add the baking powder and a pinch of salt, then the flour and milk, beating until they are both incorporated. Beat for 1 min more until smooth.\nSpoon the batter into the pan over the pineapple. Bake for 1 hr, covering with foil if it starts to brown. Leave to rest for 5 mins, then turn out onto a platter and serve warm as a pudding, with crme frache, if you like. Alternatively, leave to cool completely in the tin and serve as a cake.",
"analyzedInstructions" : [
{
"steps" : [
{
"ingredients" : [
],
"number" : 1,
"step" : "Heat oven to 180C\/160C fan\/gas",
"equipment" : [
{
"name" : "oven",
"id" : 404784,
"image" : "oven.jpg",
"temperature" : {
"unit" : "Celsius",
"number" : 180
}
}
]
},
{
"ingredients" : [
],
"number" : 2,
"step" : "Put 4 tbsp of the butter into a 22cm springform cake tin and place in the oven to melt.",
"equipment" : [
{
"id" : 404747,
"image" : "cake-pan.png",
"name" : "cake form"
},
{
"id" : 404784,
"image" : "oven.jpg",
"name" : "oven"
}
]
},
{
"ingredients" : [
{
"id" : 93813,
"image" : "molasses.jpg",
"name" : "vanilla paste"
},
{
"id" : 19334,
"image" : "dark-brown-sugar.png",
"name" : "brown sugar"
},
{
"id" : 9266,
"image" : "pineapple.jpg",
"name" : "pineapple"
},
{
"id" : 2010,
"image" : "cinnamon.jpg",
"name" : "cinnamon"
}
],
"number" : 3,
"step" : "Remove and stir in the brown sugar, cinnamon and tsp of the vanilla paste. Arrange the pineapple in the buttery sugar mixture, tossing a little to coat. Try to fill all the gaps, so you cant see much of the base.",
"equipment" : [
]
},
{
"length" : {
"unit" : "minutes",
"number" : 3
},
"ingredients" : [
],
"number" : 4,
"step" : "In a mixing bowl, beat the caster sugar and remaining butter using an electric hand whisk for 2-3 mins until light and fluffy.",
"equipment" : [
{
"id" : 405907,
"image" : "mixing-bowl.jpg",
"name" : "mixing bowl"
},
{
"id" : 404661,
"image" : "whisk.png",
"name" : "whisk"
}
]
},
{
"ingredients" : [
{
"id" : 1123,
"image" : "egg.png",
"name" : "egg"
}
],
"number" : 5,
"step" : "Add the eggs and egg white, one at a time, and the remaining vanilla.",
"equipment" : [
]
},
{
"length" : {
"unit" : "minutes",
"number" : 1
},
"ingredients" : [
{
"id" : 18371,
"image" : "white-powder.jpg",
"name" : "baking powder"
},
{
"id" : 20081,
"image" : "flour.png",
"name" : "all purpose flour"
},
{
"id" : 1077,
"image" : "milk.png",
"name" : "milk"
}
],
"number" : 6,
"step" : "Add the baking powder and a pinch of salt, then the flour and milk, beating until they are both incorporated. Beat for 1 min more until smooth.",
"equipment" : [
]
},
{
"ingredients" : [
{
"id" : 9266,
"image" : "pineapple.jpg",
"name" : "pineapple"
}
],
"number" : 7,
"step" : "Spoon the batter into the pan over the pineapple.",
"equipment" : [
{
"id" : 404645,
"image" : "pan.png",
"name" : "frying pan"
}
]
},
{
"length" : {
"unit" : "minutes",
"number" : 5
},
"ingredients" : [
],
"number" : 8,
"step" : "Bake for 1 hr, covering with foil if it starts to brown. Leave to rest for 5 mins, then turn out onto a platter and serve warm as a pudding, with crme frache, if you like. Alternatively, leave to cool completely in the tin and serve as a cake.",
"equipment" : [
{
"id" : 404765,
"image" : "aluminum-foil.png",
"name" : "aluminum foil"
}
]
}
],
"name" : ""
}
],
"spoonacularSourceUrl" : "https:\/\/spoonacular.com\/cinnamon-pineapple-upside-down-cake-212615",
"vegetarian" : true,
"gaps" : "no",
"servings" : 8,
"cookingMinutes" : 65,
"title" : "Cinnamon pineapple upside-down cake",
"id" : 212615,
"image" : "https:\/\/spoonacular.com\/recipeImages\/212615-556x370.jpg",
"glutenFree" : false,
"dishTypes" : [
"dessert"
],
"lowFodmap" : false,
"winePairing" : {
"pairingText" : "Cream Sherry, Moscato d'Asti, and Port are my top picks for Cake. A common wine pairing rule is to make sure your wine is sweeter than your food. Delicate desserts go well with Moscato d'Asti, nutty desserts with cream sherry, and caramel or chocolate desserts pair well with port. The NV Johnson Estate Cream Sherry with a 5 out of 5 star rating seems like a good match. It costs about 19 dollars per bottle.",
"pairedWines" : [
"cream sherry",
"moscato dasti",
"port"
],
"productMatches" : [
{
"link" : "https:\/\/www.amazon.com\/Johnson-Estate-Cream-Sherry-750\/dp\/B00D3GQSRW?tag=spoonacular-20",
"score" : 0.85714285714285721,
"id" : 430626,
"price" : "$19.49",
"title" : "NV Johnson Estate Cream Sherry",
"imageUrl" : "https:\/\/spoonacular.com\/productImages\/430626-312x231.jpg",
"averageRating" : 1,
"description" : "Very aromatic with notes of hazelnut, vanilla, and a touch of oak followed by sweet raisins and a touch of yeast. Clean lasting finish. Good now but will reward those allow it to age\"\". A favorite pre-prandial beverage. Consider it with nuts before dinner as an aperitif, or after dinner with dessert, especially chocolates and fruit-based desserts. Also wonderful on cold afternoons, served with biscotti to dip in \"\"Italian-style\"\". \"",
"ratingCount" : 2
}
]
},
"dairyFree" : false,
"occasions" : [
],
"spoonacularScore" : 37,
"pricePerServing" : 91.790000000000006,
"readyInMinutes" : 85
}
]
}
Recipe Class
struct Recipe {
let id: Int
let name: String
// Recipes will only ever be instantiated in response to the server
init(json: JSON) {
self.id = json["id"].intValue
self.name = json["title"].stringValue
}
}
Parse code that's not working. It will return empty array.
let recipes: [Recipe] = json.arrayValue.map({ Recipe(json: $0) })
Please read the JSON carefully.
The recipes array is in the (root) dictionary for key recipes
let recipes = json["recipes"].arrayValue.map{ Recipe(json: $0) }
It's highly recommended to drop SwiftyJSON in favor of the built-in Codable protocol.
I use ObjectMapper library + JSONExport for classes codeGen.
The best way is to use Codable protocol power.
I write playground example below.
import UIKit
// Models
struct Recipe: Codable {
let id: Int
let name: String?
}
struct Response: Codable {
let recipes: [Recipe]
}
// Test JSON
let jsonString = """
{
"recipes": [
{
"id": 141892,
"name": "Codable Recipe"
},
{
"id": 908,
"name": "JSON Recipe"
}
]
}
"""
// Codable Test Drive
let data = jsonString.data(using: .utf8)!
do {
let res = try JSONDecoder().decode(Response.self, from: data)
print("recipes count: \(res.recipes.count)")
} catch {
print("decode error: \(error)")
}
console output:
recipes count: 2

UISearchBar and JSON Data

This is my first time using a UISearchBar and it is proving to confuse me.
I think my biggest problem here is not understanding how JSON is stored and displayed.
I have my JSON data stored as:
[{
"referralId" : "v-1519014616",
"name" : "Empire State Building",
"storeId" : "",
"hereNow" : {
"count" : 2,
"summary" : "2 people are here",
"groups" : [
{
"count" : 2,
"type" : "others",
"name" : "Other people here",
"items" : [
]
}
]
},
"stats" : {
"tipCount" : 1105,
"checkinsCount" : 185916,
"usersCount" : 129661
},
"venueRatingBlacklisted" : true,
"beenHere" : {
"lastCheckinExpiredAt" : 0
},
"specials" : {
"count" : 0,
"items" : [
]
},
"venuePage" : {
"id" : "64514349"
},
"verified" : true,
"location" : {
"state" : "NY",
"neighborhood" : "Midtown Manhattan, New York, NY",
"crossStreet" : "btwn 33rd & 34th St",
"lat" : 40.748469532965927,
"address" : "350 5th Ave",
"cc" : "US",
"city" : "New York",
"postalCode" : "10118",
"formattedAddress" : [
"350 5th Ave (btwn 33rd & 34th St)",
"New York, NY 10118"
],
"lng" : -73.985513794430119,
"distance" : 17,
"country" : "United States"
},
"hasPerk" : false,
"id" : "43695300f964a5208c291fe3",
"categories" : [
{
... etc
},
I have this stored in an array titled locations and I am trying to filter through it with a search bar.
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
let name = self.locations[0]["name"].string
filteredLocations = locations.filter { names in
return (name!.lowercased().contains(searchText.lowercased()))
}
tableView.reloadData()
}
Now, obviously, name is only going to search for the item in the array. How would I be able to filter through every location's name key to properly filter?
try this one ... don't take name first from location array...
let filterArr = locations.filter {
return (($0["name"] as! String).lowercased().contains(searchText.lowercased())))
}
use this one to get the search result

Swift 3 - SwiftyJSON string returning null

I am using SwiftyJSON to download JSON from Google Places API (the json is as below)
{
"html_attributions" : [],
"results" : [
"formatted_address" : "153A Main St, East Calder, Livingston EH53, United Kingdom",
"geometry" : {
"location" : {
"lat" : 55.8959462,
"lng" : -3.4622283
},
"viewport" : {
"northeast" : {
"lat" : 55.8973141302915,
"lng" : -3.460921669708497
},
"southwest" : {
"lat" : 55.8946161697085,
"lng" : -3.463619630291501
}
}
},
"icon" : "https://maps.gstatic.com/mapfiles/place_api/icons/shopping-71.png",
"id" : "4e89b3f89f67b043ec79e7dcb5574489bae409f7",
"name" : "Ink Well Tattoo Studio",
"opening_hours" : {
"exceptional_date" : [],
"open_now" : false,
"weekday_text" : []
},
"photos" : [
{
"height" : 443,
"html_attributions" : [
"\u003ca href=\"https://maps.google.com/maps/contrib/112667948691916642485/photos\"\u003eRobert Herschell\u003c/a\u003e"
],
"photo_reference" : "CoQBdwAAAElNWvg4vO6E6HvU2srxmeI4gDd-qIS9wXPkm_0CFgJ9ctzQTUeCRKJI-0GTajrBcy9UIJo0DdtRN-T2LgyRRm6G1VwaN7zyQSlbz-tadjMB6SmPQA1hSdTjdcwC3s3vlr72AGK8mwlkBI8-z_UYu7T915TXVESaI2_cRw3rs_woEhCzOzky--6PJ-bAqYM401HIGhSKbGY7dLvJxhqG9-Z7SmQIxBV4uQ",
"width" : 450
}
],
"place_id" : "ChIJudHXfnjbh0gRxikhSbbkZzU",
"rating" : 5,
"reference" : "CmRRAAAAbgLWU0cl7tbE04cc4VyHf7407xXydh88Ld3R2B1Kq9TIfOC2XHjXIM8BmKkhx_WS2YkA6cVHmSESrx8SGbAw0vpfcFchcEyQOaHEJqc-iY4d3UWvlEWw4DmbaOzyAyBtEhBC4X_b7g-qGcvcRDzEv3WIGhRYMy0MbZUaUqTYWGIy_JWDrfJECg",
"types" : [ "store", "point_of_interest", "establishment" ]
}
]
and i am able to get the address and name from each result in the JSON using SwiftyJSON and populate my table
let row = (indexPath as NSIndexPath).row
cell?.lblShopTitle.text = self.json["results"][row]["name"].string
however i am trying to get the photo_reference string and i cannot seem to access it as it continually comes back as null
let imgRef = self.json["results"][row]["photos"]["photo_reference"]
Please read the JSON carefully.
[] represents an array.
{} represents a dictionary.
Therefore the object for key photos is an array. So it's most likely
let imgRef = self.json["results"][row]["photos"][0]["photo_reference"]

Ng-repeat orderBy value

How can I order my ng-repeat by the like_count in my json?
I have given it a bash but I am clearly missing something.
This is the repeat
item(ng-repeat="item in items | limitTo:3 | orderBy:like_count)
This is the data structure:
{
"image_url" : "bde2cca8323d098edf43389119af7748.jpg",
"title" : "This is the title",
"like_count" : "15",
"creator" : {
"profile_img" : "john-doe.jpg",
"username" : "JD",
"url" : "/John-Doe",
"first_name" : "John",
"last_name" : "Doe",
"location" : "Sydney, Australia"
}
}, {
"image_url" : "bjk23482301232234112d3232345343.jpg",
"title" : "This is the title",
"like_count" : "89",
"creator" : {
"profile_img" : "Jane-doe.jpg",
"username" : "JD",
"url" : "/Jane-Doe",
"first_name" : "Jane",
"last_name" : "Doe",
"location" : "Melbourne, Australia"
}
}
Try this..
ng-repeat="item in items | limitTo:3 | orderBy:'like_count'