【问题标题】:Get value from array objects with AlamofireObjectMapper/ObjectMapper (swift - iOS)使用 AlamofireObjectMapper/ObjectMapper 从数组对象中获取值(swift - iOS)
【发布时间】:2017-09-27 00:10:00
【问题描述】:

我是这个映射器的新手,太困惑了。我有一个 API 请求,给定一个 Title,API 返回这个:

{
Response = True;
Search =     (
            {
        Poster = "https://images-na.ssl-images-amazon.com/images/M/MV5BMjAxODQ2MzkyMV5BMl5BanBnXkFtZTgwNjU3MTE5OTE@._V1_SX300.jpg";
        Title = ARQ;
        Type = movie;
        Year = 2016;
        imdbID = tt5640450;
    },
            {
        Poster = "N/A";
        Title = Arq;
        Type = movie;
        Year = 2011;
        imdbID = tt2141601;
    },
            {
        Poster = "N/A";
        Title = "A.R.Q.";
        Type = movie;
        Year = 2015;
        imdbID = tt3829612;
    }
);
totalResults = 3;

}

所以我为这个结果创建了一个可映射的类:

class SearchResponse: Mappable {
    var isSuccess  : String?
    var searchArray: [Movie]?
    var searchCount: String?

    required init?(map: Map) {
    }

    func mapping(map: Map) {
        isSuccess   <- map["Response"]
        searchArray <- map["Search"]
        searchCount <- map["totalResults"]
    }
}

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 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"]
        year       <- map["Year"]
        imdbID     <- map["imdbID"]
        imdbRating <- map["imdbRating"]
    }
}

问题:我像这样映射了这个电影类,但是对于按标题搜索,我将只有 4 个这样的属性。但是对于下一次搜索,我需要所有这些。那正确吗?还是应该创建两个单独的类来处理每种响应?

好的!我在我的 SearchTableViewController 上显示了这个搜索的结果。现在我想展示这部电影的更多细节(之前响应中“搜索”数组的任何电影)。为此,API 提供了另一种类型的搜索,即按 imdbID 搜索。所以我在我的 SearchTableViewController 上创建了一个 segue 来获取这个 ID 并传递给我的 MovieViewController(将显示这些细节的视图):

let searchSegue = "segueFromSearch"

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    let searchIndex = tableView.indexPathForSelectedRow?.row
    let movie = movies?[searchIndex!]
    let selectedImdbID = movie?.imdbID

    print("|Table View Controler| Segue. IMDB_ID: \(String(describing: selectedImdbID))")

    if segue.identifier == searchSegue {
        if let destination = segue.destination as? MovieViewController {

            destination.imdbID = selectedImdbID!

            print("|Table View Controler| Inside of if let. Debug print: I get til here. imdbID = \(selectedImdbID!)")
        }

    }
}

我对此 API 请求的功能是:

//The movieSearched variable is the text typed on my searchBar
let URL = "https://www.omdbapi.com/?s=\(movieSearched)&type=movie"
    Alamofire.request(URL).responseObject{ (response: DataResponse<SearchResponse>) in
        print("response is: \(response)")

        switch response.result {
        case .success(let value):
            let searchResponse = value
            self.movies = (searchResponse.searchArray)
            self.searchTableView.reloadData()


        case .failure(let error):
            let alert = UIAlertController(title: "Error", message: "Error 4xx / 5xx: \(error)", preferredStyle: UIAlertControllerStyle.alert)
            alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: nil))
            self.present(alert, animated: true, completion: nil)
        }

    }

好的,鉴于我所拥有的概述,让我们谈谈我的问题......

当我按 ID 搜索时,Json 响应是:

{
    Actors = "Robbie Amell, Rachael Taylor, Shaun Benson, Gray Powell";
    Awards = "N/A";
    BoxOffice = "N/A";
    Country = "USA, Canada";
    DVD = "16 Sep 2016";
    Director = "Tony Elliott";
    Genre = "Sci-Fi, Thriller";
    Language = English;
    Metascore = "N/A";
    Plot = "Trapped in a lab and stuck in a time loop, a disoriented couple fends off masked raiders while harboring a new energy source that could save humanity.";
    Poster = "https://images-na.ssl-images-amazon.com/images/M/MV5BMjAxODQ2MzkyMV5BMl5BanBnXkFtZTgwNjU3MTE5OTE@._V1_SX300.jpg";
    Production = Netflix;
    Rated = "N/A";
    Ratings =     (
        {
            Source = "Internet Movie Database";
            Value = "6.4/10";
        },
        {
            Source = "Rotten Tomatoes";
            Value = "60%";
        }
    );
    Released = "16 Sep 2016";
    Response = True;
    Runtime = "88 min";
    Title = ARQ;
    Type = movie;
    Website = "N/A";
    Writer = "Tony Elliott";
    Year = 2016;
    imdbID = tt5640450;
    imdbRating = "6.4";
    imdbVotes = "17,481";
}

我的问题

我为按 ID 搜索做了这个 alamofire 请求:

func getMovieById() {

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

    Alamofire.request(URL).responseObject{ (response: DataResponse<SearchResponse>) in
        print("|MovieController| Response is: \(response)")

        let Result = response.result.value
        print("Result for search by id: \(String(describing: Result!.searchArray))")

        // Have to get the values here, right?

    }
}

显然,我在这里没有得到我想要的数据。所以...

问题:

  1. 如何使用可映射类获取 Json["Search"] 的值?
  2. 我必须更改我拥有的课程吗?如果是,如何以及为什么?

我对这么多层次感到困惑。另外,我是 swift 的初学者,我第一次使用这个 ObjectMapper。抱歉这里有这么多代码,但我想我必须解释一下我的场景。

【问题讨论】:

  • 使用 Alamofire.request(URL).responseObject 代替 Alamofire.request(URL).responseJSON。

标签: ios json swift alamofire objectmapper


【解决方案1】:

您必须将每个属性映射到该属性的正确数据类型。您的响应中的一个对象包含 Boolean 值(例如“响应”),但您将其声明为字符串。我们必须完全匹配属性的数据类型,否则对象将是 nil 并且不会被映射。

另外按 id 搜索响应与您的映射器类不匹配。

let Result = response.result.value 是错误的。 response.result.value 将产生 SearchResponse 对象。

底线

您必须首先正确处理映射部分。任何不匹配的类型都不会被映射。使用响应对象将为您提供具有所有映射的整个对象,而不是 JSON。所以应该是:let movie = response.result.value。然后您访问电影的属性,例如ex. movie.actors

【讨论】:

  • 按标题搜索工作正常,返回的正是我想要的。我的问题是如何使用 ID 执行此请求以使用 responseObject 获取字典数组。如果我使用 responseJSON,我会得到我想要的:Alamofire.request(URL).responseJSON { response in if let json = response.result.value { let movieJSON = json as? [String : AnyObject] print(movieJSON! as Any) } } 但是如何使用 responseObject 来做到这一点?
  • 您必须先正确处理映射部分。任何不匹配的类型都不会被映射。使用响应对象将为您提供具有所有映射的整个对象,而不是 JSON。所以应该是:let movie = response.result.value。然后您访问电影的属性,例如 for ex。 movie.actors
猜你喜欢
  • 1970-01-01
  • 2017-11-25
  • 2021-04-01
  • 1970-01-01
  • 2015-12-11
  • 2015-11-27
  • 1970-01-01
  • 2022-06-28
  • 1970-01-01
相关资源
最近更新 更多