I'm having a problem parsing JSON that is arriving from my JS Rest api. The casting from the JSON object to Swift 4 dictionary is not working. Here the API configuration file
{
"name": "api",
"version": "1.0.0",
"description": "API",
"main": "dist",
"scripts": {
"dev": "NODE_ENV=development nodemon -w src --exec babel-node src",
"build": "babel src -s -D -d dist --preset es2015,stage-2",
"start": "NODE_ENV=production pm2 start dist",
"prestart": "npm run -s build",
"lint": "eslint src"
},
"author": "Oscar",
"license": "ISC",
"devDependencies": {
"babel-cli": "^6.26.0",
"babel-preset-env": "^1.7.0",
"babel-preset-stage-2": "^6.24.1",
"eslint": "^5.10.0",
"nodemon": "^1.18.9"
},
"dependencies": {
"body-parser": "^1.18.3",
"dotenv": "^6.2.0",
"express": "^4.16.4",
"express-jwt": "^5.3.1",
"jsonwebtoken": "^8.4.0",
"mongoose": "^5.4.0",
"passport": "^0.4.0",
"passport-local": "^1.0.0",
"passport-local-mongoose": "^5.0.1"
}
}
Here the controller file
import mongoose from 'mongoose';
import { Router } from 'express';
import FoodTruck from '../model/foodtruck';
import { authenticate } from '../middleware/authMiddleware';
export default({ config, db }) => {
let api = Router();
// '/v1/foodtruck' - READ
api.get('/', (req, res) => {
// reading the DB looking for ALL restaurants
FoodTruck.find({}, (err, foodTruck) => {
if( err ) {
res.send(err);
}
res.json({foodTruck});
});
});
return api;
}
Here the model
import mongoose from 'mongoose';
import Review from './review';
let Schema = mongoose.Schema;
let FoodTruckSchema = new Schema({
name: {
type: String,
required: true
},
foodType: {
type: String,
required: true
},
avgCost: Number,
geometry: {
type: { type: String, default: 'Point' },
coordinates: {
"lat": Number,
"long": Number
}
},
reviews: [{
type: Schema.Types.ObjectId,
ref: 'Review'
}]
});
module.exports = mongoose.model('FoodTruck', FoodTruckSchema);
Here the block that is going me crazy! (Please check the line after the comment // THE NEXT LINE)
static func parseFoodTruckJSONData(data: Data) -> [FoodTruck] {
var foodTrucks = [FoodTruck]()
do {
let jsonResult = try JSONSerialization.jsonObject(with: data, options: .mutableContainers)
//Parse JSON data
// THE NEXT LINE *****************************
if let trucks = jsonResult as? [Dictionary<String, AnyObject>] {
for truck in trucks {
let newTruck = FoodTruck()
newTruck.id = truck["_id"] as! String
newTruck.name = truck["name"] as! String
newTruck.foodType = truck["foodType"] as! String
newTruck.avgCost = truck["avgCost"] as! Double
let geometry = truck["geometry"] as! Dictionary<String, AnyObject>
newTruck.geomType = geometry["type"] as! String
let coords = geometry["coordinates"] as! Dictionary<String, AnyObject>
newTruck.lat = coords["lat"] as! Double
newTruck.long = coords["long"] as! Double
newTruck.title = newTruck.name
newTruck.subtitle = newTruck.foodType
foodTrucks.append(newTruck)
print("(parseFoodTruckJSONData) Added a new food truck \(newTruck.id)")
}
} else {
print("(parseFoodTruckJSONData) Something is going wrong with food trucks parsing...")
}
}catch let err {
print(err)
}
return foodTrucks
}
And I'm calling this function here
// Get all foodtrucks
func getAllFoodTrucks() {
let sessionConfig = URLSessionConfiguration.default
// Create session, and set a URLSessionDelegate
let session = URLSession(configuration: sessionConfig, delegate: nil, delegateQueue: nil)
// Create the request
// Get all foodtrucks
guard let URL = URL(string: GET_ALL_FOODTRUCKS_URL) else { return }
var request = URLRequest(url: URL)
request.httpMethod = "GET"
let task = session.dataTask(with: request, completionHandler: { (data: Data?, response: URLResponse?, error: Error? ) -> Void in
if(error == nil){
// Success
let statusCode = (response as! HTTPURLResponse).statusCode
print("(getAllFoodTrucks) URL session task succeeded: HTTP \(statusCode)")
if let data = data {
// THE NEXT LINE *****************************
self.foodTrucks = FoodTruck.parseFoodTruckJSONData(data: data)
if(self.foodTrucks.count>0) {
self.delegate?.trucksLoaded()
}
}
}else{
// Failure
print("(getAllFoodTrucks) URL session task failed: \(error!.localizedDescription)")
}
})
task.resume()
session.finishTasksAndInvalidate()
}
The call parsing is returning an empty list. Naturally my database is not empty.
Here the JSON
{
"foodTruck": [
{
"geometry": {
"coordinates": [
35.89,
-89.324
],
"type": "Point"
},
"reviews": [
"5c20a26b92e52a2a1fc4435b",
"5c20a2dd92e52a2a1fc4435c"
],
"_id": "5c209fa09eec9429efc2a893",
"name": "Joe's Stabbin Wagon",
"foodType": "Meat",
"avgCost": 5.99,
"__v": 2
},
{
"geometry": {
"coordinates": [
38.89,
-86.324
],
"type": "Point"
},
"reviews": [],
"_id": "5c20ce386151a32af5423f1e",
"name": "Smoki truck",
"foodType": "Hamburger",
"avgCost": 14.99,
"__v": 0
}
]
}
Is there something that is not arriving correctly from the server?
Thank you very much!
UPDATE:
I found the mistake. The JSON start with a "foodTruck" entity so this is a Dictionary. The correct cast of it is:
if let jsonTrucks = jsonResult as? [String: Any] {
let trucks = jsonTrucks["foodTruck"] as! [[String: Any]]
for truck in trucks {
//...
}
} else {
print("(parseFoodTruckJSONData) Something is going wrong with food trucks parsing...")
}