Example 1: variable generic
func addition<T: Numeric>(a: T, b: T) -> T
{
return a + b
}
// Adding two integers
let resultA = addition(a: 42, b: 99)
print(resultA)
// Adding two doubles
let resultB = addition(a: 3.1415, b: 1.618)
print(resultB)
Example 2: return type generic
struct MoviesAgent {
func run<T: Decodable>(_ urlRequest: URLRequest) -> AnyPublisher<T, Error> {
return URLSession.shared.dataTaskPublisher(for: urlRequest)
.map { $0.data }
.decode(type: T.self, decoder: JSONDecoder())
.receive(on: DispatchQueue.main)
.eraseToAnyPublisher()
}
}
struct PageDTO<T: Codable>: Codable {
let page: Int?
let total_results: Int?
let total_pages: Int?
let results: [T]
}
struct MovieDTO: Codable {
let id: Int
let title: String
let poster_path: String?
var poster: URL? {
poster_path.map { URL(string: $0)! }
}
}
struct MovieListItemModel : Identifiable{
var id: Int
var title: String
var poster: URL?
init(dto: MovieDTO) {
self.id = dto.id
self.title = dto.title
self.poster = dto.poster
}
}
enum Event {
case onAppear
case onMoviesLoaded([MovieListItemModel])
case onError(Error)
}
let agent = MoviesAgent()
let url = URL(string: "https://api.themoviedb.org/3/trending/movie/week?api_key=8fd6920fbc4eb9841dfd261f3cb91aca")!
let request = URLRequest(url: url)
func wrapper() -> AnyPublisher<PageDTO<MovieDTO>, Error> {
return agent.run(request)
}
let resultPub = wrapper()
resultPub // AnyPublisher<PageDTO<MovieDTO>, Error>()
.map { $0.results.map(MovieListItemModel.init) } // AnyPublisher<MovieListItemModel, Error>()
.map (Event.onMoviesLoaded)
.catch { Just(Event.onError($0))}
.eraseToAnyPublisher()