Generics in Swift have a lot of use, except as a placeholder in the method I described earlier, and can be used in protocols to form a generic protocol, and the members that follow this generic protocol become generic members. We also use our previous event reminder demo to show that in the previous version we used a tableview to present the data, and now if there are new requirements, we need to make a similar arrangement in Collectonview, and provide a filter for the date for the data source. In the face of similar functional requirements obviously you don't want to write two code, so the best way to do this is to refine a protocol and declare a default implementation in the protocol extension.
Let's take the first step: analyzing the requirements, refining the composition of the Protocol, in the above scenario, we want a date filter, so we need to define a method, and the filter is for the data source, which is the array we used in our previous demo DataList
Step Two: Define this protocol in the following format:
protocol FestivalsAndEventsTool{ vardataList:[DateViewModel]{get set} func search(date:String) -> [DateViewModel]}
Third, declare the default implementation in the protocol extension, this default implementation needs to be the implementation of the majority of cases, so that we can comply with the protocol free of charge for this implementation, to avoid unnecessary code, note that this step is not necessary, but it can significantly improve the code reuse:
extension FestivalsAndEventsTool{ func search(date:String) -> [DateViewModel]{ return dataList.filter{ $0.datedate } }}
Now back in the subclass of Tableviewcontroller, you can get a way to filter data by simply adhering to the protocol:
class ShowedTableViewController: UITableViewController, FestivalsAndEventsTool
If you still need to show events and festivals in a collectionviewcontroller, just let Collectionviewcontroller also follow Festivalsandeventstool. The search method is then called at the appropriate location in the code.
Let's talk about the generic controller, our array source is heterogeneous, because the array members are protocol types, and if you want the data source of the protocol to remain diverse, but the data source for each controller is isomorphic, you can declare a generic protocol using the Associatedtype keyword:
protocol FestivalsAndEventsTool{ associatedtype Model:DateViewModel var dataList:[Model]{getset} func search(date:String) -> [Model]}extension FestivalsAndEventsTool{ func search(date:String) -> [Model]{ return dataList.filter{ $0.datedate } }}
The model using the Associatedtype declaration is also a placeholder, you can add some constraints to the placeholder, such as in the example above we need model must abide by the Dateviewmodel protocol. The type of the model is not declared in the code of the compliance, and the compiler determines the actual type of the model based on the type that each model actually passes in, and if you declare the protocol as the above format, the previous Tableviewcontroller will give an error. Because our DataList is [Dateviewmodel] type, if you change DataList to [Event] or [Festival], the compiler passes. The generic protocol guarantees our data security and consistency.
Additional notes on "Phantom Architecture" 5: Retrofit Controller