0

I am showing a tableview with the list generated using the following code. The UI is properly populated. However on did select method, the call is not matched inside the generic case.

@objc public protocol ListProtocol {}


class EmptyListProtocol:ListProtocol {
    let message:String
    
    init(message:String){
        self.message = message
    }
}


class ListItemStrategy<T>: ListProtocol{
    let object:T
    
    init(listitem:T) {
        self.object = listitem
    }
}

struct CartInfo {
    let card_id : String
    let productname: String
    let purchasedate:String
}

struct ProductOnSale {
    
    let product_id:String
    let product_name:String
    let store_id:String
}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        
        let item = self.tablelist[indexPath.row]
        switch item {
        case is ListItemStrategy<Any>:
            print("didtap")            
        case is EmptyListProtocol: break
        default:
            break
     }
}

var table list : [ListProtocol] = []

I am not able to detect in particular, if a cart is selected or new purchase product is selected.

Nassif
  • 1,113
  • 2
  • 14
  • 34

1 Answers1

2

When checking the type you need to understand that SomeGeneric<Any> is a specific type and that you can't use the protocol Any here as something that represents any implementation of the generic type.

This means your switch would need to be something like

switch item {
    case is ListItemStrategy<ProductOnSale>:
        ...
    case is ListItemStrategy<CartInfo>:
        ...
    case ...
}

I assume you want to access the specific objects which mean you need to type case item so it might be preferable to skip the switch and use if let to cast directly

let item = self.tablelist[indexPath.row]

if let cartInfo = item as? ListItemStrategy<CartInfo> {
    ...
} else if let productOnSale = item as? ListItemStrategy<ProductOnSale> {
    ...
} else if let ... {
    ...
}

Here is a simple example

let tableList : [ListProtocol] = [
    ListItemStrategy(listitem: ProductOnSale(product_id: "product1", product_name: "", store_id: "")),
    ListItemStrategy(listitem: CartInfo(card_id: "card1", productname: "", purchasedate: "")),
    ListItemStrategy(listitem: ProductOnSale(product_id: "product2", product_name: "", store_id: "")),
    ListItemStrategy(listitem: EmptyListProtocol(message: "Empty"))
]

for item in tableList {
    if let cartInfo = item as? ListItemStrategy<CartInfo> {
        print(cartInfo.object.card_id)
    } else if let productOnSale = item as? ListItemStrategy<ProductOnSale> {
        print(productOnSale.object.product_id)
    } else if let emptyMessage = item as? ListItemStrategy<EmptyListProtocol> {
        print(emptyMessage.object.message)
    }
}
Joakim Danielson
  • 43,251
  • 5
  • 22
  • 52
  • thanks. Fortunately I was able to figure out myself and the solution is exactly what you have added above – Nassif Jul 27 '21 at 10:05