I'm having trouble to use a custom Object in Eureka Form, I'm trying to load the objects from a Rest Service, I'm using Alamofire to get the options, Im using row.options.append to fill the data, and when I select the cell I get an error assertion failed: Duplicate tag Building
Here is my class that conforms to the Equatable Protocol
class Building: Mappable, Equatable {
var name_building: String?
var id_building: Int?
required init?(){
}
required init?(_ map: Map){
}
func mapping(map: Map) {
id_building <- map["id_building"]
name_building <- map["name_building"]
}
}
func == (lhs: Building, rhs: Building) -> Bool {
return lhs.id_building == rhs.id_building
}
And here is the Form
import UIKit
import Eureka
import CoreLocation
import Alamofire
import KeychainAccess
import ObjectMapper
import SnapKit
class UserViewController: FormViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.title = "Perfil del Usuario"
// Do any additional setup after loading the view.
form +++ Section("Datos Generales")
<<< NameFloatLabelRow("kName") {
$0.title = "Nombre"
}
<<< TextFloatLabelRow("kLastName") {
$0.title = "Apellidos"
}
<<< TextFloatLabelRow("kPhone") {
$0.title = "Teléfono"
}
<<< TextFloatLabelRow("kEmail") {
$0.title = "Email"
$0.disabled = true;
}
<<< SegmentedRow<String>("kGenre") {
$0.title = "Genero"
$0.options = ["Masculino", "Femenino"]
}
<<< CheckRow("kRider") {
$0.title = "¿Estoy dispuesto a dar Aventones?"
$0.value = true
}
+++ Section("Casa")
<<< LocationRow("kHome"){
$0.title = "Casa"
$0.value = CLLocation(latitude: -34.91, longitude: -56.1646)
}
<<< TimeInlineRow("kHomeDepartureTime"){
$0.title = "Hora de Salida"
$0.value = NSDate()
}
+++ Section("Trabajo")
<<< PushRow<Building>("kBuilding") {
$0.title = "Edificio"
$0.selectorTitle = "Donde Trabajas?"
}
<<< TimeInlineRow("kEnterTime"){
$0.title = "Hora de Entrada"
$0.value = NSDate()
}
<<< TimeInlineRow("kExitTime"){
$0.title = "Hora de Salida"
$0.value = NSDate()
}
+++ Section()
<<< ButtonRow() { (row: ButtonRow) -> Void in
row.title = "GUARDAR"
} .onCellSelection({ (cell, row) in
print("Salvando Informacion")
let nameRow: NameFloatLabelRow! = self.form.rowByTag("kName")
let lastNameRow: TextFloatLabelRow! = self.form.rowByTag("kLastName")
let phoneRow: TextFloatLabelRow! = self.form.rowByTag("kPhone")
let emailRow: TextFloatLabelRow! = self.form.rowByTag("kEmail")
let genreRow: SegmentedRow<String>! = self.form.rowByTag("kGenre")
let riderRow: CheckRow! = self.form.rowByTag("kRider")
let locationRow: LocationRow! = self.form.rowByTag("kHome")
let homeDepartureTimeRow: TimeInlineRow! = self.form.rowByTag("kHomeDepartureTime")
let buildingRow: PushRow<Building>! = self.form.rowByTag("kBuilding")
let buildingEnterTimeRow: TimeInlineRow! = self.form.rowByTag("kEnterTime")
let buildingExitTimeRow: TimeInlineRow! = self.form.rowByTag("kExitTime")
let user = User()
user.email = emailRow.value
user.name = nameRow.value
user.lastName = lastNameRow.value
user.genre = genreRow.value
user.phone = phoneRow.value
user.id_type = riderRow.value == true ? 1 : 2
user.homeDepartureDate = homeDepartureTimeRow.value
user.jobEnterTime = buildingEnterTimeRow.value
user.jobExitTime = buildingExitTimeRow.value
user.id_building = 3
let location = locationRow.value! as CLLocation
user.latitude = location.coordinate.latitude
user.longitude = location.coordinate.longitude
let JSONString = Mapper().toJSONString(user, prettyPrint: false)
let mappedObject = Mapper<User>().map(JSONString)
let request = "requesttoCreateUser"
Alamofire.request(.POST, request, parameters: Mapper().toJSON(user), encoding: .JSON)
.validate()
.responseJSON { response in
switch response.result {
case .Success:
print("Validation Successful")
case .Failure(let error):
print(error)
}
}
})
self.getBuilding();
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func getBuilding(){
let buildingRow: PushRow<Building>! = self.form.rowByTag("kBuilding")
let request = "requestToGetBuildings"
Alamofire.request(.GET, request).responseArray { (response: Response<[Building], NSError>) in
let buildingsArray = response.result.value
if let buildingsArray = buildingsArray {
for building in buildingsArray {
buildingRow.options.append(building)
}
}
}
}
}
And It crashes here in the Eureka class BaseRow.swift
final func wasAddedToFormInSection(section: Section) {
self.section = section
if let t = tag {
assert(section.form?.rowsByTag[t] == nil, "Duplicate tag \(t)")
self.section?.form?.rowsByTag[t] = self
self.section?.form?.tagToValues[t] = baseValue as? AnyObject ?? NSNull()
}
addToRowObservers()
evaluateHidden()
evaluateDisabled()
}
As mentioned here.
All you need to do is conform your model to CustomStringConvertible protocol.
This is because the default implementation of SelectorViewController uses String(option) as the tag for your PushRow rows
So your class should look like this:
class Building: Mappable, Equatable,CustomStringConvertible {
var name_building: String?
var id_building: Int?
var description: String {
return name_building
}
required init?(){
}
required init?(_ map: Map){
}
func mapping(map: Map) {
id_building <- map["id_building"]
name_building <- map["name_building"]
}
}
func == (lhs: Building, rhs: Building) -> Bool {
return lhs.id_building == rhs.id_building
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With