Borrado de Tweets Propios en iOS usando Swipe en UITableView

Clase 31 de 52Curso de Desarrollo de Apps para iOS

Contenido del curso

Tu primera app en iOS

Proyecto: PlatziTweets

Resumen

Lograr que una aplicación se sienta completa implica cubrir las operaciones básicas sobre los datos: crear, leer y eliminar. En este punto la app ya publica tweets, los obtiene del servidor, gestiona login y registro. Ahora toca implementar la funcionalidad de borrar tweets usando el gesto de swipe nativo de las celdas en iOS, consumiendo un servicio DELETE del API y controlando que cada usuario solo pueda eliminar sus propios posts.

¿Cómo agregar acciones de swipe a las celdas de un UITableView?

Para habilitar las acciones deslizables en las celdas, lo primero es asignar el delegate del UITableView. Hasta ahora solo se había configurado el data source, pero el delegate es indispensable para controlar la interacción del usuario con las celdas [01:30].

swift tableView.delegate = self

Después se crea una extensión que implemente el protocolo UITableViewDelegate y dentro se llama al método editActionsForRow(at indexPath:) [02:00]. Este método retorna un arreglo de acciones que aparecerán al deslizar la celda.

swift let deleteAction = UITableViewRowAction(style: .destructive, title: "Borrar") { (_, indexPath) in self.deletePost(at: indexPath) } return [deleteAction]

  • El parámetro style acepta valores como .default, .destructive y .normal.
  • El title es el texto visible en el botón de la acción.
  • El handler es el bloque que se ejecuta cuando el usuario toca la opción.

Con esto, al deslizar cualquier celda hacia la izquierda aparece el botón rojo "Borrar" [03:20].

¿Cómo consumir un servicio DELETE para eliminar un post?

El método deletePost(at:) es una función privada que centraliza toda la lógica de eliminación [04:00]. Sigue una secuencia clara:

¿Cómo obtener el ID del post seleccionado?

Se accede al data source (el arreglo de posts) usando indexPath.row para ubicar el elemento exacto y extraer su identificador [04:30].

swift let postID = dataSource[indexPath.row].id

¿Cómo preparar el endpoint y ejecutar la petición?

La documentación del API requiere concatenar el ID del post a la URL base. Esto se logra construyendo el endpoint dinámicamente [05:10].

swift let endpoint = Endpoints.deletePost + postID

Luego se llama a SimpleNetworking con el método .delete, que es una operación HTTP DELETE. A diferencia de un POST, aquí no se envía un cuerpo (body); toda la información viaja en la URL [05:40].

swift SNCall.delete(endpoint) { (result: SNResultWithEntity<GeneralResponse, ErrorResponse>) in // Manejo del resultado }

Dentro del completion handler se manejan tres escenarios: éxito, error controlado y error inesperado, cerrando siempre el indicador de carga (SVProgressHUD.dismiss()) [06:15].

¿Cómo sincronizar la tabla con el servidor tras eliminar?

Cuando el servicio confirma la eliminación, hay que actualizar dos cosas en orden:

  • Eliminar del data source con dataSource.remove(at: indexPath.row) [07:00].
  • Eliminar la celda de la tabla con tableView.deleteRows(at: [indexPath], with: .left) [07:15].

El parámetro rowAnimation define la animación de salida; .left desliza la celda hacia la izquierda.

¿Cómo impedir que un usuario borre tweets ajenos?

El API ya protege contra esto en el servidor, pero la experiencia de usuario mejora si la app previene la acción desde la interfaz. Para ello se implementa el método canEditRowAt dentro del delegate [08:30].

swift func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool { return dataSource[indexPath.row].author.email != "test1@test.com" }

Este método retorna un booleano: si el correo del autor del post coincide con el del usuario actual, la celda no se puede editar y el swipe queda deshabilitado [09:00].

Sin embargo, dejar el correo escrito directamente en el código (hardcodeado) no es una buena práctica. El reto propuesto consiste en guardar el correo del usuario en UserDefaults durante el login y luego recuperarlo en esta validación para comparar contra el autor real del post [10:20]. Así la funcionalidad queda dinámica y correcta para cualquier cuenta.

¿Ya implementaste el reto con UserDefaults? Comparte tu solución y cuéntanos si encontraste alguna dificultad en el proceso.