我正在使用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中,将尝试的代码作为注释。你能帮我吗?
答案 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)
}
}