如何在Swift 4

时间:2019-05-22 16:34:27

标签: ios swift alamofire alexa alexa-skills-kit

我正在使用Swift 4创建一个iOS应用,然后尝试使用Alamofire从外部API获取数据,然后使用Swifty JSON将该数据转换为JSON并通过UIViewTable呈现给用户。我想根据API发送的数据类型添加条件(如if或swift语句)以使用不同类型的数据结构。

我有多个swift文件,一个用于API请求,另一个用于Function,另一个用于UITableCell结构声明。

我想在NotificationsViewController中添加一个if开关语句,以获取一种API响应。在createCells函数中,我知道什么类型的通知,因此可以在响应中设置必要的数据。此代码已获取数据,并将其放入具有自定义类型NotificationData的2D数组中。问题是当我想根据2D数组中的通知类型添加其他类型的自定义单元格时。

* NotificationsViewController * 项目主屏幕的文件


class NotificationsViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    private let request = GetNotificationsRequest()
    private let functions = Functions()

    (...)

    var cells: [[NotificationData]] = []

    override func viewDidLoad() {
        super.viewDidLoad()

        guard let urlToExecute = URL(string: functions.generateUrl(stage: "dev", parameters: "appnotification/notificatios/\(idAssociation!)/\(idUser!)/10/1", side: "inside")) else {
            return
        }
        request.execute(urlToExecute, user: userName as! String, pass: userPassword as! String) { (json, noItems, statusCode, error) in
            print(urlToExecute)
            if let error = error {
                print("Ha ocurrido un error.\n\(error)")
            }
            else {
                //--------------------------- Se ha realizado el llamado
                self.cells = self.functions.createCells(json: json!, noItems: noItems!)
                print(type(of: self.cells))
                // Output: Array<Array<NotificationData>>
                print(self.cells.count)
                // Output: 10
            }
        }        
    }

    //I WANT TO ADD THE IF OR SWITCH STATEMENT HERE BUT XCODE GETS AN ERROR


    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        print("Hay \(cells.count) celdas.")
        return cells.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        //for index in 0..<cells.count {
            //switch cells[index][indexPath.row].typeLabel {
            //case "Score":
        let cell = tableView.dequeueReusableCell(withIdentifier: "ScoreCell") as! ScoreCell
        cell.fullNameLabel.text = cells[indexPath.row][indexPath.row].fullNameLabel
        cell.agoLabel.text = cells[indexPath.row][indexPath.row].agoLabel
        cell.sisLabel.text = cells[indexPath.row][indexPath.row].sisLabel
        cell.rcLabel.text = cells[indexPath.row][indexPath.row].rcLabel
        cell.soLabel.text = cells[indexPath.row][indexPath.row].soLabel
        cell.oLabel.text = cells[indexPath.row][indexPath.row].oLabel
        cell.diaLabel.text = cells[indexPath.row][indexPath.row].diaLabel
        cell.tempLabel.text = cells[indexPath.row][indexPath.row].tempLabel
        cell.respLabel.text = cells[indexPath.row][indexPath.row].respLabel
        cell.avpuLabel.text = cells[indexPath.row][indexPath.row].avpuLabel
        cell.scoreLabel.text = cells[indexPath.row][indexPath.row].scoreLabel
        print(cell)
        return cell
        //}
    }
}

* GetNotifications()函数* 然后该函数使用Alamofire从API获取数据

    let functions = Functions()
    typealias WebServiceResponse = (JSON?, Int?, Int?, Error?) -> Void
    //Definición del método llamado execute() que realiza la sequest
    func execute(_ url:URL,user: String, pass: String, completion: @escaping WebServiceResponse) {
        //Definición de headers y credenciales para realizar la request
        let usr = "\(user)"
        //let usr = "USER"
        let pass = "\(pass)"
        //let pass = "PASSWORD"
        let parameters: Parameters = [:]
        let credentialsData = "\(usr):\(pass)".data(using: String.Encoding.utf8)!
        let codCredentials = credentialsData.base64EncodedString(options: [])
        let headers = [
            "Authorization": "Basic \(codCredentials)"
        ]

        //Definición del tipo de request, envío de headers para la autenticación y establecimiento de reglas de validación
        Alamofire.request(url, method: .get, parameters: parameters, encoding: URLEncoding.default, headers: headers) .validate(statusCode: 200..<300) .responseJSON { response in
            let statusCode = response.response?.statusCode
            print(headers)
            print(usr)
            print(pass)
            switch response.result {
            case .success(let value):
                let json = JSON(value)
                let noItems = json["notifications"].count
                completion(json, noItems, statusCode, nil)
                print("Se ejecutó el llamado correctamente. Contiene \(noItems) ítems.")
            case .failure(let error):
                completion(nil, nil, statusCode, error)
                print("Ha ocurrido un error al ejecutar el llamado")
                print(error)
            }
        }
    }
}

