[iOS] Clean MVC programmeren

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • BikkelZ
  • Registratie: Januari 2000
  • Laatst online: 21-02 08:50
Ik ken MVC uit zowel PHP als Microsoft.Net en ik moet zeggen dat ik het vooral op .Net erg lekker vind werken. Ook een tijdje met MVVM onder WPF gewerkt en dat werkte ook fijn als je het goed aanpakte. Nu lijkt er op papier precies het zelfde te bestaan voor iOS, namelijk een UIView as je View, UIViewController als je Controller en objecten gemapt naar je webservices of managed objects.

Het probleem waar ik tegen aan loop is dat in de praktijk mijn ViewController vol met UI-gerelateerde code zit zoals het uitvoeren van een animatie na een klik, het toevoegen van items in een grid vorm en de spatiering daar van en ga zo maar door. Daar tussendoor nog wat routings van clicks en delegates.

Kortom: mijn Controller weet *alles* van de View en is dus helemaal geen netjes gescheiden laag. Ook gebeuren er dus een hoop verschillende niet echt gerelateerde dingen in één class en dat is dus ook niet helemaal volgens de manier waarop ik normaliter werk met classes. Eigenlijk is het meer een soort van Code Behind van een Win- WebForms project met alle lelijke dingen die daar bij horen.

Naar mijn beleving is een goede Controller een controller die een actie ontvangt en dan de boel aan elkaar knoopt zodat de juiste View opgebouwd wordt met de juiste data, maar misschien dat ik daarmee weer iets te veel in het webdenken blijf hangen. Maar MVVM onder WPF bewijst dat je ook bij een desktop applicatie prima alles gescheiden kunt houden.

Hoe gaan jullie hier nou in de praktijk mee om?

iOS developer


Acties:
  • 0 Henk 'm!

  • ZpAz
  • Registratie: September 2005
  • Laatst online: 21:12
Het probleem waar ik tegen aan loop is dat in de praktijk mijn ViewController vol met UI-gerelateerde code zit zoals het uitvoeren van een animatie na een klik, het toevoegen van items in een grid vorm en de spatiering daar van en ga zo maar door. Daar tussendoor nog wat routings van clicks en delegates.
Je zegt, het animering en de spatiering van de items is iets voor de view als ik het zo lees.

Je zou toch de betreffende view kunnen subclassen en dan vanuit de controller op de events bepaalde methodes daarbinnnen kunnen aanroepen?

Tweakers Time Machine Browser Extension | Chrome : Firefox


Acties:
  • 0 Henk 'm!

  • Herko_ter_Horst
  • Registratie: November 2002
  • Niet online
iOS legt het accent van MVC inderdaad iets anders dan veel web-frameworks. In iOS heb je vooral te maken met geheel generieke views die je in XCode in elkaar klikt en specifieke Controllers die de vertaling doen naar je Model en v.v.. Dat je Controller veel weet van de view is dus normaal (hoewel spatiering er m.i. niet in zou moeten zitten, dan heb je misschien de verkeerde view gepakt).

In Web frameworks heb je vaak nog de mogelijkheid iets van processing in je view te stoppen (een forEach om een tabel op te bouwen o.i.d.). Views in een webapp zijn daarmee vaak specifieker voor een bepaalde toepassing. Dat is er in iOS niet bij.

Ik kan je aanraden om de cursus iOS ontwikkeling van Stanford University (gratis via iTunes) eens te bekijken, hierin legt prof. Hegarty heel duidelijk uit hoe MVC in iOS in elkaar zit.

"Any sufficiently advanced technology is indistinguishable from magic."


Acties:
  • 0 Henk 'm!

  • BikkelZ
  • Registratie: Januari 2000
  • Laatst online: 21-02 08:50
ZpAz schreef op maandag 15 april 2013 @ 16:53:
[...]


Je zegt, het animering en de spatiering van de items is iets voor de view als ik het zo lees.

