Home > Back-end >  how to create Swift struct for Google Api Places auto populate endpt
how to create Swift struct for Google Api Places auto populate endpt

Time:04-09

I'm failing to get my swift struct CustomerLocationPredictions to be populated from the googleapi/maps/api/places/autocomplete end point. It seems to just be a silly mistake somewhere in my struct.

Example json response from postman

{
"predictions": [
    {
        "description": "810 Alliance Drive, Greensboro, NC, USA",
        "matched_substrings": [
            {
                "length": 8,
                "offset": 4
            }
        ],
        "place_id": "Eic4MTAgQWxsaWFuY2UgRHJpdmUsIEdyZWVuc2Jvcm8sIE5DLCBVU0EiLiosChQKEgldq-4SqhtTiBESdqAnRro2HRIUChIJeXvHOD8ZU4gRyBK-eJTEuZM",
        "reference": "Eic4MTAgQWxsaWFuY2UgRHJpdmUsIEdyZWVuc2Jvcm8sIE5DLCBVU0EiLiosChQKEgldq-4SqhtTiBESdqAnRro2HRIUChIJeXvHOD8ZU4gRyBK-eJTEuZM",
        "structured_formatting": {
            "main_text": "810 Alliance Drive",
            "main_text_matched_substrings": [
                {
                    "length": 8,
                    "offset": 4
                }
            ],
            "secondary_text": "Greensboro, NC, USA"
        },
        "terms": [
            {
                "offset": 0,
                "value": "810"
            },
            {
                "offset": 4,
                "value": "Alliance Drive"
            },
            {
                "offset": 20,
                "value": "Greensboro"
            },
            {
                "offset": 32,
                "value": "NC"
            },
            {
                "offset": 36,
                "value": "USA"
            }
        ],
        "types": [
            "route",
            "geocode"
        ]
    },
    {
        "description": "810 Alliance Church Road, Greensboro, NC, USA",
        "matched_substrings": [
            {
                "length": 8,
                "offset": 4
            }
        ],
        "place_id": "Ei04MTAgQWxsaWFuY2UgQ2h1cmNoIFJvYWQsIEdyZWVuc2Jvcm8sIE5DLCBVU0EiLiosChQKEglr2ga7whdTiBG82Rvya0GljhIUChIJeXvHOD8ZU4gRyBK-eJTEuZM",
        "reference": "Ei04MTAgQWxsaWFuY2UgQ2h1cmNoIFJvYWQsIEdyZWVuc2Jvcm8sIE5DLCBVU0EiLiosChQKEglr2ga7whdTiBG82Rvya0GljhIUChIJeXvHOD8ZU4gRyBK-eJTEuZM",
        "structured_formatting": {
            "main_text": "810 Alliance Church Road",
            "main_text_matched_substrings": [
                {
                    "length": 8,
                    "offset": 4
                }
            ],
            "secondary_text": "Greensboro, NC, USA"
        },
        "terms": [
            {
                "offset": 0,
                "value": "810"
            },
            {
                "offset": 4,
                "value": "Alliance Church Road"
            },
            {
                "offset": 26,
                "value": "Greensboro"
            },
            {
                "offset": 38,
                "value": "NC"
            },
            {
                "offset": 42,
                "value": "USA"
            }
        ],
        "types": [
            "route",
            "geocode"
        ]
    },
    {
        "description": "810 Alliance Avenue, Rockford, IL, USA",
        "matched_substrings": [
            {
                "length": 3,
                "offset": 0
            },
            {
                "length": 8,
                "offset": 4
            }
        ],
        "place_id": "ChIJh-PFfLCVCIgRUmLa9Pv-Ep0",
        "reference": "ChIJh-PFfLCVCIgRUmLa9Pv-Ep0",
        "structured_formatting": {
            "main_text": "810 Alliance Avenue",
            "main_text_matched_substrings": [
                {
                    "length": 3,
                    "offset": 0
                },
                {
                    "length": 8,
                    "offset": 4
                }
            ],
            "secondary_text": "Rockford, IL, USA"
        },
        "terms": [
            {
                "offset": 0,
                "value": "810"
            },
            {
                "offset": 4,
                "value": "Alliance Avenue"
            },
            {
                "offset": 21,
                "value": "Rockford"
            },
            {
                "offset": 31,
                "value": "IL"
            },
            {
                "offset": 35,
                "value": "USA"
            }
        ],
        "types": [
            "premise",
            "geocode"
        ]
    },
    {
        "description": "810 Alliance Court, Asheville, NC, USA",
        "matched_substrings": [
            {
                "length": 12,
                "offset": 0
            }
        ],
        "place_id": "EiY4MTAgQWxsaWFuY2UgQ291cnQsIEFzaGV2aWxsZSwgTkMsIFVTQSJREk8KNAoyCYOUesl7jVmIESXq3Q6C4v_-Gh4LEO7B7qEBGhQKEgkrkVFbXIxZiBF9hEcBznFriwwQqgYqFAoSCVM14bN7jVmIEeMPnFvzVFxP",
        "reference": "EiY4MTAgQWxsaWFuY2UgQ291cnQsIEFzaGV2aWxsZSwgTkMsIFVTQSJREk8KNAoyCYOUesl7jVmIESXq3Q6C4v_-Gh4LEO7B7qEBGhQKEgkrkVFbXIxZiBF9hEcBznFriwwQqgYqFAoSCVM14bN7jVmIEeMPnFvzVFxP",
        "structured_formatting": {
            "main_text": "810 Alliance Court",
            "main_text_matched_substrings": [
                {
                    "length": 12,
                    "offset": 0
                }
            ],
            "secondary_text": "Asheville, NC, USA"
        },
        "terms": [
            {
                "offset": 0,
                "value": "810 Alliance Court"
            },
            {
                "offset": 20,
                "value": "Asheville"
            },
            {
                "offset": 31,
                "value": "NC"
            },
            {
                "offset": 35,
                "value": "USA"
            }
        ],
        "types": [
            "street_address",
            "geocode"
        ]
    },
    {
        "description": "810 Alliance Road, Surry, VA, USA",
        "matched_substrings": [
            {
                "length": 12,
                "offset": 0
            }
        ],
        "place_id": "EiE4MTAgQWxsaWFuY2UgUm9hZCwgU3VycnksIFZBLCBVU0EiURJPCjQKMgmR3_fCPGewiRFyqVm0Hu3VShoeCxDuwe6hARoUChIJ9WvIE5hmsIkRrxjljIN-qGMMEKoGKhQKEgnrv-952WawiREAuhFkShhFjA",
        "reference": "EiE4MTAgQWxsaWFuY2UgUm9hZCwgU3VycnksIFZBLCBVU0EiURJPCjQKMgmR3_fCPGewiRFyqVm0Hu3VShoeCxDuwe6hARoUChIJ9WvIE5hmsIkRrxjljIN-qGMMEKoGKhQKEgnrv-952WawiREAuhFkShhFjA",
        "structured_formatting": {
            "main_text": "810 Alliance Road",
            "main_text_matched_substrings": [
                {
                    "length": 12,
                    "offset": 0
                }
            ],
            "secondary_text": "Surry, VA, USA"
        },
        "terms": [
            {
                "offset": 0,
                "value": "810 Alliance Road"
            },
            {
                "offset": 19,
                "value": "Surry"
            },
            {
                "offset": 26,
                "value": "VA"
            },
            {
                "offset": 30,
                "value": "USA"
            }
        ],
        "types": [
            "street_address",
            "geocode"
        ]
    }
],
"status": "OK"
}

