【问题标题】:How to instantiate a mapped class? (swift - alamofireObjectMapper)如何实例化映射类? (迅速 - 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

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

【问题讨论】:

    标签: swift alamofire objectmapper


    【解决方案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
    }
    

    【讨论】:

    • 您好,感谢您的回答。我的目标是组织我的功能分开。看看你能不能再帮我一次,看看我在我的问题中所做的更新。
    猜你喜欢
    • 2016-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-16
    • 1970-01-01
    • 2016-09-09
    • 2016-10-22
    相关资源
    最近更新 更多