UITableViewCell如何知道从Array或Dictionaries加载什么JSON

时间:2016-04-22 10:32:13

标签: arrays json swift uitableview dictionary

我们假设我有一组3个JSON字典,每个字典都有自己的类型(演示,条目,评论)。

[
{
    "_id": "random ID",
    "profile": "random ID Profile",
    "demo": {
        "_id": "random ID",
        "profile": {
            "_id": "random ID",
            "name": "name",
            "username": "username",
            "description": "description",
            "picture": "/picture"
        },
        "path": "/path",
        "created": "date"
    },
    "type": "demo",
    "source": "570aa8f647a70780a7111e91",
    "__v": 0,
    "created": "date"
},
{
    "_id": "random ID",
    "comment": "random comment ID",
    "type": "comment",
    "source": "57077c4e356c10371ca91ad9",
    "__v": 0,
    "created": "date"
},
{
    "_id": "random ID",
    "entry": "random entry ID",
    "type": "entry",
    "source": "57077c4e356c10371ca91ad9",
    "__v": 0,
    "created": "date"
}
]

现在我正在检查请求中的类型,所以我只能获得演示。

    func getTimeline(urlString: NSURL, completion: ([ModelDemos]) -> Void) {
    Alamofire.request(.GET, urlString).responseJSON { response in

        if let httpResponse = response.response {
            switch httpResponse.statusCode {
            case 200:
                var modelTimeline = [ModelDemos]()

                if let demos = response.result.value as? [JSONDictionary] {
                    for demo in demos {
                        if let type = demo["type"] as? String {
                            if type == "demo" {
                                if let demo = demo["demo"] as? JSONDictionary {
                                    let JSON = ModelDemos(data: demo)
                                    modelTimeline.append(JSON)
                                }
                            }
                        }
                    }
                } else { print("not working") }

                dispatch_async(dispatch_get_main_queue()) {
                    completion(modelTimeline)
                    print("Am I back on the main thread ? Response: \(NSThread.isMainThread())")
                }
            default:
                return
            }
        }
    }
}

在我的TimelineViewController

中设置完成方法之后
var timelineDemos = [ModelDemos]()

func runApiManagerTimeline() {
    guard let urlString = urlString else {return}
    apiManagerCurrentUserProfile.getTimeline(urlString, completion: didGetCurrentUserProfileDemos)
}

func didGetCurrentUserProfileDemos(demos: [ModelDemos]) {
    timelineDemos = demos
    timelineCollectionView.reloadData()
}

一切正常,我只获得了演示词典,我可以将它加载到DemoUITableViewCell。

现在我必须为数组中的每个Dictionary创建3种不同类型的UITableViewCell。想象一下,它是一个Facebook提要,每个字典都不同,而且数字也在不断增长。

我如何告诉每个Cell应该加载哪些内容?

3 个答案:

答案 0 :(得分:0)

使用这些方法:

    // MARK: - Table view Functions
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    //3 because of 3 different dictionaries
    return 3
}

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
//Define the amount of rows for each section
    if (section == 0) {
        return --amount of entries in regarding dictionary--
    } else if (section == 1) {
        return --amount of entries in regarding dictionary--
    } else {
        return --amount of entries in regarding dictionary--
    }
}

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
 if (indexPath.section == 0) {
      //Dict 1
 } else if (indexPath.section == 1) {
      //Dict 2
 } else {
      //Dict 3
 }

答案 1 :(得分:0)

我认为您可以尝试自定义数据源,使类(内部类或非内部类)像:

class GeneralNotificationInfo: NSObject {
    var notificationTime:NSDate! = NSDate()
    enum notificationType: Int {
        case Demo = 1
        case Entry = 2
        case Test = 3
    }
    var data:NSDictionary! = NSDictionary()
    ...
}

通过这种个性化,您可以轻松处理您的手机。

关于您的代码:

typealias AlamoNetSuccess = (result: NSDictionary?) -> Void
typealias AlamoNetProgress = (result: NSDictionary?) -> Void
typealias AlamoNetFailure = (error: NSDictionary?) -> Void

