Displaying JSON data

Well here is another piece of the puzzle if this helps. I’m using WIX Database. Not sure if that matters.

I have no idea. What does the json output that you are generating look like now?

This is with using my url.

OK but what does your JSON data look like. There is a mismatch between the Model struct and the json data. Can you get a dump of it?

It does appear to be a problem with WIX Data Base code. I have contacted support about it. I hope I don’t have to upgrade anything $$$ :eyes:

Hey Chris,

So I was told to remove the tag in the (error) that you had localized and I get this:


What do you make of it?

Can you provide a copy of the contents of the json file that is being provided by the server?

Previously it looked like this in the DummyData file you linked in the very first post.

{“items”:"[{“name”:“My name is Gilbert”,“greetings”:“Hello world”,"_id":“7ad33209-1223-449b-afbc-c69d20935389”,"_owner":“04c4cdf4-723c-4c3b-a14d-6867c733b2d1”,"_createdDate":“2022-06-26T17:05:18.192Z”,"_updatedDate":“2022-06-27T20:13:13.707Z”,“title”:“User”}]"}

Is that what it still looks like?

I finally got it to work!!! It was the code in my WIX HTTPResonse code that was not matched up. I used your JSON tree and it worked! Thank you so much for the guidance!

Great. Good luck with the rest of the project.

Much appreciated!

Hey Chris. Is there a way to use what you’ve done and make it into a “login” and “create an account” storyboard without Firebase and Coca Pods?

@coder3000

I don’t follow what you mean.

Do you mean create your own means of enabling users to login and create an account?

If so, how do you propose to store login, password and account details securely?

So far my efforts with your help is to store and use data in one location, WIX Database. With your help we were able to make a successful HTTP connection.

Are you familiar with WIX?

So far was I trying to merge what you showed me, using JSON, with a tutorial by Chris Ching on “Custom Login”. It’s quite a puzzle. So I am seeking assistance.

@coder3000

I have heard of WIX only because of the huge amount of advertising on YouTube but I have no experience with it whatsoever.

How would I take the project that you gave me and make it so I can submit data to the same api endpoint that I provided? This is really the question that I meant to ask instead of the Custom Login question.

At the moment the sample project is reading data from the json file and from what you have posted in your recent messages is that the method you are using to “read” the json file is different to the method I used in the sample.

As to how you “post” data to the endpoint I have absolutely no idea.

Hi Chris,

I am trying to create a structure that works with a model that was given to me for my project. I am trying to put some structures into an array but failing to without errors. Here is what’s happening:

This is the data model:

{
   "pickup": {
     "name": "Kermit's Salads",
     "phoneNumber": "+12125551234",
     "street": "26 Broadway",
     "city": "New York City",
     "state": "NY",
     "postalCode": "10004",
     "country": "US",
     "latitude": 40.716038,
     "longitude": -74.00631,
     "unit": "104B",
     "instructions": "Use back entrance"
   },
   "dropoff": {
     "name": "Miss Piggy",
     "phoneNumber": "+12125555678",
     "street": "312 Broadway",
     "city": "New York City",
     "state": "NY",
     "postalCode": "10004",
     "country": "US",
     "latitude": 40.24377,
     "longitude": -74.10277,
     "unit": "Suite 300",
     "instructions": "Leave with security guard"
   },
   "orderDetails": [
     {
       "title": "Salad Green",
       "quantity": 3
     }
   ],
   "pickupTime": "2015-09-22T18:30:00.0000000Z",
   "quoteExternalReference": "basket_e699aece",
   "deliveryExternalReference": "order_713a8bd9",
   "tip": 3.5,
   "deliveryId": "cb1915b1-3330-4477-b4bf-88c9b935943c",
   "statusUpdateUrl": "https://goedash.com",
   "dropoffTime": "2015-09-22T18:30:00.0000000Z",
   "controlledContents": "Alcohol,Tobacco",
   "allowedVehicles": "Walker,Bicycle,DeliveryBicycle,Car,Van",
   "orderValue": 22.5,
   "brandName": "BigBellyBurger",
   "currency": "USD"
 }

What am I doing wrong. I’d appreciate some help. Thanks!

What you are doing wrong is that this:

let accept: [Pickup, Dropoff, OrderDetails, TheRest]

Is not valid Swift.

What type is accept? This looks like your are trying to create an array but you are really describing the type of accept. Only problem is, [Pickup, Dropoff, OrderDetails, TheRest] isn’t a valid way to do that.

Instead, what you should be doing is something like this:

struct Accept: Codable {
    //although what kind of name is Accept?
    
    let pickup, dropoff: LocationInfo
    
    let orderDetails: [OrderDetail]

    let pickupTime: String
    let quoteExternalReference: String
    let deliveryExternalReference: String
    let tip: Double
    let deliveryID: String
    let statusUpdateURL: String
    let dropoffTime: String
    let controlledContents: String
    let allowedVehicles: String
    let orderValue: Double
    let brandName: String
    let currency: String

    enum CodingKeys: String, CodingKey {
        case pickup, dropoff, orderDetails, pickupTime, quoteExternalReference, deliveryExternalReference, tip
        case deliveryID = "deliveryId"
        case statusUpdateURL = "statusUpdateUrl"
        case dropoffTime, controlledContents, allowedVehicles, orderValue, brandName, currency
    }
}

