Home > AI > Language > Swift >

Generic

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()

Leave a Reply