var params :[String: AnyObject]? = ["user": "David", "age": 40]

func getTimeline(urlString: NSURL,params: [String: AnyObject], success successBlock :AlamoNetSuccess,
        failure failureBlock :AlamoNetFailure) {
.request(.GET, url, parameters: params, encoding: ParameterEncoding.URL)
            .responseJSON { response in
                print("∙ ---")
                print("∙ Net URLs: \(response.request?.URL)")  // original URL request
                print("∙ ---")
                //print(response.response) // URL response
                //print(response.data)     // server data
                //print(response.result)   // result of response serialization
                if response.result.isSuccess {
                    let jsonDic = response.result.value as! NSDictionary
                    successBlock(result: jsonDic)
                } else {
                    let httpError: NSError = response.result.error!
                    let statusCode = httpError.code
                    let error:NSDictionary = ["error" : httpError,"statusCode" : statusCode]
                        failureBlock(error: error)
                }
}

let wrappedNetSuccess: AlamoNetSuccess = {(result: NSDictionary?) -> Void in // 
    print ("∙ Net Success: \(result)")
    // do whatever you want with your dictionary, parse it into datasource...
}

let wrappedAPIFailure: AlamoNetFailure = {(error: NSDictionary?) -> Void in
    print ("∙ Net Failure: \(error)")
    // handle your network error with alertViews or other..
}

apiManagerCurrentUserProfile.getTimeline(urlString,params:[], success: wrappedAPISuccess, failure: wrappedAPIFailure)

答案 2 :(得分:0)

使用自定义结构作为数据源数组模型的另一个好例子。

首先创建enum以将String类型映射到enum个案例

enum DataType : String { case Demo = "demo", Comment = "comment", Entry = "entry" }

创建自定义struct项作为数据源模型。声明三种数据类型的所有常见属性不带初始值,单个属性初始值,以使用隐式成员初始值设定项创建Item实例和根据类型为各个属性赋值。示例属性来自JSON,只是一个示例

struct Item {
  // common properties
  var type : DataType
  var source : String
  var created : String

  // individual properties
  var username = ""
  var description = ""
  var picture = ""
}

在TableView控制器中创建数据源数组

var modelTimeline = [Item]()
解析JSON时

并创建Item个实例

...
if let demos = response.result.value as? [JSONDictionary] {
  for demo in demos {
    if let type = demo["type"] as? String {
      let source = type["source"] ?? ""
      let created = type["date"] ?? ""
      var item = Item(type: DataType(rawValue:type), source: source, created: created)
      if type == "demo" {
        if let demo = demo["demo"] as? JSONDictionary, profile = demo["profile"] as? JSONDictionary {
          item.username = profile["username"] ?? ""
          item.description = profile["description"] ?? ""
          item.picture = profile["picture"] ?? ""
        }
      }
      modelTimeline.append(item)
    }
  }
} else { print("not working") }
...

cellForRowAtIndexPath中创建单元格并根据类型

为UI元素指定值
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
  let item = modelTimeline[indexPath.row]
  switch item.type {
    case .Demo:
    let cell = tableView.dequeueReusableCellWithIdentifier("DemoCell", forIndexPath: indexPath) as! DemoUItableViewCell
    cell.usernameLabel.text = item.username
    cell.descriptionLabel.text = item.description
    cell.sourceLabel.text = item.source
    // populate other UI elements
    return cell

    case .Comment:
    cell = tableView.dequeueReusableCellWithIdentifier("CommentCell", forIndexPath: indexPath)  as! CommentUItableViewCell
    cell.sourceLabel.text = item.source
    // populate other UI elements
    return cell

    case .Entry:
    cell = tableView.dequeueReusableCellWithIdentifier("EntryCell", forIndexPath: indexPath)  as! EntryUItableViewCell
    cell.sourceLabel.text = item.source
    // populate other UI elements
    return cell
  }
}

代码不是完整的工作版本,它只是建议如何为不同类型使用不同的单元格。