* createCells()函数* 函数然后获取API数据json(在Swifty JSON中)并使用NotificationData结构转换为2D数组并将其保存在arrayNotifications

func createCells(json: JSON, noItems: Int) -> Array<Array<NotificationData>> {

        var arrayNotifications = [[NotificationData]]()
        for index in 0..<noItems {
            var type = json["notifications"][index]["idnotification_type"].rawString()!
            var notification = [NotificationData]()

            switch type {
            case "1":
                print("Ingreso")
                type = "Ingreso"
                var ago = ""
                let agoWithoutFormat = json["notifications"][index]["detail"]["start"].rawString()!
                print(agoWithoutFormat)
                var fullName = json["notifications"][index]["detail"]["name"].rawString()!; fullName += " "; fullName += json["notifications"][index]["detail"]["lastname"].rawString()!
                let reason = json["notifications"][index]["detail"]["reason_for_admission"].rawString()!
                let room = json["notifications"][index]["detail"]["room"].rawString()!
                let floor = json["notifications"][index]["detail"]["floor"].rawString()!
                let timeStart = json["notifications"][index]["detail"]["start"].rawString()!

                let dateFormatterGet = DateFormatter()
                dateFormatterGet.dateFormat = "yyyy-MM-dd HH:mm:ssZZZZZ"
                //according to date format your date string
                if let date = dateFormatterGet.date(from: agoWithoutFormat) {
                    ago = date.self.timeAgoDisplay()
                    print(ago)
                } else {
                    print("Se ha producido un error al codificar la hora")
                    ago = "Hace tiempo."
                }
                // --------- AGREGAR notificación al array
                notification = [NotificationData(typeLabel: type, agoLabel: ago, fullNameLabel: fullName, sisLabel: "", diaLabel: "", rcLabel: "", tempLabel: "", soLabel: "", respLabel: "", oLabel: "", avpuLabel: "", scoreLabel: "", reasonLabel: reason, roomLabel: room, floorLabel: floor, timeStartLabel: timeStart, dateStartLabel: "", timeEndLabel: "", dateEndLabel: "")]
                arrayNotifications.append(notification)
            case "2":
                print("Egreso")

            case "3":
                print("Score")
                type = "Score"
                var ago = ""
                let agoWithoutFormat = json["notifications"][index]["detail"]["time"].rawString()!
                //print(agoWithoutFormat)
                var fullName = json["notifications"][index]["detail"]["name"].rawString()!; fullName += " "; fullName += json["notifications"][index]["detail"]["lastname"].rawString()!
                let sis = json["notifications"][index]["detail"]["detail"]["sistolica"].rawString()!
                let dia = json["notifications"][index]["detail"]["detail"]["diastolica"].rawString()!
                let rc = json["notifications"][index]["detail"]["detail"]["ritmocardiaco"].rawString()!
                let temp = json["notifications"][index]["detail"]["detail"]["temperatura"].rawString()!
                let so = json["notifications"][index]["detail"]["detail"]["saturaciondeoxigeno"].rawString()!
                let resp = json["notifications"][index]["detail"]["detail"]["respiracionesxminuto"].rawString()!
                let o = json["notifications"][index]["detail"]["detail"]["oxigenosuplementario"].rawString()!
                let avpu = json["notifications"][index]["detail"]["detail"]["avpu"].rawString()!
                let score = json["notifications"][index]["detail"]["total"].rawString()!
                //let score = json["notifications"][index]["detail"]["detail"]["avpu"].rawString()!
                let dateFormatterGet = DateFormatter()
                dateFormatterGet.dateFormat = "yyyy-MM-dd HH:mm:ss"
                //according to date format your date string
                if let date = dateFormatterGet.date(from: agoWithoutFormat) {
                    ago = date.self.timeAgoDisplay()
                    print(ago)
                } else {
                    print("Se ha producido un error al codificar la hora")
                    ago = "Hace tiempo."
                }
                notification = [NotificationData(typeLabel: type, agoLabel: ago, fullNameLabel: fullName, sisLabel: sis, diaLabel: dia, rcLabel: rc, tempLabel: temp, soLabel: so, respLabel: resp, oLabel: o, avpuLabel: avpu, scoreLabel: score, reasonLabel: "", roomLabel: "", floorLabel: "", timeStartLabel: "", dateStartLabel: "", timeEndLabel: "", dateEndLabel: "")]
                arrayNotifications.append(notification)
                //print(notification)
            case "4":
                print("Recordatorio de Score")

            case "5":
                print("Deterioro fisiológico")

            default:
                print("Ha ocurrido un error al crear la celda.")

            }
        }
        //print(arrayNotifications)
        return arrayNotifications
    }
}

