使用AlamofireObjectMapper / ObjectMapper从数组对象获取价值(Swift-iOS) [英] Get value from array objects with AlamofireObjectMapper/ObjectMapper (swift - iOS)

查看:111
本文介绍了使用AlamofireObjectMapper / ObjectMapper从数组对象获取价值(Swift-iOS)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是这个映射器的新手,太困惑了。我有一个API请求(给定标题),API返回以下内容:

I'm new with this mapper thing and too confused. I have an API request, given a Title, the API return this:

{
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;

}

所以我创建了为此结果的可映射类:

So I've created a mappable class for this result:

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个此属性。但对于下一次搜索,我将全部需要。那正确吗?还是应该创建两个单独的类来处理每种响应?

Question: I mapped this movie class like this, but for the search by title I'll only have 4 of this attributes. But for the next search I'll need all of them. Is that right? Or should I create two separate classes to deal with each kind of response?

好!我正在SearchTableViewController上显示此搜索的结果。现在,我想显示这部电影的更多详细信息(此先前响应中搜索数组的任何电影)。为此,API提供了另一种搜索类型,即通过imdbID进行搜索。因此,我在SearchTableViewController上创建了一个序列,以获取此ID并传递给MovieViewController(将显示这些详细信息的视图):

Ok! I'm showing the result of this search on my SearchTableViewController. Now I want to show more details of this movie (any movie of the "Search" array on this previous response). To do that, the API offers another type of search, that is search by imdbID. So I've created a segue on my SearchTableViewController to get this ID and pass to my MovieViewController (the view that will show these details):

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请求的功能是:

My function for this API request is:

//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)
        }

    }

好的,鉴于我所拥有的内容,让我们谈谈我的问题。 ..

OK, given this overview of what I have, let's talk about my problem...

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

When I search by ID, the Json response is that:

{
    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请求的:

My problem

I did this alamofire request for the search by ID:

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?

    }
}

很明显,我没有我想要的数据在这里。所以...

Obviously, I'm not getting the data that I want it here. So...


问题:

Questions:




  1. 如何使用可映射类获取Json [ Search]的值?

  2. 是否必须更改现有的类?如果是,那么如何以及为什么?

我对这么多层次感到困惑。另外,我是Swift的新手,并且是第一次使用此ObjectMapper。抱歉,在这里有这么多代码,但是我想我必须解释一下我的情况。

I'm too confused by so many layers. Also, I'm beginner with swift and I'm using this ObjectMapper for the first time. Sorry for so much code here, but I think I had to explain my scenario.

推荐答案

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

You have to map each property with correct data type of that property. One of the objects in your response contains a Boolean value ( For ex. "Response"), but you are declaring it as a String. We have to match the data type of the property exactly, else the object will be nil and will not be mapped.

通过id搜索响应与您的映射器类不匹配。

Also search by id response does not match your mapper class.

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

let Result = response.result.value is wrong. response.result.value would yield you SearchResponse object.

底线

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

You have to get the mapping part right first. Any mismatching types will be not be mapped. Using response object will give you the whole object with all the mappings instead of the JSON obviously. So it should be: let movie = response.result.value. Then you access movie's properties like for ex. movie.actors

这篇关于使用AlamofireObjectMapper / ObjectMapper从数组对象获取价值(Swift-iOS)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