Updating row's label based of web service impl

2020-05-08 02:12发布

问题:

I have a table view with 7 rows Monday, Tuesday,....,Sunday. My app receives a json from a web service which is of format:

  ({
  appointments = (
                    {
                    numApts = 1;
                    scheduleDate = "2015-11-02";
                    },
                    {
                    numApts = 2;
                    scheduleDate = "2015-11-04";
                    }
                );
})

So I am trying to loop through the json response and update the label of our weekday if it matches a date in the json received.

Not sure how to implement this. Do I need a model class? Something like:

import UIKit

class CurrentRosterModel {
    var numApts : String?
    var scheduleDate : String?

    init(json : NSDictionary){
        self.numApts = json["numApts"] as? String
        self.scheduleDate = json["scheduleDate"] as? String
    }
}

What I was trying today was a function to update the rows text like so, but I wasn't getting into the final if let condition to access the cell in order to update the label:

    let weekDateDict = ["Monday" : mon, "Tuesday" : tues, "Wednesday" : wedns, "Thursday" : thurs, "Friday" : fri, "Saturday" : sat, "Sunday" : sun]
    //where vars mon = "2015-11-02", tues = "2015-11-03" etc.
            //aptsArray is hard coded for now but will need to come from a web service response later
            let aptsArray : [Dictionary<String, String>] = [
                [
                    "numApts" : "1",
                    "scheduleDate" : "2015-11-02"
                ],
                [
                    "numApts" : "2",
                    "scheduleDate" : "2015-11-04"
                ]];



            for (weekDay, weekDate) in weekDateDict {
                if aptsArray.contains({ $0.values.contains(weekDate)}) {
                    print("Matched with weekDate is \(weekDate) and weekDay is \(weekDay)")
                    //getting this condition twice as expected
                    let ourIndexPath : NSIndexPath?
                    switch weekDay {
                        case "Monday":
                            ourIndexPath = NSIndexPath(forRow: 0, inSection : 0)
                            //print("Monday label update")
                        case "Tuesday":
                            ourIndexPath = NSIndexPath(forRow: 1, inSection : 0)
                            //print("Tuesday label update")
                        case "Wednesday":
                            ourIndexPath = NSIndexPath(forRow: 2, inSection : 0)
                            //print("Wednesday label update")
                        case "Thursday":
                            ourIndexPath = NSIndexPath(forRow: 3, inSection : 0)
                            //print("Thursday label update")
                        case "Friday":
                            ourIndexPath = NSIndexPath(forRow: 4, inSection : 0)
                            //print("Friday label update")
                        case "Saturday":
                            ourIndexPath = NSIndexPath(forRow: 5, inSection : 0)
                            //print("Saturday label update")
                        case "Sunday":
                            ourIndexPath = NSIndexPath(forRow: 6, inSection : 0)
                            //print("Sunday label update")
                    default :
                        ourIndexPath = NSIndexPath(forRow: 7, inSection : 0)
                        //print("swicth not satisfied")
                    }

                    if let cell = weekTableView.cellForRowAtIndexPath(ourIndexPath!) as? WeekDayCell{
                        print("got in here")//not getting in here
                        cell.numAptsLbl.text = aptsArray[0]["numApts"]!
                        weekTableView.beginUpdates()
                        weekTableView.reloadRowsAtIndexPaths([ourIndexPath!], withRowAnimation: UITableViewRowAnimation.Automatic)
                        weekTableView.endUpdates()

                    }

                }

My tableview methods look as follows:

func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    return 1
}

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return 7
}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = weekTableView.dequeueReusableCellWithIdentifier("WeekDayCell", forIndexPath: indexPath) as! WeekDayCell

    cell.dayLbl?.text = weekArray[indexPath.row]
    cell.numAptsLbl?.text = "0"
    //indexPath.row.description
    //print("indexpath in tableview is \(indexPath)")

    return cell
}

回答1:

Assumptions

First of all, the json sample you posted is not valid json, but rather the output you would see in the debugger. I'm assuming the json will be something similar to the following format:

{
  "appointments": [
    {
      "numApts": 1,
      "title": "Coffee",
      "scheduleDate": "2015-11-02"
    },
    {
      "numApts": 2,
      "title": "Shower",
      "scheduleDate": "2015-11-04"
    },
    {
      "numApts": 3,
      "title": "Rollercoaster!!!!",
      "scheduleDate": "2015-12-24"
    }
  ]
}

TL;DR

I would recommend that you create an Appointment model which represents a single appointment. You should then create a wrapper around which stores all of the appointments, filtered according to the week day. You can name this wrapper whatever you find appropriate for your project.

Code example