Je zou toch de betreffende view kunnen subclassen en dan vanuit de controller op de events bepaalde methodes daarbinnnen kunnen aanroepen?
Klop het subclassen van bijvoorbeeld de UIButton class en daar dan wat extra code in plakken dat gaat tot zeker hoogte prima en dat doe ik nu ook (het kan ook niet echt anders als je code maar één keer wilt schrijven). Maar toch ben je dan alsnog een hoop code vanuit de Controller aan het schrijven om dat weer aan te sturen.
Herko_ter_Horst schreef op maandag 15 april 2013 @ 19:21:
In Web frameworks heb je vaak nog de mogelijkheid iets van processing in je view te stoppen (een forEach om een tabel op te bouwen o.i.d.). Views in een webapp zijn daarmee vaak specifieker voor een bepaalde toepassing. Dat is er in iOS niet bij.
Op zich gaat het er inderdaad om dat je gewoon vanuit je Controller gewoon een bepaalde View moet kunnen aanroepen die verder niet gebabysit hoeft te worden vanuit je Controller. Gewoon een Model of ViewModel aanbieden aan een View en die gaat daar lekker verder meer los. Of dat dat nou alleen vanuit een front-end template met repeaters en andere handigheden gebeurt of via een klassiekere code-behind methode maakt voor mij verder niet zo veel uit. Maar nu zit mijn code-behind door mijn Controller heen.
Herko_ter_Horst schreef op maandag 15 april 2013 @ 19:21:
Ik kan je aanraden om de cursus iOS ontwikkeling van Stanford University (gratis via iTunes) eens te bekijken, hierin legt prof. Hegarty heel duidelijk uit hoe MVC in iOS in elkaar zit.
Thanks ik zal hem eens bekijken.

Maar ik ben eigenlijk vooral op zoek naar een stukje elegantie in plaats van "tja het werkt wel maar ik kijk er liever niet naar"

iOS developer


Acties:
  • 0 Henk 'm!

  • ZpAz
  • Registratie: September 2005
  • Laatst online: 21:12
Klop het subclassen van bijvoorbeeld de UIButton class en daar dan wat extra code in plakken dat gaat tot zeker hoogte prima en dat doe ik nu ook (het kan ook niet echt anders als je code maar één keer wilt schrijven). Maar toch ben je dan alsnog een hoop code vanuit de Controller aan het schrijven om dat weer aan te sturen.
Zou je een voorbeeld kunnen geven? :)

Tweakers Time Machine Browser Extension | Chrome : Firefox


Acties:
  • 0 Henk 'm!

  • Herko_ter_Horst
  • Registratie: November 2002
  • Niet online
BikkelZ schreef op maandag 15 april 2013 @ 20:37:
Op zich gaat het er inderdaad om dat je gewoon vanuit je Controller gewoon een bepaalde View moet kunnen aanroepen die verder niet gebabysit hoeft te worden vanuit je Controller. Gewoon een Model of ViewModel aanbieden aan een View en die gaat daar lekker verder meer los. Of dat dat nou alleen vanuit een front-end template met repeaters en andere handigheden gebeurt of via een klassiekere code-behind methode maakt voor mij verder niet zo veel uit. Maar nu zit mijn code-behind door mijn Controller heen.
Dat is jouw interpretatie van MVC :)

Wat jij beschrijft, komt volgens mij overeen met de Presentation Model aanpak.

iOS heeft daarentegen een Passive View aanpak. UIView sub-classing gebeurt nauwelijks, UIViewController sub-classing altijd.

Het is gewoon een andere aanpak. Je kan je ertegen verzetten en je app op dezelfde manier bouwen als je gewend was met je .Net webapps, maar dan haal je niet alles uit de ondersteuning die Xcode je biedt. De code wordt er volgens mij ook niet lelijker van.

De verantwoordelijkheden liggen nog steeds heel helder: View weet absoluut niks van Model, View weet ook niks van Controller (m.u.v. goed gedefinieerde delegates). Model weet niks van View en Controller, maar kan alleen "events" sturen via Protocols. Alleen Controller weet "alles".

"Any sufficiently advanced technology is indistinguishable from magic."


Acties:
  • 0 Henk 'm!

  • BikkelZ
  • Registratie: Januari 2000
  • Laatst online: 21-02 08:50
