es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

No estoy seguro de si estoy utilizando Rx Swift correctamente – Enlazar BehaviorRelay a TableView.

Estoy tratando de actualizar la tabla a través de un botón de eliminar en mi clase de celdas de tabla. Pero no actualiza la tabla al instante, lo cual no sé si es demasiado pedir para el comportamiento del relay.

Propiedades:

private let businesses: BehaviorRelay<[StoresFeedModel]> = BehaviorRelay(value: [])

var businessDataMain = [StoresFeedModel]()

var businessDataFav = [StoresFeedModel]()

El botón:

@objc func deleteTapped(_ sender: UIButton){
    deleteFavIdCoreData(id: storeid) //
    StoresFeed.shared.getFavDataforFavSegment()
}

El método que hace la llamada a la API y actualiza businessDataFav:

func getFavDataforFavSegment() {
    businesses.accept(businessDataFav)
    StoresTabCell.shared.fetchStoreIdCoreData()
    if StoresTabCell.shared.favIDsCoreData.removingDuplicates().count > 0 {
        for i in 0..<storestabcell.shared.favidscoredata.removingduplicates().count {
            yelpapimanager.shared.getfavstoreinfo(id: storestabcell.shared.favidscoredata.removingduplicates()[i].favoritestoreid!) { datafav in
                self.businessdatafav = datafav
            }
        }
    } else {
        businessdatafav = [storesfeedmodel(title: "no favorites yet", image: novalueimage, id: "no id yet")]
        return
    }
}

método de enlace:

func bindtableviewmain() {
    businesses.asobservable()
        .bind(to: tableview
                .rx
                .items(cellidentifier: storesfeedcellid, celltype: storestabcell.self)
        )
    {
        row, businessdata, cell in
        cell.configurewithdata(datamodel: businessdata)
    }
    .disposed(by: disposebag)
}

tengo dos segmentos en la vista principal:

@objc func actionofsc() {
    let type = segments[segmentcontrol.selectedsegmentindex]
    switch type {
    case .allstores:
        getmaindata()
    case .favorites:
        getfavdataforfavsegment()
    }
}

ahora lo que quiero es la actualización de la tabla mientras navego en el segmento de favoritos y presiono el botón de eliminar. mantengo los ids de los favoritos en core data. por lo tanto, el botón de eliminar o agregar favoritos actualiza primero la entidad de core data y luego realizo la llamada a la api a través de esos ids. ¿qué estoy haciendo mal? {=”” yelpapimanager.shared.getfavstoreinfo(id:=”” storestabcell.shared.favidscoredata.removingduplicates()[i].favoritestoreid!)=”” {=”” datafav=”” in=”” self.businessdatafav=”dataFav” }=”” }=”” }=”” else=”” {=”” businessdatafav=”[StoresFeedModel(title:” “no=”” favorites=”” yet”,=”” image:=”” novalueimage,=”” id:=”” “no=”” id=”” yet”)]=”” return=”” }=”” }=”” ="" método="" de="" enlace:=""swift=”” func=”” bindtableviewmain()=”” {=”” businesses.asobservable()=”” .bind(to:=”” tableview=”” .rx=”” .items(cellidentifier:=”” storesfeedcellid,=”” celltype:=”” storestabcell.self)=”” )=”” {=”” row,=”” businessdata,=”” cell=”” in=”” cell.configurewithdata(datamodel:=”” businessdata)=”” }=”” .disposed(by:=”” disposebag)=”” }=”” ="" tengo="" dos="" segmentos="" en="" la="" vista="" principal:=""swift=”” @objc=”” func=”” actionofsc()=”” {=”” let=”” type=”segments[segmentControl.selectedSegmentIndex]” switch=”” type=”” {=”” case=”” .allstores:=”” getmaindata()=”” case=”” .favorites:=”” getfavdataforfavsegment()=”” }=”” }=”” “`=”” ahora=”” lo=”” que=”” quiero=”” es=”” la=”” actualización=”” de=”” la=”” tabla=”” mientras=”” navego=”” en=”” el=”” segmento=”” de=”” favoritos=”” y=”” presiono=”” el=”” botón=”” de=”” eliminar.=”” mantengo=”” los=”” ids=”” de=”” los=”” favoritos=”” en=”” core=”” data.=”” por=”” lo=”” tanto,=”” el=”” botón=”” de=”” eliminar=”” o=”” agregar=”” favoritos=”” actualiza=”” primero=”” la=”” entidad=”” de=”” core=”” data=”” y=”” luego=”” realizo=”” la=”” llamada=”” a=”” la=”” api=”” a=”” través=”” de=”” esos=”” ids.=”” ¿qué=”” estoy=”” haciendo=””></storestabcell.shared.favidscoredata.removingduplicates().count {
yelpapimanager.shared.getfavstoreinfo(id: storestabcell.shared.favidscoredata.removingduplicates()[i].favoritestoreid!) { datafav in
self.businessdatafav = datafav
}
}
} else {
businessdatafav = [storesfeedmodel(title: “no favorites yet”, image: novalueimage, id: “no id yet”)]
return
}
}


método de enlace: ```swift func bindtableviewmain() { businesses.asobservable() .bind(to: tableview .rx .items(cellidentifier: storesfeedcellid, celltype: storestabcell.self) ) { row, businessdata, cell in cell.configurewithdata(datamodel: businessdata) } .disposed(by: disposebag) }

