在Recipe.swift的模型文件中,有如下内容:
import UIKit
import ObjectMapper
//json解析
//为了支持映射,类或者构造体只需要实现Mappable协议,
struct RecipeList: Mappable
{
//声明
var code:String?
var msg:String? //一般变量
var data :[Recipe]? // Recipe的数组
//协议包含的第一个方法
init?(map: Map) {
}
//协议包含的第一个方法,ObjectMapper使用自定义的<- 运算符来声明成员变量和 JSON 的映射关系。
mutating func mapping(map: Map) {
//映射关系,没有加入Recipe的数组
data <- map["data"]
code <- map["code"]
msg <- map["msg"]
}
}
//大多数情况下你都可以使用框架提供的转换类 TransformOf 来快速的实现一个期望的转换。
//这里有一个transfromOfTupleAndString()的方法,供下面的调用,方法的类型是TransformOf<(CGFloat,CGFloat,CGFloat),String>,是一种泛型。
func transfromOfTupleAndString()->TransformOf<(CGFloat,CGFloat,CGFloat),String>{
// TransformOf 的初始化需要两个类型和两个闭包。两个类型声明了转换的目标类型和源类型,闭包则实现具体转换逻辑。
//(CGFloat,CGFloat,CGFloat)是screeningId的类型
return TransformOf<(CGFloat,CGFloat,CGFloat),String>.init(fromJSON: { (screenID) -> (CGFloat, CGFloat, CGFloat)? in
// 把值从 String? 转成 (CGFloat,CGFloat,CGFloat)?
let defaultV:CGFloat = 3
//screenID 就是要转换的String,也就是screeningId
if let string = screenID
{
let strArr = string.components(separatedBy: ",")
if strArr.count >= 3
{
let value1 = (strArr[0] as NSString).floatValue
let value2 = (strArr[1] as NSString).floatValue
let value3 = (strArr[2] as NSString).floatValue
return (CGFloat(value1),CGFloat(value2),CGFloat(value3))
}
}
return (defaultV,defaultV,defaultV)
}, toJSON: { (value) -> String? in
// 把值从 (CGFloat,CGFloat,CGFloat)? 转成 String?
let (value1,value2,value3) = value!
return "\(value1),\(value2),\(value3)"
})
}
struct Recipe: Mappable {
//Recipe的数组里的变量声明
var detailsUrl:String?
var clickCount:Int?
var id:Int?
var categoryID:Int?
var description:String?
var releaseDate:String?
var type:String?
var screeningId:(CGFloat,CGFloat,CGFloat)?
var maketime:String?
var name:String?
var shareCount:Int?
var createDate:TimeInterval?
var modifyDate:TimeInterval?
var imageUrl:String?
var title:String?
init?(map: Map) {
}
mutating func mapping(map: Map) {
//Recipe的数组的映射关系
detailsUrl <- map["detailsUrl"]
clickCount <- map["clickCount"]
id <- map["id"]
categoryID <- map["categoryID"]
description <- map["description"]
releaseDate <- map["releaseDate"]
type <- map["type"]
maketime <- map["maketime"]
name <- map["name"]
shareCount <- map["shareCount"]
createDate <- map["createDate"]
modifyDate <- map["modifyDate"]
imageUrl <- map["imageUrl"]
title <- map["title"]
//这里的transfromOfTupleAndString() 进行自定义转换规则处理的调用
screeningId <- (map["screeningId"],transfromOfTupleAndString())
}
}
在 RecipeViewController中使用这个模型文件:
先创建相应的实例,
var recipeList = [Recipe]()
/
// MARK: - 网络请求
func loadNewData()
{
currentpage = 0
recipeList.removeAll()
loadMoreData()
}
这里在第一次请求数据的时候会将以前的recipeList 对象进行清空。recipeList对象在这下面有使用:
extension RecipeViewController:UICollectionViewDelegate,UICollectionViewDataSource
{
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return recipeList.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: ArticleCellID, for: indexPath) as! ArticleCell
return cell
}
func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
guard let cell = cell as? ArticleCell else{
return
}
cell.recipeData = recipeList[(indexPath as NSIndexPath).item]
}
func collectionView(_ collectionView: UICollectionView, didEndDisplaying cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
guard let cell = collectionView.cellForItem(at: indexPath) as? ArticleCell else{
return
}
cell.foodImageView.image = nil
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
if let id = recipeList[(indexPath as NSIndexPath).item].id {
performSegue(withIdentifier: "showDetail", sender: id)
}
}
}