Massive View Controller - IOS - Soluciones

16

Estoy seguro de que cada nuevo desarrollador de iOS tiene el siguiente problema: los controladores de vista se llenan muy rápido de código para diversos fines, llegando fácilmente a más de 500 líneas de código.

Así es como se ve para dos pantallas básicas y comunes:

1) La pantalla del formulario: ingrese la descripción de la imagen aquí

2) La pantalla del controlador de vista de tabla ingrese la descripción de la imagen aquí

Hasta ahora he leído sobre dos soluciones diferentes:

  1. Primera solución: https://bendyworks.com/single-responILITY-principle-ios/ . Esto se basa en notificaciones, separa completamente el controlador de vista del modelo de vista (intenciones) y, por lo tanto, reduce el código en el controlador de vista. Creo que tiene la desventaja de romper el código, similar a las estructuras Go-To. Se parece a esto: ingrese la descripción de la imagen aquí

  2. La segunda solución mantiene los mismos controladores de vista abarrotados (las acciones de los botones se ejecutan dentro de VC, etc.). pero usa bibliotecas como TPKeyboardAvoiding , BlocksKit u otras soluciones, la mayoría de ellas basadas en categorías. Con esta segunda solución, el código se reduce drásticamente, pero el controlador de vista aún tiene mucha responsabilidad.

¿Qué opinas de estas soluciones? ¿Cual es mejor? Hay alguno mejor?

Ravul
fuente
55
No puedo dar una buena respuesta debido al tiempo, pero esto debería apuntarlo en la dirección correcta.
Mike D
Mi intención es reunir tantas buenas respuestas como sea posible para finalmente superar este problema que tantos desarrolladores nuevos tienen. Gracias por el enlace, si encuentro algo nuevo seguramente lo publicaré aquí.
Ravul
Aquí hay una gran charla sobre pelear con controladores de vista gordos por Andy Matuschak https://realm.io/news/andy-matuschak-refactor-mega-controller/
Tomasz Bąk

Respuestas:

6

Podemos usar MVVM para resolver este problema.

Model-View-ViewModel, o patrón MVVM como se le conoce comúnmente, es un patrón de diseño de interfaz de usuario. VM toma toda la lógica sobre la preparación de datos del modelo para la interfaz de usuario desde VC.

Ejemplo:
tiene un objeto modelo con algunos campos, desea formatear algunos de ellos, hacer cálculos y combinarlos.

En el caso de MVC, toda esa lógica se encuentra en ViewController.
En MVVM lo mueve todo de VC a VM.

VM preparará todos los datos para UI y VC simplemente lo configura de esta manera.

(en clase VC)

self.descriptionLabel = self.viewModel.textForDescriptionLabel;

Tutoriales y temas:

kaspartus
fuente
3
Si bien esto puede responder teóricamente la pregunta, sería preferible incluir aquí las partes esenciales de la respuesta y proporcionar el enlace para referencia.
Bart van Ingen Schenau
Estoy de acuerdo con Bart Si nadie más publicará un resumen de todos estos métodos, haré uno tan pronto como los entienda y los probaré.
Ravul
2
@Ravul respuesta actualizada
kaspartus
He votado su respuesta y gracias por esta idea. Estoy leyendo acerca de la programación funcional reactiva y parece una buena idea. Creo que la respuesta a esta pregunta es una enumeración, con algunas ventajas, desventajas y al menos un diagrama conceptual para las siguientes 4 formas de abordar el problema: 1) Cacao reactivo 2) KVO 3) Método de delegado y 4) Forma clásica de escribiendo un controlador de vista. Lo escribiré tan pronto como pruebe todos estos métodos si nadie más lo hace antes que yo. Si mientras tanto encuentro nuevas formas, eso es aún mejor.
Ravul
3

He tenido que desenredar código en controladores de vista de gran tamaño antes y realmente impidió mi capacidad de navegar por el contenido al principio. Una cosa importante que me di cuenta es que el tamaño solo del controlador de vista no era razón suficiente para separar las cosas. Hay complejidad en tener 1 archivo grande y también complejidad en tener un montón de archivos pequeños. Aquí hay algunas razones válidas para refactorizar para dividir un controlador de vista en partes más pequeñas:

