如何使用来自Web服务的数组填充TableViewCell?

时间:2017-07-17 15:45:52

标签: arrays swift rest uitableview

我需要使用存储在数组中的信息填充TableViewCell,该数组符合我从REST API带来的数据。我试图从服务中为每个特定类别的数组创建一个类,然后将此数组放在' for循环中。然后尝试填充TableViewCell。但我认为我正确地声明了我的参数,因为我有很多错误。

我遵守的课程是:

class CouponDesc : AnyObject {
    var description: String

    init(description: String) {
        self.description = description
    }
}

class CouponCat : AnyObject {
    var category: String

    init(category: String) {
        self.category = category
    }
}

class CouponTitle : AnyObject {
    var title: String

    init(title: String) {
        self.title = title
    }
}

我需要从网络服务中获取的类别包括:优惠券中的标题,描述和类别,这就是我制作这些课程的原因。

我制作的for循环是:

for index in mainCoupon {
    let description = (mainCoupon[index as! Int] as AnyObject).value(forKey: "promoDescription") as! String
    let newCoupon = CouponDesc(description: description)
    self.couponsDesc.append(newCoupon)
}

for index in mainCoupon {
    let title = (mainCoupon[index as! Int] as AnyObject).value(forKey: "nameStore") as! String
    let newCoupon = CouponTitle(title: title)
    self.couponsTitle.append(newCoupon)
}

for index in mainCoupon {
    let category = (mainCoupon[index as! Int] as AnyObject).value(forKey: "category") as! String
    let newCoupon = CouponCat(category: category)
    self.couponsCat.append(newCoupon)
}

mainCoupon是来自REST API的数组:

let miURL = URL(string: RequestConstants.requestUrlBase)
let request =  NSMutableURLRequest(url: miURL!)
request.httpMethod = "GET"
if let data = try? Data(contentsOf: miURL! as URL) {
    do {
        let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? NSDictionary
        let parseJSON = json
        let object = parseJSON?["object"] as! NSDictionary
        let mainCoupon = object["mainCoupon"] as! NSArray

我认为我的错误在于本节:

let category = (mainCoupon[index as! Int] as AnyObject).value(forKey: "category") as! String

因为我不确定如何将该类别分配到优惠券的数组中。最后,我将数组分配给TableViewCell的地方是:

 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! HomeTableViewCell

    cell.couponImg.image = couponsImg[indexPath.row]
    cell.couponTitle.text = couponsTitle[indexPath.row] as AnyObject as? String
    cell.couponDescription.text = couponsDesc[indexPath.row] as AnyObject as? String
    cell.couponCategory.text = couponsCat[indexPath.row] as AnyObject as? String

    return cell
}

此外,我不确定我是否将正确的值输入细胞:

cell.couponTitle.text = couponsTitle[indexPath.row] as AnyObject as? String'

我不知道这是不是最好的方式。

我收到的错误是:

  

无法转换类型' __ NSDictionaryM'的值(0x10a1aa2b0)到' NSNumber' (0x1093a14a8)。

这是因为这一行:

let description = (mainCoupon[index as! Int] as AnyObject).value(forKey: "promoDescription") as! String'

我的TableViewCell的类是这样的:

class HomeTableViewCell: UITableViewCell {
    @IBOutlet weak var couponImg: UIImageView!
    @IBOutlet weak var couponTitle: UILabel!
    @IBOutlet weak var couponDescription: UITextView!
    @IBOutlet var starButtons: [UIButton]!
    @IBOutlet weak var couponCategory: UILabel!

REST Example

1 个答案:

答案 0 :(得分:2)

不需要在这里继承AnyObject class CouponDesc : AnyObject

无需拥有3个不同的对象来存储您的数据;您的数据简单而不复杂。但是,如果需要,您仍然可以使用三个对象,但您应该稍后对它们进行分组,如:

class CouponMainDescription {
  let desc: CouponDesc
  let title: CouponTitle
  // on and on 
}

我将使用一个简单的struct with a failable init return nil,如果其中一个键的值为nil

struct CouponDescription {
    let stars:Int
    let distance:Double
    let address:String
    // do the same for other data members 
    init?(_ dict:[String:Any]?) {
          guard let _dict = dict,
                let stars = _dict["stars"] as? Int,
                let distance = _dict["distance"] as? Double,
                let address = _dict["address"] as? String
            else { return nil }

        self.stars = stars
        self.distance = distance
        self.address = address

    }
}



let arrCoupons = [CouponDescription?]() //<<-- we have an array to populate your tableView 
  

在您的解析方法

之后

    let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String:Any]

    let mainCoupons = json["mainCoupon"] as? NSArray //<-- mainCoupons is an array of object/ dictionary so 

   let arr = mainCoupon.map({ CouponDescription($0 as? [String:Any])}) 
  

使用map而不是使用for循环,我们将获取该mainCoupons数组的每个对象并将每个对象转换为CouponDescription对象,结果将附加到arr,这是arrCoupons let arr = mainCoupon.flatMap({ CouponDescription($0 as? [String:Any])}) 相同的类型,最后将arr分配给arrCoupons&amp;重新加载你的tableView

甚至使用flatMap删除可选项(在这种情况下更好)

arr
  

其中[CouponDescription][CouponDescription?]而非let arrCoupons = [CouponDescription?]()的类型,因此将此let arrCoupons = [CouponDescription]()更改为class Athlete: def __init__(self, name, number): self.name = name self.number = number def __str__(self): return "Athlete(" + self.name + ", " + self.number + ")" def name(self): return self.name def number(self): return self.number