Marvel App (Fork)

Listado de personajes de Marvel hecho en UIKit

Reemplazo de librerías AlamoFire y KingFisher por URLSession. Se añade la funcionalidad de persistencia Local para favoritos

Reemplazo de librería AlamoFire y KingFisher por URLSession
    func requestCodable<JSON: Codable>(url: URL,
                                       type: JSON.Type, success: @escaping (_ json: JSON) -> (),
                                       failure: @escaping(_ error: NetworkError?) -> () )  {
        session.dataTask(with: url) { data, response, error in
            guard error == nil else { return failure(.badResponse) }
            guard let status = response as? HTTPURLResponse, self.statusOk.contains(status.statusCode) else { return failure(.badStatus) }
            
            if let data, let items = try? JSONDecoder().decode(JSON.self, from: data) {
                success(items)
            } else {
                return failure(.badJson)
            }
            return failure(.unknown)
        }.resume()
    }
    
    func requestImage(url: URL?, success: @escaping (_ image: UIImage) -> (),
                      failure: @escaping(_ error: NetworkError?) -> () )  {
        guard let url else {return failure(.badURL) }
        
        session.dataTask(with: url) { data, response, error in
            guard error == nil else { return failure(.badResponse ) }
            guard let status = response as? HTTPURLResponse, self.statusOk.contains(status.statusCode) else { return failure(.badStatus) }
            
            if let data, let image = UIImage(data: data) {
                   return success(image)
            } else {
                return failure(.badImage)
            }
        }.resume()
        
    }
}

enum NetworkError: Error {
    case badResponse, badStatus, badJson, badImage, unknown, badURL
} 
Añadido features de añadir personaje a favoritos y su persistencia en archivo local (json)
final class Persistence: FavouritesPersistence {
    static let shared = Persistence()
    
    func loadFavourites() throws -> [HeroeData] {
        if FileManager.default.fileExists(atPath: URL.favouritesPath.path()) {
            do {
                let data = try Data(contentsOf: .favouritesPath)
                return try JSONDecoder().decode([HeroeData].self, from: data)
            } catch {
                print("error loading favourites")
            }
        }
        return []
    }
    
    func saveFavourites(_ heroes: [HeroeData]) {
        do {
            let data = try JSONEncoder().encode(heroes)
            try data.write(to: .favouritesPath, options: .atomic)
        } catch {
            return
        }
    }
}

protocol FavouritesPersistence {
    func loadFavourites() throws -> [HeroeData]
    func saveFavourites(_ heroes: [HeroeData])
}
Añadida feature de descargar más personajes al llegar al final de scroll
func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
            let currentOffset = scrollView.contentOffset.y
            let maximumOffset = scrollView.contentSize.height - scrollView.frame.size.height
            
            if maximumOffset - currentOffset <= 50 {
                self.modelLogic.fetchHeroes()
            }
        }
Añadido model Logic

MarvelApp
Pablomarke

¿Quieres recibir posts, cheatCodes, enlaces y katas en Swift para practicar?

Quincenalmente recibirás en tu correo electrónico la newsletter, solo hace falta tu correo electrónico.