ios - 使用 Alamofire 和 AlamofireObjectMapper 映射两种响应(iOS - swift)

标签 ios swift api casting alamofire

因此,我正在制作一个 iOS 应用程序,用于在 imdb 数据库上搜索电影(使用 omdb api),并且用户可以保存收藏夹。

通过imdbTitle搜索,请求url为“https://www.omdbapi.com/?s=(imdbTitle)&type=movie”,例如,如果imdbTitle =“arq”,则响应为:

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

但是为了保存电影,我必须通过imdbID搜索,url:“https://www.omdbapi.com/?i=(imdbID )”,如果imdbID是搜索到的电影中的imdbID,imdbID = tt3829612,则响应为:

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

所以,我的 Movie 类必须具有以下属性:海报、标题、运行时、流派、导演、 Actor 、情节、已发布、imdbID 和 imdbRating(要在我的 UI View 上显示此属性,当然,imdbID 除外)

我是一个初学者,我对所有这些事情感到非常困惑(以前从未使用过 API 数据)。

无论如何,经过大量搜索后,我发现有一种方法可以使用 AlamofireObjectMapper 将此响应作为数组获取。

我已经有了我的请求功能:

func searchMoviesOnJson(imdbTitle: String, completionHandler: @escaping (Dictionary<String, Any>?) -> ()) {

let urlByName: String = "https://www.omdbapi.com/?s=\(imdbTitle)&type=movie"

//returns a list of movies that contains the title searched
//------------------------------------------------

Alamofire.request(urlByName).responseJSON {
    response in

    switch response.result {

    case .success(let value):
        let moviesJSON = value
        completionHandler(moviesJSON as? Dictionary<String, Any>)

    case .failure(_):
        completionHandler(nil)
    }
}
//------------------------------------------------

}
func getMovieFromJson(imdbID: String, completionHandler: @escaping (Dictionary<String, String>) -> ()) {

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

//returns a single movie information
//------------------------------------------------
Alamofire.request(urlById).responseJSON {
    response in

    if let moviesJSON = response.result.value {
        completionHandler(moviesJSON as! Dictionary<String, String>)
    }
}
//------------------------------------------------
}

那么,有人可以向我解释一下(就像向 child 解释一样)我该如何进行此映射吗?我创建了一个 Movie.swift,在这个文件中我将放置我的 Movie 类和 MovieDAO 类。

如何使用 AlamofireObjectMapper 实现这两个类以及我必须在请求方法中更改谁?

更新:

class Movie {

let poster: String?
let title: String?
let runtime: String?
let genre: String?
let director: String?
let actors: String?
let plot: String?
let released: String?
let imdbID: String?
let imdbRating: String?


init(poster: String?, title: String?, runtime: String?, genre: String?, director: String?, actors: String?, plot: String?, released: String?, imdbID: String?, imdbRating: String?) {

    //checking if is nil

    if let isPoster = poster {
        self.poster = isPoster
    } else {
        self.poster = nil
    }

    if let isTitle = title {
        self.title = isTitle
    } else {
        self.title = nil
    }

    if let isGenre = genre {
        self.genre = isGenre
    } else {
        self.genre = nil
    }

    if let isRuntime = runtime {
        self.runtime = isRuntime
    } else {
        self.runtime = nil
    }

    if let isDirector = director {
        self.director = isDirector
    } else {
        self.director = nil
    }

    if let isActors = actors {
        self.actors = isActors
    } else {
        self.actors = nil
    }

    if let isPlot = plot {
        self.plot = isPlot
    } else {
        self.plot = nil
    }

    if let isReleased = released {
        self.released = isReleased
    } else {
        self.released = nil
    }

    if let isImdbID = imdbID {
        self.imdbID = isImdbID
    } else {
        self.imdbID = nil
    }

    if let isImdbRating = imdbRating {
        self.imdbRating = isImdbRating
    } else {
        self.imdbRating = nil
    }
}
}

更新2

我按照你所说的那样声明了变量 movieDetail,但是 xcode 显示错误并建议我可以添加参数,所以我这样做了,但问题没有解决。

enter image description here

最佳答案

您必须解析收到的 JSON: 例如如果收到的 json 是:

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

正如您所提到的,如果您已将 json 响应存储在 NSDictionary 中

您可以通过以下方式访问搜索结果的值

var moviesArray = [Movie]() //array of your Movie class

var imdbIdArray = [String]()


if let searchResults = moviesJSON["Search"] as? NSArray {
    for searchResult in searchResults {
      let movieResult = searchResult as! Dictionary<String,String>
      let movieDetail = Movie()
      movieDetail.title = movieResult["Title"]
      movieDetail.type = movieResult["Type"] 
    //similarly you can do it for other params as well
      moviesArray.append(movieDetail)
      let imdbId = movieResult["imdbId"]
      imdbIdArray.append(imdbId)
    }

}

class Movie: NSObject {
    var title = String()
    var type = String()
}

现在 movieArray 由结果集中返回的电影列表组成。

关于ios - 使用 Alamofire 和 AlamofireObjectMapper 映射两种响应(iOS - swift),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43455203/

相关文章:

python - 简单 Flask python 后端中 POST 方法的 KeyError

javascript - 如何检查 Facebook 粉丝专页是否被点赞

ios - 将 plist 中保存的所有图像加载到 tableview 中

iOS/Swift - 向下/向上滚动时隐藏/显示 UITabBarController

ios - 无法从 SecItemCopyMatching 检索数据

ios - Twitter 和 Facebook 不会出现在 UIActivityViewController Swift 3.0 上

ios - 如何防止 UITabBarController 更新 subview ?

java - 为什么 .size() 不是集合上的 getSize()

ios - 添加 appledoc 时出错

ios - xcode如何在数据库中的 Collection View 单元格中显示图像