kkarol kkarol - 1 year ago 81
Swift Question

Different structs in one array in Swift

I have a struct called


struct trip {
var name: String
var description: String
var elements: [Any] = []

mutating func addItemToElements(newValue: Any) {

As you can see, there is an array inside. I'm adding some other structs like
into this array by function

struct element_flight {
var origin: String
var destination: String
var flightno: String
var departure: NSDate
var arrival: NSDate
var seat: String

Then I'm trying to create a list using table view:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "elementTrip", for: indexPath) as! CellInElementsOfTripsTableViewCell
let elem = trips[0].elements[indexPath.row]
cell.mainTextLabel.text = elem.origin //it doesn't work

return cell

I can't get any of parts of struct (like
in code). What am I doing wrong?

I'm creating similar structs to
and it could be the best way to put it in one array and then show in table view.

Answer Source

A simple, naive solution would be to cast elem to the correct type:

cell.mainTextLabel.text = (elem as! element_flight).origin

However, since the elements array can store Any, what if elem is some other type? Obviously, it will crash!

I don't understand why you want to store a bunch of Any in elements. This is a sign or bad code. Any is seldom used in Swift.

If you're just going to store some types, but not Any types, in elements, create a protocol and make all the types that you want to store conform to it. At least you get a little bit of type safety.

Let's say your array will only contain two structs: element_flight and SomeOtherStruct. You should do something like this:

protocol SomeProtocol { // please give this a proper name yourself
    // properties/methods that are common among element_flight and SomOtherStruct

struct element_flight: SomeProtocol {
    // ...

struct SomeOtherStruct: SomeProtocol {
    // ...

And change the array to be of type [SomeProtocol].

Now in the cellForRowAtIndexPath method, you need to test whether elem is element_flight or SomeOtherStruct:

if let flight = elem as? element_flight {
    cell.mainTextLabel.text = flight.origin
} else if let someOtherStuff = elem as? SomeOtherStruct {
    // do some other stuff
} else {
    // something's wrong if this is executed, maybe call fatalError
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download