如何实例化映射类? (迅速 - alamofireObjectMapper)

Posted

技术标签:

【中文标题】如何实例化映射类? (迅速 - alamofireObjectMapper)【英文标题】:How to instantiate a mapped class? (swift - alamofireObjectMapper) 【发布时间】:2017-05-01 03:50:25 【问题描述】:

我有一个名为 Movie 的映射类,我提出了一个返回此类型的 API 请求。如何使用我的 API 响应的值实例化此类?

电影映射类:

class Movie: Mappable 

var posterURL  : String?
var title      : String?
var runtime    : String?
var director   : String?
var actors     : String?
var genre      : String?
var plot       : String?
var production : String?
var released   : String?
var year       : String?
var imdbID     : String?
var imdbRating : String?

required init?(map: Map) 



func mapping(map: Map) 
    posterURL  <- map["Poster"]
    title      <- map["Title"]
    runtime    <- map["Runtime"]
    director   <- map["Director"]
    actors     <- map["Actors"]
    genre      <- map["Genre"]
    plot       <- map["Plot"]
    production <- map["Production"]
    released   <- map["Released"]
    year       <- map["Year"]
    imdbID     <- map["imdbID"]
    imdbRating <- map["imdbRating"]
  

在我的 MovieViewController 中,我正在调用 API 并为我的出口标签传递值。 但我想通过分配在我的 API 调用中获得的值来实例化这个类。

func getMovieById() 

    let requestURL = "https://www.omdbapi.com/?i=\(String(describing: imdbID!))"
    print("URL: \(requestURL)")


    Alamofire.request(requestURL).responseObject (response: DataResponse<Movie>) in
        print("|MovieController| Response is: \(response)")

        DispatchQueue.main.async 
            let spinnerActivity = MBProgressHUD.showAdded(to: self.view, animated: true)
            spinnerActivity.label.text = "Loading";
            spinnerActivity.isUserInteractionEnabled = false;
        

        let movie = response.result.value


        if let posterURL = movie?.posterURL 
            print("Poster URL: \(posterURL)")

            let imgStg: String = posterURL
            print("---> Image string: \(imgStg)")
            let imgURL: URL? = URL(string: imgStg)
            let imgSrc = ImageResource(downloadURL: imgURL!, cacheKey: imgStg)

            self.movPosterImageView.layer.cornerRadius = self.movPosterImageView.frame.size.width/2
            self.movPosterImageView.clipsToBounds = true

            //image cache with KingFisher
            self.movPosterImageView.kf.setImage(with: imgSrc)

        


        if let title = movie?.title 
            print("Title: \(title)")
            self.movTitleLabel.text = title
        


        if let runtime = movie?.runtime 
            print("Runtime: \(runtime)")
            self.movRuntimeLabel.text = runtime
        

        if let genre = movie?.genre 
            print("Genre: \(genre)")
            self.movGenreLabel.text = genre
        

        if let plot = movie?.plot 
            print("Plot: \(plot)")
            self.movPlotTextView.text = plot
        

        if let rating = movie?.imdbRating 
            print("Rating: \(rating)")
            self.movRatingLabel.text = rating
        

        if let director = movie?.director 
            print("Director: \(director)")
            self.movDirectorLabel.text = director
        

        if let production = movie?.production 
            print("Production: \(production)")
            self.movProductionLabel.text = production
        

        if let actors = movie?.actors 
            print("Actors: \(actors)")
            self.movActorsLabel.text = actors
        

        if let released = movie?.released 
            print("Released in: \(released)")
            self.movReleasedLabel.text = released
        





        DispatchQueue.main.async 
            MBProgressHUD.hide(for: self.view, animated: true)
        

    //Alamofire.request

//getMovieByID()

应该是这样的

let movieDetails: Movie = Movie(plot = movie?.plot, title = movie?.title, ...)

如何使用可映射类做到这一点?


更新

我正在尝试组织这些东西,而且我必须重用代码,所以这个内部函数对我来说似乎更好。因此,我开始分离 API 调用,如下所示:

文件:OMDB.swift

import Foundation
import Alamofire
import AlamofireObjectMapper



func getMovieIdFromAPI(imdbID: String, completionHandler: @escaping (Movie) -> () ) 

    let requestURL = "https://www.omdbapi.com/?i=\(imdbID)"

    print("|getMovieIdFromAPI|   URL: \(requestURL)")


    Alamofire.request(requestURL).responseObject (response: DataResponse<Movie>) in
        print("|Alamofire request|   Response is: \(response)")

        if let movieResult = response.result.value
            completionHandler(movieResult)
        
      
  

下一步,我正在尝试创建一个 MovieDAO,在这里我必须实例化我的对象,对吗?所以,在我的 Movie 类所在的同一个文件中,我使用这个函数创建了一个 MovieDAO 类:

class MovieDAO 

func getMovieDetailed<Movie: Mappable>(imdbID: String, completionHandler: @escaping (Movie) -> ()) 

    getMovieIdFromAPI(imdbID: imdbID, completionHandler: 
        (movieResult) in

        let mapper = Mapper<Movie>()
        let movieDetailed = mapper.map(movieResult)!



        completionHandler(movieDetailed)

    )

  


但我没有很好地理解答案,xcode给了我一个错误

   let movieDetailed = mapper.map(movieResult)!
                              ^Error: Argument labels '(_:)' do not match any available overloads

您能解释一下我如何使用在这种情况下给出的答案吗?

【问题讨论】:

【参考方案1】:

ObjectMapper 可帮助您获取模型类的实例,并根据您的 API 响应设置属性值。您需要执行最后一步,告诉 ObjectMapper 使用您提供的 json 执行“映射”过程。您可以使用此通用方法解析任何 Mappable 类的响应

static func parseModel<Model: Mappable>(modelResponse modelResponse: AnyObject, modelClass: Model.Type) ->  Model? 

    let mapper = Mapper<Model>()
    let modelObject = mapper.map(modelResponse)!

    return modelObject

【讨论】:

您好,感谢您的回答。我的目标是组织我的功能分开。看看你能不能再帮我一次,看看我在我的问题中所做的更新。

以上是关于如何实例化映射类? (迅速 - alamofireObjectMapper)的主要内容,如果未能解决你的问题,请参考以下文章

Mapper(DAO层)接口如何实例化

随机获取“网络连接丢失。”迅速使用“Alamofire.request”

如何在 Swift 5 中使用 Alamofire 解析 json

无法使用 alamofire 深入了解响应 json。迅速

如何在 Java 中实例化一组地图?

使用 Alamofire 使用 JSON 数组填充 UIPickerView 时遇到问题 |迅速