MVC

El controlador de vista no debería hacer mucho más que ser el pegamento de conexión entre la vista y el modelo. Si tiene mucho código de conexión de red, código de manipulación de imágenes, etc., considere dividirlos en clases auxiliares.

Múltiples controles con el controlador de vista como fuente de datos

Si tiene un montón de controles en pantalla que tienen su controlador de vista como fuente de datos, considere dividirlos en objetos de fuente de datos separados y haga que sean la fuente de datos. O también puede dividirlos en Controladores de vista separados (como si el Controlador de vista tiene una vista de tabla además de otro controlador, puede dividirlo en su propia clase Controlador de vista de tabla).

Código duplicado

Si tiene exactamente el mismo código en diferentes controladores de vista, colóquelo en 1 ubicación compartida. Eso hará que su código sea reutilizable y ayudará a administrar la complejidad.

Aquí hay algunos consejos adicionales para minimizar la complejidad de View Controller:

Storyboard en lugar de programático

Crear elementos de vista es mucho código y el código de geometría de marco también es mucho trabajo. De lo contrario, considere usar restricciones de diseño automático y colocar la mayor cantidad posible de elementos de vista en el guión gráfico.

Código / comentarios innecesarios

También asegúrese de eliminar códigos / comentarios innecesarios. Muchas veces un nuevo archivo de View Controller vendrá con métodos que no está utilizando. Si no está utilizando un método como didReceiveMemoryWarningeste, es seguro sacarlo. Además, debido a que el archivo del controlador de vista es tan grande, a veces da miedo eliminar el código o los comentarios antiguos. ¡No dejes eso! Solo se suma a la complejidad.

Notificaciones

Para responder a su pregunta sobre notificaciones: las notificaciones no son un Golden Hammer para usar con todo. Considero que las notificaciones son útiles cuando varios controladores de vista necesitan actualizarse al mismo tiempo debido a una acción en particular. Sin embargo, tenga cuidado con las notificaciones, usarlas en exceso puede causarle mucho dolor al tratar de localizarlas.

Korey Hinton
fuente
2

Hay una arquitectura especial que llaman VIPER (Ver, Interactor, Presentador, Entidad y Enrutamiento). Intentaré resumir aquí lo que necesitas saber:

Ver

  • son vistas falsas;
  • contener objetos como UIView, UIViewController, UILabel, etc.
  • espera el contenido del presentador ;
  • manejar la interacción del usuario y pasarla a la capa Presentador .

Presentador

  • no conoce los objetos de la interfaz de usuario;
  • obtener entradas de la capa de Vista ;
  • manejar la lógica de la vista (el método add presentará otra pantalla);

Enrutamiento

  • manejar la lógica de navegación y las animaciones de transición;
  • conoce objetos como UINavigationController, UIWindow, etc.

Entonces, lo que creo que limpiarás en tu código:

  • las validaciones de datos se moverán a la capa Presentador ;

  • la navegación se moverá a los objetos Wireframe ( capa de enrutamiento );

  • divida su controlador de vista observando el principio DRY ;

  • Las pantallas complejas tendrán dos o más Vistas y Presentadores.

Debería ver el siguiente enlace sobre la arquitectura VIPER http://mutualmobile.github.io/blog/2013/12/04/viper-introduction/

¡Buena suerte!

orafaelreis
fuente
1
¿Esta arquitectura funciona para pequeñas aplicaciones? Parece que tienes que crear muchos objetos para presentarlo al proyecto.
Tomasz Bąk
Sí, estoy de acuerdo en que es más objeto que el MVC tradicional, pero vale la pena. Puede ver un ejemplo simple que creé este año github.com/orafaelreis/cascavel Cascavel es como un proyecto base para inicializar proyectos VIPER.
orafaelreis
Excelente! La arquitectura VIPER parece diseñada exactamente para evitar el problema de los controladores de vista masivos.
Christophe