struct LocationInfo: Codable {
    let name: String
    let phoneNumber: String
    let street: String
    let city: String
    let state: String
    let postalCode: String
    let country: String
    let latitude
    let longitude: Double
    let unit: String
    let instructions: String
}

struct OrderDetail: Codable {
    let title: String
    let quantity: Int
}

Take a look at this, study it, see what’s going on, and if you have any questions, don’t hesitate to ask.


And just a hint: Placing text in a code block with backticks ``` works just as well for JSON as it does for code. Among other things, it keeps the forum software from “smartening” the quotation marks so that when someone tries to validate the JSON, the typographic quote marks don’t raise errors.

1 Like

Hey @roosterboy,

Thanks a lot! Your model isn’t giving me any screaming errors and it all makes sense to me. I am having issues implementing it in my api code that I have being using with simple JSON models.

First I made some adjustment to match what I was trying to accomplish:

**import** Foundation

**struct** OrderAccepted: Decodable {

//although what kind of name is Accept? 
// I changed it to OrderAccepted

**let** pickup, dropoff: LocationInfo

**let** orderDetails: [OrderDetail]

**let** pickupTime: String

**let** quoteExternalReference: String

**let** deliveryExternalReference: String

**let** tip: Double

**let** deliveryID: String

**let** statusUpdateURL: String

**let** dropoffTime: String

**let** controlledContents: String

**let** allowedVehicles: String

**let** orderValue: Double

**let** brandName: String

**let** currency: String

**enum** CodingKeys: String, CodingKey {

**case** pickup, dropoff, orderDetails, pickupTime, quoteExternalReference, deliveryExternalReference, tip

**case** deliveryID = "deliveryId"

**case** statusUpdateURL = "statusUpdateUrl"

**case** dropoffTime, controlledContents, allowedVehicles, orderValue, brandName, currency

}

}

**struct** LocationInfo: Decodable, Identifiable {

**let** id: UUID

**let** name: String

**let** phoneNumber: String

**let** street: String

**let** city: String

**let** state: String

**let** postalCode: String

**let** country: String

**let** latitude: Double

**let** longitude: Double

**let** unit: String

**let** instructions: String

}

**struct** OrderDetail: Decodable {

**let** title: String

**let** quantity: Int

}

And then I tried to add it to ContentViewModle, which is wrong. What did I do wrong:

mport Foundation

class ContentViewModel: ObservableObject {
    @Published var accept = [OrderAccepted.self]()

    init() {
        fetchRemoteData()
    }

    func fetchLocalData() {

        let jsonUrl = Bundle.main.url(forResource: "data", withExtension: "json")
        
        do {
            //  Read the file into a data object
            let jsonData = try Data(contentsOf: jsonUrl!)
            
            let decoder = JSONDecoder()
            do {
                let decodedData = try decoder.decode(OrderAccepted.self, from: jsonData)
                self.accept = OrderAccepted.CodingKeys
            } catch {
                print("Unable to decode JSON data \(error.localizedDescription)")
            }
        } catch {
            print("Unable to find JSON data")
        }
    }

    func fetchRemoteData() {
        let urlString = "https://www.goedash.com/_functions/api/accept" //http://d1058276.myweb.iinethosting.net.au/data.json
        let url = URL(string: urlString)
        let defaultSession = URLSession(configuration: .default)
        let dataTask = defaultSession.dataTask(with: url!) { data, response, error in

            if error != nil {
                print(error!)
                return
            }

            do {
                let json = try JSONDecoder().decode(OrderAccepted.self, from: data!)
                DispatchQueue.main.async {
                    self.accept = json.CodingKeys
                }
            } catch {
                print(error)
            }
        }
        dataTask.resume()
    }
}

Here are my errors:


In your ContentViewModel class:

@Published var accept = [OrderAccepted.self]()

should be:

@Published var accept = [OrderAccepted]()

You are declaring an array of OrderAccepteds. When you use OrderAccepted.self you are using what is called the metatype, which is basically the type of the type (i.e., OrderAccepted.Type). I know that probably sounds confusing, and it is, so don’t worry too much about it. Just know that you need [OrderAccepted] and not [OrderAccepted.self]


Next, in the fetchLocalData method:

let decodedData = try decoder.decode(OrderAccepted.self, from: jsonData)
self.accept = OrderAccepted.CodingKeys

First, ContentViewModel.accept is an array of OrderAccepteds, so you need to indicate that in the decode call.

Second, you will almost never need to use CodingKeys for anything. It is used internally by the Codable system to synthesize (en|de)coding of your data. There are rare occasions when you will need to use it, such as when manually (en|de)coding, but those times are, like I said, rare. The rest of the time, it’s enough to just declare a CodingKeys enum in your data model and let the compiler take it from there.

Put these two points together and your code now becomes:

let decodedData = try decoder.decode([OrderAccepted].self, from: jsonData)
self.accept = decodedData

//you could even combine the two lines as:
//self.accept = try decoder.decode([OrderAccepted].self, from: jsonData)

In fetchRemoteData, you have a similar issue.

let json = try JSONDecoder().decode(OrderAccepted.self, from: data!)
DispatchQueue.main.async {
    self.accept = json.CodingKeys
}

should be:

let json = try JSONDecoder().decode([OrderAccepted].self, from: data!)
DispatchQueue.main.async {
    self.accept = json
}

That’s what I can see from looking at it without testing your code. Give those changes a try and see how you do.