Here are my Swift Structs

struct CustomerLocationPredictions: Codable {
        let predictions: [CustomerPlaces]
        init(name: String, address: String){
            predictions = [CustomerPlaces(name: name, address: address)]
        }
        init(){
            predictions = [CustomerPlaces()]
        }
    }


struct CustomerPlaces: Codable{
    let description: String
    let matched_substrings: [CustomerMatchedSubstrings]
    let place_id, reference: String
    let structured_formatting: [CustomerStructuredFormatting]
    let terms: [CustomerTerms]
    let types: [String]
    
    init(name: String, address: String){
        self.description = address
        self.matched_substrings = [CustomerMatchedSubstrings()]
        self.terms = [CustomerTerms()]
        self.place_id = ""
        self.reference = ""
        self.structured_formatting = [CustomerStructuredFormatting()]
        self.types = []
    }
    init() {
        description = ""
        matched_substrings = [CustomerMatchedSubstrings()]
        terms = [CustomerTerms()]
        self.place_id = ""
        self.reference = ""
        self.structured_formatting = [CustomerStructuredFormatting()]
        self.types = []
    }
    enum CodingKeys: String, CodingKey {
        case description = "description"
        case matched_substrings = "matched_substrings"
        case place_id = "place_id"
        case reference = "reference"
        case structured_formatting = "structured_formatting"
        case terms = "terms"
        case types = "types"
    }
}

struct CustomerStructuredFormatting: Codable{
    let main_text, secondary_text: String
    let main_text_matched_substrings: [CustomerMatchedSubstrings]
    init(){
        main_text = ""
        main_text_matched_substrings = [CustomerMatchedSubstrings()]
        secondary_text = ""
    }
}

struct CustomerMatchedSubstrings: Codable{
    let length, offset: Int
    init(){
        length = 0
        offset = 0
    }
}

struct CustomerTerms: Codable{
    let offset: Int
    let value: String
    init(){
        offset = 0
        value = ""
    }
}

How I'm decoding the json

var customerResponce = try JSONDecoder().decode(CustomerLocationPredictions.self, from: data!)

my current error

Error info: typeMismatch(Swift.Array, Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "predictions", intValue: nil), _JSONKey(stringValue: "Index 0", intValue: 0), CodingKeys(stringValue: "structured_formatting", intValue: nil)], debugDescription: "Expected to decode Array but found a dictionary instead.", underlyingError: nil))

Thank you for any help!

CodePudding user response:

You messed this line up:

let structured_formatting: [CustomerStructuredFormatting]

try:

let structured_formatting: CustomerStructuredFormatting
  • Related