tengo dos segmentos en la vista principal:

@objc func actionofsc() {
    let type = segments[segmentcontrol.selectedsegmentindex]
    switch type {
    case .allstores:
        getmaindata()
    case .favorites:
        getfavdataforfavsegment()
    }
}

ahora lo que quiero es la actualización de la tabla mientras navego en el segmento de favoritos y presiono el botón de eliminar. mantengo los ids de los favoritos en core data. por lo tanto, el botón de eliminar o agregar favoritos actualiza primero la entidad de core data y luego realizo la llamada a la api a través de esos ids. ¿qué estoy haciendo mal?>

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Parece que el problema está en cómo estás actualizando la array businessDataFav en tu método getFavDataforFavSegment(). Como estás realizando una llamada asíncrona a la API dentro de un bucle, las actualizaciones a la array businessDataFav no serán inmediatas y, por lo tanto, la vista de tabla no se actualizará al instante.

    Una forma de solucionar este problema es introducir un bloque de finalización (completion block) en tu método de llamada a la API para actualizar la array businessDataFav y recargar los datos de la vista de tabla después de que todas las llamadas a la API hayan terminado de ejecutarse. Aquí tienes un ejemplo de implementación:

    func getFavDataforFavSegment() {
        businesses.accept(businessDataFav)
        StoresTabCell.shared.fetchStoreIdCoreData()
        let favIDs = StoresTabCell.shared.favIDsCoreData.removingDuplicates()
        if favIDs.count > 0  {
            // Crea un grupo de despacho (dispatch group) para realizar un seguimiento de las llamadas a la API
            let group = DispatchGroup()
            for id in favIDs {
                group.enter()
                YelpAPIManager.shared.getFavStoreInfo(id: id.favoriteStoreID!) { dataFav in
                    // Agrega los datos devueltos a la array
                    self.businessDataFav.append(contentsOf: dataFav)
                    // Notifica al grupo de despacho que esta llamada a la API ha terminado de ejecutarse
                    group.leave()
                }
            }
            // Espera a que todas las llamadas a la API hayan terminado de ejecutarse
            group.notify(queue: .main) {
                // Recarga los datos de la vista de tabla con la array actualizada
                self.tableView.reloadData()
            }
        } else {
            businessDataFav = [StoresFeedModel(title: "No hay favoritos todavía", image: noValueImage, id: "Sin ID aún")]
            tableView.reloadData()
        }
    }
    

    Con esta implementación, la array businessDataFav se actualizará una vez que todas las llamadas a la API hayan terminado de ejecutarse, y la vista de tabla se actualizará con los nuevos datos.

    Nota: Es posible que necesites modificar las instrucciones group.enter() y group.leave() para asegurarte de que el grupo de despacho reciba la notificación adecuada cuando la llamada a la API finalice su ejecución.

Comments are closed.