Herko_ter_Horst schreef op maandag 15 april 2013 @ 21:39:
[...]

Dat is jouw interpretatie van MVC :)

Wat jij beschrijft, komt volgens mij overeen met de Presentation Model aanpak.
Exact.
Herko_ter_Horst schreef op maandag 15 april 2013 @ 21:39:
[...]

iOS heeft daarentegen een Passive View aanpak. UIView sub-classing gebeurt nauwelijks, UIViewController sub-classing altijd.

Het is gewoon een andere aanpak. Je kan je ertegen verzetten en je app op dezelfde manier bouwen als je gewend was met je .Net webapps, maar dan haal je niet alles uit de ondersteuning die Xcode je biedt. De code wordt er volgens mij ook niet lelijker van.
Ik ben zelf altijd iemand die roept dat de beste standaard de standaard is die iedereen volgt, want dan heb je consistente code. Maar het wordt voor mij gewoon erg rommelig. Neem dit als voorbeeld:

Ik heb een scherm gebouwd waarin een rits met foto's toegevoegd worden aan de hand van hoe groot ze zijn en hoe groot ze maximaal mogen zijn volgens mijn config, en vervolgens gecentreerd. Deze foto's kun je vervolgens slepen naar een andere plek om ze van volgorde laten veranderen, verwijderen of via een custom implementatie van de camera een rits foto's toevoegen en dan het meeste ook nog geanimeerd.

- initialisatie van de View aan de hand van de data
- alle koppelingen van knoppen naar functies
- alle drag en drop code voor sorteren, toevoegen en verwijderen
- initialisatie en respons van de camera subview
- verificatie en opslaan model aansturen
- hierbij weer een block managen omdat het asynchroon gebeurt
- overgangen naar andere schermen

Bij mij roept mijn intuitie dan steeds "je class heeft te veel code, je class doet te veel dingen". Het wordt ook lastig bepaalde dingen nog terug te vinden.

Hoe zorg ik er nou voor dat op een logische manier mijn code wat beter opgesplitst en opgeschoond kan worden? Ik heb wel vaker gehad dat het een tijdje duurde voordat ik een nieuw pattern helemaal begreep, dus ik wil dit ook best wel een kans geven. Ik merk sowieso wel dat PresentationModel achtige dingen heel erg lastig gaan worden omdat ze tegen de filosofie in gaan.

[ Voor 8% gewijzigd door BikkelZ op 15-04-2013 22:33 ]

iOS developer


Acties:
  • 0 Henk 'm!

  • Herko_ter_Horst
  • Registratie: November 2002
  • Niet online
Zonder je code te kennen, valt er voor mij niet zoveel over te zeggen (en eerlijk gezegd ben ik zelf ook nog ietwat een noob in iOS programmeren - maar met 15 jaar Java-ervaring en dan die cursus van Stanford durf ik er wel iets over te zeggen ;)).

Als je dat allemaal in 1 view/viewcontroller hebt zitten, dan klinkt het alsof je iets niet goed doet. Een iOS "view"/"pagina" bestaat typisch uit een hele hierarchie van views en viewtjes, elk met hun eigen controller. Daarmee worden gelijk de verantwoordelijkheden verdeeld.

In hoeverre is de functionaliteit die je wilt op te delen in subviews? Maak je voor de overgang naar andere schermen gebruik van een UINavigationController sub-class? Of een UITabBarController o.i.d?

Ik kan je echt aanraden die online-cursus te volgen. Een hele rits concepten en best practices m.b.t. Xcode en de manier waarop iOS MVC "doet", worden in een redelijk tempo op een heldere manier uit de doeken gedaan. Wel een solide OO-achtergrond vereist, maar dat lijkt me voor jou het probleem niet :)

"Any sufficiently advanced technology is indistinguishable from magic."


Acties:
  • 0 Henk 'm!

  • BikkelZ
  • Registratie: Januari 2000
  • Laatst online: 21-02 08:50
Herko_ter_Horst schreef op maandag 15 april 2013 @ 23:25:

Als je dat allemaal in 1 view/viewcontroller hebt zitten, dan klinkt het alsof je iets niet goed doet. Een iOS "view"/"pagina" bestaat typisch uit een hele hierarchie van views en viewtjes, elk met hun eigen controller. Daarmee worden gelijk de verantwoordelijkheden verdeeld.
Hoewel ik denk dat dat voorbeeld van die fotoapp niet veel anders gekund had omdat het nou eenmaal redelijk complex is om drag-overs en dergelijke netjes te doen heb je hier misschien wel een goed punt. Volgens mij heb ik alleen een CaptureImagesView gemaakt met bijbehorende Controller omdat die dan gelijk het hele scherm overneemt via een present functie. Maar een UIView met een UIViewController gebruiken zoals ik met een simpele UIView (animeren, toevoegen in interface builder als een klein onderdeel met sub-onderdelen) doe lukte me niet.

Als het toch mogelijk is om meerdere UIViews met UIViewControllers genest te kunnen gebruiken dan zou dat een stuk beter zijn, ik ben er op vastgelopen. Het zou in ieder geval een beetje als een WebForms applicatie gaan werken, een hoop wiring van events en inits maar wel gescheiden en makkelijk herbruikbare ViewControllers.
Herko_ter_Horst schreef op maandag 15 april 2013 @ 23:25:
In hoeverre is de functionaliteit die je wilt op te delen in subviews? Maak je voor de overgang naar andere schermen gebruik van een UINavigationController sub-class? Of een UITabBarController o.i.d?
Met deze app ben ik gewoon begonnen met de houding de praktijk is de beste leermeester (voor mij iig, ik duik overal gewoon in) maar het was wel een harde leermeester. Ik zou hem de volgende keer wel opzetten met een soort navigatiebalk er in met een subview met de echte content maar nu is het gewoon scherm-scherm-scherm met een geneste UIView steeds overal voor sessie en uitloggen (niet super ideaal dus). Ik heb alles er in zitten wat ik er in wilde hebben en hoe de klant het wilde hebben maar ik ben dus zeker niet eerst braaf een boek en tutorials gaan lezen. Het is net zo goed een les geweest van hoe het niet moet als hoe het wel moet ;)
Herko_ter_Horst schreef op maandag 15 april 2013 @ 23:25:
Ik kan je echt aanraden die online-cursus te volgen. Een hele rits concepten en best practices m.b.t. Xcode en de manier waarop iOS MVC "doet", worden in een redelijk tempo op een heldere manier uit de doeken gedaan. Wel een solide OO-achtergrond vereist, maar dat lijkt me voor jou het probleem niet :)
Ik ga het maar eens doen dan in de dode uurtjes. In welk deel zou ik het gedeelte over het nesten van Views kunnen vinden? Deel 5?

iOS developer


Acties:
  • 0 Henk 'm!

  • Herko_ter_Horst
  • Registratie: November 2002
  • Niet online
BikkelZ schreef op dinsdag 16 april 2013 @ 04:01:
Ik ga het maar eens doen dan in de dode uurtjes. In welk deel zou ik het gedeelte over het nesten van Views kunnen vinden? Deel 5?
Ik zou zeker even vooraf het deel over MVC "the iOS way" meepakken uit lecture 1. In lecture 5 gaat het introduceert genestte views, aan de hand van het specifieke voorbeeld van de UITabBarController. Lecture 6 gaat er dieper op in. Het stuk in lecture 8 over auto-layout is ook erg nuttig om te voorkomen dat je allerlei layout-zaken in je Controller moet gaan regelen.

[ Voor 27% gewijzigd door Herko_ter_Horst op 16-04-2013 18:36 ]

"Any sufficiently advanced technology is indistinguishable from magic."


Acties:
  • 0 Henk 'm!

  • BikkelZ
  • Registratie: Januari 2000
  • Laatst online: 21-02 08:50
Die autolayouts zijn geniaal, als ik codematig een layout opzet dan doe ik het vaak toch even via Interface Builder eerst om te zien welke er gegenereerd worden.

Bedankt Herko, ik kan weer even vooruit :)

iOS developer

Pagina: 1