我正在学习如何使用VIPER架构通过"电影数据库"api在表视图中显示数据,但我还没有学会如何解码和序列化JSON。我分享我的课程。
JSON响应
{
"page": 1,
"results": [
{
"adult": false,
"backdrop_path": "/aTovumsNlDjof7YVoU5nW2RHaYn.jpg",
"genre_ids": [
27,
53,
10749
],
"id": 616820,
"original_language": "en",
"original_title": "Halloween Ends",
"overview": "Four years after the events of Halloween in 2018, Laurie has decided to liberate herself from fear and rage and embrace life. But when a young man is accused of killing a boy he was babysitting, it ignites a cascade of violence and terror that will force Laurie to finally confront the evil she can’t control, once and for all.",
"popularity": 4845.496,
"poster_path": "/3uDwqxbr0j34rJVJMOW6o8Upw5W.jpg",
"release_date": "2022-10-12",
"title": "Halloween Ends",
"video": false,
"vote_average": 6.9,
"vote_count": 417
},
{
"adult": false,
"backdrop_path": "/5GA3vV1aWWHTSDO5eno8V5zDo8r.jpg",
"genre_ids": [
27,
53
],
"id": 760161,
"original_language": "en",
"original_title": "Orphan: First Kill",
"overview": "After escaping from an Estonian psychiatric facility, Leena Klammer travels to America by impersonating Esther, the missing daughter of a wealthy family. But when her mask starts to slip, she is put against a mother who will protect her family from the murderous “child” at any cost.",
"popularity": 3138.264,
"poster_path": "/pHkKbIRoCe7zIFvqan9LFSaQAde.jpg",
"release_date": "2022-07-27",
"title": "Orphan: First Kill",
"video": false,
"vote_average": 6.8,
"vote_count": 1046
},
{
"adult": false,
"backdrop_path": "/etP5jwlwvkNhwe7jnI2AyA6ZKrR.jpg",
"genre_ids": [
878
],
"id": 575322,
"original_language": "en",
"original_title": "Звёздный разум",
"overview": "After depleting Earth's resources for centuries, humankind's survival requires an exodus to outer space. An international expedition is quickly formed to find a suitable new planet, but when plans go awry, the crew is suddenly stranded without power on a strange planet, where something unimaginable lies in wait.",
"popularity": 2457.191,
"poster_path": "/aVLV38txajXhEy2qNEClPIsDbAH.jpg",
"release_date": "2022-01-06",
"title": "Project Gemini",
"video": false,
"vote_average": 5.5,
"vote_count": 98
}
],
"total_pages": 35518,
"total_results": 710341
}
交互程序TMDB
import Foundation
protocol AnyInteractor{
var presenter : AnyPresenter? {get set}
func downloadMovies()
}
class MovieInteractor : AnyInteractor {
var presenter : AnyPresenter?
func downloadMovies(){
guard let url = URL(string: "https://api.themoviedb.org/3/movie/popular?api_key=115962553d2044ca5dd8433fb4bc3e29")
else{
return
}
let task = URLSession.shared.dataTask(with: url) { [weak self] data, response, error in
guard let data = data, error == nil else {
self?.presenter?.interactorDidDownloadMovie(result:
.failure(NetworkError.networkFailed))
return
}
do{
let movies = try JSONDecoder().decode([Result].self, from: data)
self?.presenter?.interactorDidDownloadMovie(result: .success(movies))
}catch{
self?.presenter?.interactorDidDownloadMovie(result: .failure(NetworkError.parsingFailed))
}
}
task.resume()
}
}
演示者MDB
import Foundation
enum NetworkError : Error {
case networkFailed
case parsingFailed
}
protocol AnyPresenter {
var router : AnyRouter? {get set}
var interactor : AnyInteractor? {get set}
var view : AnyView? {get set}
func interactorDidDownloadMovie(result: Result<Movies: [Results], Error>)
}
class MoviePresenter : AnyPresenter {
var router: AnyRouter?
var interactor : AnyInteractor? {
didSet{
interactor?.downloadMovies()
}
}
var view: AnyView?
func interactorDidDownloadMovie(result: Result<Movies: [Results], Error>){
switch result{
case .success(let movies):
view?.update(with: movies)
case.failure(_):
view?.update(with: "Intenta más tarde")
}
}
}
实体TMDB
import Foundation
struct Movies: Codable {
let page: Int
let results: [Results]
let totalPages, totalResults: Int
}
struct Results: Codable {
let adult: Bool
let backdropPath: String
let genreIDS: [Int]
let id: Int
let originalTitle, overview: String
let popularity: Double
let posterPath, releaseDate, title: String
let video: Bool
let voteAverage: Double
let voteCount: Int
}
路由器MDB
import Foundation
import UIKit
typealias EntryPoint = AnyView & UIViewController
protocol AnyRouter{
var entry: EntryPoint? {get}
static func startExecution() -> AnyRouter
}
class MovieRouter : AnyRouter {
var entry : EntryPoint?
static func startExecution() -> AnyRouter {
let router = MovieRouter()
var view: AnyView = ViewTMDB() as! AnyView
var presenter : AnyPresenter = MoviePresenter()
var interactor : AnyInteractor = MovieInteractor()
view.presenter = presenter
presenter.view = view
presenter.router = router
presenter.interactor = interactor
interactor.presenter = presenter
router.entry = view as? EntryPoint
return router
}
}
我真的不知道如何使用VIPER架构在表视图中显示这个JSON响应。
谢谢。
看看Codable
协议。对于从JSON反序列化对象,您将特别需要Decodable
协议。
您可以采取一些简单的步骤来使结构符合可解码协议,然后使用JSONDecoder
类的实例来解码对象。
如何在表视图中显示您的数据,是否使用VIPER,是一个单独的问题。(我建议你尽快逃离VIPER。这不是我推荐的设计模式。(