* NotificationData * NotificationData的结构

struct NotificationData {
    var typeLabel: String
    var agoLabel: String
    var fullNameLabel: String
    var sisLabel: String
    var diaLabel: String
    var rcLabel: String
    var tempLabel: String
    var soLabel: String
    var respLabel: String
    var oLabel: String
    var avpuLabel: String
    var scoreLabel: String
    var reasonLabel: String
    var roomLabel: String
    var floorLabel: String
    var timeStartLabel: String
    var dateStartLabel: String
    var timeEndLabel: String
    var dateEndLabel: String
}

* ScoreCell * 自定义的UITableViewCell比定义了Score原型单元格

class ScoreCell: UITableViewCell {
    @IBOutlet weak var typeLabel: UILabel!
    @IBOutlet weak var agoLabel: UILabel!
    @IBOutlet weak var fullNameLabel: UILabel!
    @IBOutlet weak var sisLabel: UILabel!
    @IBOutlet weak var diaLabel: UILabel!
    @IBOutlet weak var rcLabel: UILabel!
    @IBOutlet weak var tempLabel: UILabel!
    @IBOutlet weak var soLabel: UILabel!
    @IBOutlet weak var respLabel: UILabel!
    @IBOutlet weak var oLabel: UILabel!
    @IBOutlet weak var avpuLabel: UILabel!
    @IBOutlet weak var scoreLabel: UILabel!

    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    }

}

* IngressCell * 自定义UITableViewCell比定义Ingress原型单元格

class IngressCell: UITableViewCell {
    @IBOutlet weak var reasonLabel: UILabel!
    @IBOutlet weak var agoLabel: UILabel!
    @IBOutlet weak var patientNameLabel: UILabel!
    @IBOutlet weak var descriptionLabel: UITextView!

    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    }
}

我试图在NotificationsViewController中添加if或switch语句以获取通知的类型,例如如果类型为3,则类型为Score,所以我必须使用名为let cell = tableView.dequeueReusableCell(withIdentifier: "ScoreCell") as! ScoreCell的原型单元格ScoreCell,但如果类型为1,则类型为Ingress,因此必须更改为{{1}并使用Ingress原型单元。 当我尝试在ViewController中添加这些条件时,xcode标记为错误。在NotificationsViewController中,将尝试的代码作为注释。你能帮我吗?

2 个答案:

答案 0 :(得分:1)

使用具有一项要求的协议

protocol NotificationData {
    var type : String { get }
}

然后使用不同的结构,例如仅声明属于该结构的成员

struct Ingreso : NotificationData {
   let type : String

   let room : String
   let floor : String

   // other members 
}

struct Egreso : NotificationData {
   let type : String

   // other members
}

struct Score : NotificationData {
   let type : String

   let sis: String
   let dia: String
   // other members
}

createCells中,根据类型创建不同的结构并分配type

尚不清楚您是否真的需要2D数组,简单的解决方案是将1D数组声明为协议类型,并按type对该数组进行排序

var cells = [NotificationData]()

cellForRow中打开type,获取该项并将其强制转换为实际的静态类型以访问结构成员

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let item = cells[indexPath.row]
    switch item.type {
       case "Score":
           let cell = tableView.dequeueReusableCell(withIdentifier: "ScoreCell", for: indexPath) as! ScoreCell
           let score = item as! Score

           // assign values to the UI
           return cell

        case "Ingreso":
           let cell = tableView.dequeueReusableCell(withIdentifier: "IngresoCell", for: indexPath) as! IngresoCell
           let ingreso = item as! Ingreso

           // assign values to the UI
           return cell

        case "Egreso":
           let cell = tableView.dequeueReusableCell(withIdentifier: "EgresoCell", for: indexPath) as! EgresoCell
           let egreso = item as! Egreso

           // assign values to the UI
           return cell

        // and so on

答案 1 :(得分:0)

您需要关心import PySimpleGUI as sg xList = ['a', 'b', ... 'zz'] layout = [[sg.Text('Select a thingy')], [sg.Radio(<for thingy in xList: 'thingy', thingy>)], #^^^^^^ for loop is psuedo code [sg.OK(), sg.Cancel()]]

cellForRowAt

其中type是对象的可能类型的func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let typeSection = array[indexPath.row].type switch typeSection { case .CenterTitleCell: return getCenterTitleCell(tableView, indexPath) case .CenterDescriptionCell: return getCenterDescriptionCell(tableView, indexPath) case .CenterImageCell: return getImageCell(tableView, indexPath) case .FooterTitleCell: return getFooterViewCell(tableView, indexPath) } }