I've tried to put together the most simplest case for what you want to implement. Hopefully the naming used in the code is descriptive enough to explain itself.

I think this will be plenty of help to answer your question and to get you going from here. The output of my code will be something similar to the following image:

Now, I need to highlight that there's a bit of force unwrapping here and there that you need to be aware, before you start using something like this in production.

Appointment.swift:

//
//  Appointment.swift
//  WeekDays
//
//  Created by Stefan Veis Pennerup on 02/11/15.
//  Copyright © 2015 Kumuluzz. All rights reserved.
//

import Foundation

struct Appointment {

    // MARK: - Formatter

    private static var DateFormatter: NSDateFormatter = {
        let formatter = NSDateFormatter()
        formatter.dateFormat = "yyyy-MM-dd"
        return formatter
    }()

    // MARK: - Properties

    let numApts: Int
    let title: String
    let scheduleDate: NSDate

    // MARK: - Initializers

    init(json: [String: AnyObject]) {
        numApts = json["numApts"] as? Int ?? 0
        title = json["title"] as? String ?? ""
        let dateString = json["scheduleDate"] as? String ?? ""
        scheduleDate = Appointment.DateFormatter.dateFromString(dateString) ?? NSDate()
    }
}

WeekDaysModel.swift:

//
//  WeekDays.swift
//  WeekDays
//
//  Created by Stefan Veis Pennerup on 02/11/15.
//  Copyright © 2015 Kumuluzz. All rights reserved.
//

import Foundation

enum WeekDay: Int {
    // Sunday has been set as the initial index, because the NSDateComponents
    // has been created with Sunday as the initial day with an index of 1. 
    // This is being taken into consideration in the getWeekDayIndexForDate()
    case Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday
}

struct WeekDaysModel {

    // MARK: - Properties

    var appointments: [WeekDay: [Appointment]] = [
        WeekDay.Monday:[],
        WeekDay.Tuesday:[],
        WeekDay.Wednesday:[],
        WeekDay.Thursday:[],
        WeekDay.Friday:[],
        WeekDay.Saturday:[],
        WeekDay.Sunday:[]
    ]

    // MARK: - Initializers

    init() {}

    init(json: [String: AnyObject]) {
        // Ensures there is data
        guard let appointmentsJson = json["appointments"] as? [[String: AnyObject]] else {
            return
        }

        // Parses the data points to the Appointment model
        let apts = appointmentsJson.map { json in
            return Appointment(json: json)
        }

        // Assigns each Appointment to a weekday
        _ = apts.map { apt in
            let i = getWeekDayIndexForDate(apt.scheduleDate)
            appointments[WeekDay(rawValue: i)!]! += [apt]
        }        
    }

    // MARK: - Helpers

    private func getWeekDayIndexForDate(aDate: NSDate) -> Int {
        let cal = NSCalendar(identifier: NSCalendarIdentifierGregorian)!
        let comp = cal.components(.Weekday, fromDate: aDate)
        return (comp.weekday - 1)
    }  
}

ViewController.swift:

//
//  ViewController.swift
//  WeekDays
//
//  Created by Stefan Veis Pennerup on 02/11/15.
//  Copyright © 2015 Kumuluzz. All rights reserved.
//

import UIKit

class ViewController: UITableViewController {

    // MARK: - Properties

    private var model = WeekDaysModel() {
        didSet {
            tableView.reloadData()
        }
    }

    // MARK: - Lifecycle methods

    override func viewDidLoad() {
        super.viewDidLoad()
        Backend.downloadAppointments{
            self.model = $0
        }
    }

    // MARK: - UITableViewDelegate

    // MARK: - UITableViewDataSource

    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return model.appointments.count
    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return model.appointments[WeekDay(rawValue: section)!]!.count
    }

    override func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        return String(WeekDay(rawValue: section)!)
    }

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("myCell")!
        let apts = model.appointments[WeekDay(rawValue: indexPath.section)!]!
        cell.textLabel?.text = apts[indexPath.row].title
        return cell
    }
}

Backend.swift:

//
//  Backend.swift
//  WeekDays
//
//  Created by Stefan Veis Pennerup on 02/11/15.
//  Copyright © 2015 Kumuluzz. All rights reserved.
//

import Foundation
import Alamofire

struct Backend {

    static func downloadAppointments(handler: (WeekDaysModel)->Void) {
        let url = "http://stefanveispennerup.com/so.json"
        Alamofire.request(.GET, url).responseJSON { response in
            // TODO: Check response code, etc..
            if let json = response.result.value as? [String: AnyObject] {
                let model = WeekDaysModel(json: json)
                handler(model)
            }
        }
    }  
}