11 ms·
Much ado about iOS app architecture
- phreack 9y agoOP brings some great points (I've had a lot of trouble with an inherited code-based UI in Swift), but I was dying to see code examples of the 'correct way' to use UIKit and its patterns, particularly Dependency Injection, as I've yet to find a solution that I'm comfortable with. Can anyone link a good example?
- designcode 9y agoI have the opposite opinion. Storyboards / xibs are complete evil. Crash Xcode all the time, dont work well with version control / multiple people editing, hard to refactor.. list goes on. Code makes things very simple and reusable when it comes to UI in iOS.
- MPiccinato 9y agoI don't have a link to a good example but I have used https://github.com/Swinject/Swinject https://github.com/Swinject/Swinject in the past and it really helps get the job done. You can over do it a bit though as with anything.
- ryansobol 9y agohttp://aplus.rs/2017/highly-maintainable-app-architecture/ http://aplus.rs/2017/highly-maintainable-app-architecture/
- mephitix 9y agoDependency injection is surprisingly easy with Swift since you can implement it with protocol extensions. You don't need a framework or anything: http://www.danielhall.io/a-swift-y-approach-to-dependency-injection http://www.danielhall.io/a-swift-y-approach-to-dependency-in...
- liamzebedee 9y agoAs a full stack dev who has never written iOS apps, I have tried to understand the conceptual basics and how they compare. > Cocoa Touch is (I suspect) deliberately very simple: there’s Target-Action pattern, Dependency Injection, Delegate and MVC Can anyone enrich this explanation?
- WoodenChair 9y agoThese are pretty standard design patterns across most GUI frameworks. For instance Java Swing apps and Android apps also are commonly built with an MVC architecture. All four of these design patterns are not iOS specific, but they are design patterns the Cocoa Touch framework was made to be programmed against.
- programmarchy 9y agoTarget-Action: A button needs to send a click action to a target handler. Dependency Injection: A controller requires a service (e.g. access to some API) to work, so it's injected into the instance typically by the constructor. Think hierarchy or dependency graph. Delegate: A table view draws cells in a table but it doesn't know how to draw them, so it delegates this to something else, typically the containing view controller. Data Sources are a similar concept but instead of asking the receiver to do something it asks the receiver a question about the data it's supposed to model. For example the table view would ask how many sections and rows do I have. MVC: Model (data), View (visual representation of data), Controller (controlling flow of data to and from its visual representation).
- LeoNatan25 9y ago> Target-Action: A button needs to send a click action to a target handler. That is selling the responder chain very very short.
- nemothekid 9y ago>1. Write as little code as possible This is really sound advice that took me years to appreciate. Just like the "Roll Safe"-meme, it always comes back to me in a similar expression like from a now 8 year old blog post on MSDN - "Source code is a liability, not an asset!" (https://blogs.msdn.microsoft.com/elee/2009/03/11/source-code-is-a-liability-not-an-asset/ https://blogs.msdn.microsoft.com/elee/2009/03/11/source-code...)
- MPiccinato 9y ago> 2. Don’t fight the SDK / tools I see this quite a bit in projects where devs haven't taken the time to understand the SDK and tools/patterns provided by Apple. The biggest one I see blundered quite often is the delegate pattern in favor of an event/subscription system.
- perlpimp 9y agoI see this everywhere. I think this enshrines difference between seniority of a coder. new coders always want to write everything of their own. Senior coders want to write nothing unless they have to, remain dependency free. Learn standard vim / xcode / os keybinding etc etc. because at the end of the day the more something unique is the less chance it can be immediately useful. This works the other way too, defence against homegenity of a large pool of other businesses / coders (but this one is about marketing and not writing code). Great artists steal et al.
- Apocryphon 9y agoSo, just how did Square come up with this design pattern? https://medium.com/square-corner-blog/ziggurat-ios-app-architecture-b54b3f7132f0 https://medium.com/square-corner-blog/ziggurat-ios-app-archi...
- virmundi 9y agoWhy not just use a message bus? Push new data into bus. Things listen for that. Push reply on bus. Things listen for that. Update as necessary.
- astrange 9y agoWe call that NSNotificationCenter around here.
- zoul 9y agoExcept you can’t pull a well-typed object out of the notification. And have to use a string constant to subscribe. And if you happen to want to filter the notification stream or even gasp map over it, you’re on your own. The amount of boilerplate and subtle bugs around NSNotificationCenter is really not nice.
- thopkinson 9y agoUgh. Kill me now.
- sctb 9y agoPlease stop posting unsubstantively like this here. https://news.ycombinator.com/newsguidelines.html https://news.ycombinator.com/newsguidelines.html
- LeoNatan25 9y ago> Problems With MVC > Goes on to list non-MVC problems How many times have we seen this sort of nonsense? Facebook tried to push their observer pattern Redux on the basis that MVC is bad, and the presenter displayed something that was not MVC. The article of this topic mentions exactly this issue—I guess people this day and age do not know what MVC is.
- on_and_off 9y agoVery interesting to read this from the other side of the pond (Android dev). Android has a bit of a different architecture history : at first the framework team has built it as modular components (IIRC you were not even supposed to be able to subclass Application) with no recommandation on how to architect your app code outside of that. It lead to MVC with all the business logic in massive activities .. at least for most companies. We now have the same jungle of really abstracted patterns with some of them actively fighting against the framework by rewriting it. To be fair, parts of the framework like fragments have been a disappointment (and again to be fair Google is hard working at addressing this). I just want the minimum amount of abstraction that gives me the advantages I want (separation of concerns, testability) and not rewrite everything from scratch.
- gumballhead 9y agoExactly what I was thinking when I read that. Original Android didn't go far enough, then RxJava and clean architecture went way too far. Fortunately the new architecture components like LiveData and ViewModel coupled with kotlin (especially coroutines, wow where have those been all my life) are simple to use and understand while providing the right level of abstraction. Android development has become really nice lately.
- nsainsbury 9y agoYes, I've noticed this a lot with Android projects too. Recently I looked at a project that openly bragged about using: RxJava 2/AutoDispose, Conductor, AutoValue, Glide, ThreetenABP, Inspector, PSync, Chuck, Scalpel, Stetho, Room, Firebase, Butter Knife Look, not all of those things are bad but jesus fucking christ, what happened to exercising restraint and good judgement with introducing dependencies in to your projects? Dependencies are a LIABILITY and for something to be introduced it has to be worth it, not just provide some minor syntactical convenience (like Butter Knife, etc.)
- pjmlp 9y agoIt is called CV driven development.
- wankerrific 9y agoI feel like this guy lifted the thoughts from my head and wrote them on his blog. I agree 110% on everything here.
- flipgimble 9y agoWhile the article has a some good points about not over-engineering unless you need it, I’m really put off by the pissed off and dismissive attitude. Ex “here’s another wannabe who never bothered to learn”, “This pisses me off“, “I’ve spent 15 years” etc. This shows the author doesn’t really understand why you might decide to use an architecture that departs from the apple MVC orthodoxy, and despite “years of experience” never worked on a large, multi platform project, that tried to avoid 1st party tool lock-in, or actually implemented in-depth testing beyond the anemic xcode support. The truth is that Apple mostly cares about providing a good UI SDK with general platform services, but is agnostic about how any one app is architected. It makes sense they will preach the simplest and most general pattern: MVC. Or how about not pissing on other people’s valid ideas because you are offended and want to show off your own contrarian cleverness?
- grandalf 9y agoAgreed, the tone was arrogant and annoying.
- coldtea 9y ago>Or how about not pissing on other people’s valid ideas because you are offended and want to show off your own contrarian cleverness? How about not calling other people's criticism "showing off", "contrarian cleverness" and "pissing"?
- valuearb 9y agoI work on a 90k line application with many views written in VIPER. It’s awful. It’s an arbitrary collection of classes that reduces maintain-ability, readability and ease of debugging.
- metatation 9y ago> actually implemented in-depth testing beyond the anemic xcode support I think this is the key motivator for people looking at alternative architectures. My guess is most people wouldn't stray very far from basic UIKIt/MVC if the established practices weren't so hard to unit test. I see the experimentation with alternative approaches as the iOS community going through a phase of maturity, and is a positive signal. Many people in the community care deeply about issues of code quality and testability and while striving for simplicity. The increase in iOS architecture related articles is an indication of unrest and an active search for better practices. I suspect that it is only through these experiments that we will discover the balance we are looking for. Similarly, I think articles like the OP are a healthy resistance against the pendulum swinging too far the other way. Although I agree with several points made I'm disappointed that testability isn't even mentioned and thus many points ring hollow.
- mephitix 9y agoI generally agree with this sentiment. VIPER is terrible except for maybe 1% of projects - and those projects I envision having thousands of developers, dealing with legacy code, and fragile infrastructure. I've seen companies actively avoid auto-layout and storyboards because "it messes up during merges", so then they turn to ridiculous code-based layout which makes it impossible for designers to work with. However all those storyboard format issues were resolved back in XCode 6 (or maybe even XCode 5). I think XCode 7 introduced storyboard references which allowed devs to work on decoupled storyboards without any possibility of conflicts. Anyway what I've landed on for production apps is something closer to MVVM: Using Swift's protocol extensions for dependency injection without any frameworks, and having a view interface over the controller for testing business logic. There are other small tweaks, but for the most part, no crazy frameworks, no fighting the system. I don't agree with the idea that you HAVE to use MVC. You should try out some of these ideas if you have the time/resources and see what works, what doesn't. Make the call based on team/time to market/skills/performance requirements/reliability requirements/etc. If I'm writing a quick prototype app i'm going M(assive)VC all the way.
- jobu 9y agoVIPER reminds me of the "Enterprise Code" meme. Take a look at the FizzBuzz Enterprise Edition if you're not familiar: https://github.com/EnterpriseQualityCoding/FizzBuzzEnterpriseEdition/tree/master/src/main/java/com/seriouscompany/business/java/fizzbuzz/packagenamingpackage/interfaces https://github.com/EnterpriseQualityCoding/FizzBuzzEnterpris...
- sAuronas 9y agoMVP sans the third-party frameworks works pretty well and is easy to read, maintain and test. I prefer it to MVC, for sure, but if you really wanted to... you could still write lightweight view controllers using a lot of abstraction (and don’t forget to inject your dependencies). I have nothing against VIPER, et al, but I think the author makes some really good points on complexity and the inability to understand your system when you have to rely on some of these architectural patterns.
- irrational 9y ago>Q: Should I write clever or obvious code? A: Always be obvious! I love this. I feel like so much JavaScript code I've seen over the past few years fails on this account.
- bottled_poe 9y agoIt's about maintainability more than anything. I want a different developer to be able to jump in an understand a code base as quickly as possible. In my experience, unless there is a lot of duplicated code, it's usually much more cost effective in the long term to repeat yourself a few times (heresy I know).
- mhd 9y agoWhat's obvious to some is obtuse to others. Take iterating and filtering as a prominent example. For some, the functional approach highlights the operations themselves and avoids boilerplate. For others, the indentation of traditional loops and conditions alone is worth that. Usually there's a certain language culture attached to that. A Perl programmer sees "map sort map" and knows what's going on, everyone else is just going "Schwartzian what?". A big problem with JavaScript is that it doesn't have a culture that points in a specific direction, so you're bound to encounter all kinds of approaches, and none is really "native". Swift probably isn't as bad, but it'll hit the same cultural barriers from time to time, depending on the previous experience and general environmental conditioning of the programmers.
- kccqzy 9y agoI wholeheartedly agree. I’ll just mention that this is especially acute in Haskell. Haskell is widely considered to be a language with a steep learning curve, but for experts and experienced ones it is easy to lose track of how advanced the code really is and how obtuse it is to a beginner. The lens library is the best example. I often write extremely concise data structure manipulation code that composes lenses, prisms, getters and traversals, sometimes using (->) other times using Indexed as the profunctor. It’s obvious to me but I’m sometimes told at code review time that it’s too hard to understand.
- nielsbot 9y agoGenerally agree with the article, but of course I have my disagreements. Specifically: > I consider Auto Layout one of the top 5, maybe top 3 technologies to ever come out of Apple. It’s beautiful, easy to work with and there’s nothing I can’t do with it. It's not beautiful, nor easy to work with, nor does it work for every scenario. I am going to say something heretical: I have given up on auto layout and I find "manual" layout much easier. But that's because I rely on "one cool trick"[1]: Do not lay out views using an x-y cursor. Instead, slice up the bounds of the view being layed out using `CGRect.divide()`... So simple. If you're using manual layout but not using `CGRect.divide()`, I urge you to give it a shot it will change your life. Of course maybe everyone does it that way and I'm the only person who thinks it's a life-changer. :) [1] Side note: I learned this trick from a technical interview at EA games years ago... The best interviews are those where you leave knowing more than when you went in, even if you don't get the job.
- cageface 9y agoDealing with auto layout is probably my least favorite aspect of iOS dev, but I wouldn't recommend doing layout by hand. There are just too many variables to consider to write really robust manual layouts. That said I'm really disappointed with UIStackView. When it was first announced it seemed like a great solution to a lot of common layout problems but in practice I've found it tends to cause as many problems as it solves and now I mostly just use it when I need a clean way to hide & reveal various UI elements dynamically. I'd take some variant of flexbox over all this any day.
- nielsbot 9y agoI do think auto-layout could be fixed with better a) design tools and b) visualization, test and debug tools.
- oculusthrift 9y agoi just use pure nslayoutconstraints and don’t have to deal with uibuilder. i find it pretty easy. especially if you code yourself some helper functions for it
- 9y ago
- mdhughes 9y agoAs a Mac and iOS dev since 2005: For long-term survival and maintenance of your software, XIB and autolayout are slow toxins, and Swift is a swift-acting toxin. You won't be able to recompile your Swift code in a year. Or worse, it'll compile but be semantically different. You won't be able to edit a XIB without fixing AL issues in 1-2 years, and the XIB will be unreadable in 5-10. The part of Xcode that used to be Interface Builder is still useful for prototyping, but don't ship that! Write complex UI in code. Autolayout strings in code aren't as bad as the obscure UI, but one can just as easily compute and set frames. Choose any language except Swift. Or, good luck with your walking-dead software.
- saagarjha 9y agoSwift is slowly moving towards binary and source stability. Storyboards are more capable then they used to be–and they're literally XML. How can you make that unreadable?
- mdhughes 9y agoSwift devs keep saying it'll get less fragile, then they rewrite "exceptions", or how strings work, or anything else and all your code has to be fixed line-by-line. I do not believe it'll be stable this decade. Xcode stops supporting old features in XIB, or a class has a deprecated and then removed property, and the deserialization fails. XIB is not XML with a nice semantic DTD, it's an object serialization graph that happens to use XML.
- valuearb 9y agoNah, I switched to Swift at v1.0, the transitions have been relatively easy. Right now our app has 90k lines of code so Swift 3 was a day of work, but mostly automated. Swift 4 is automatic. The trick to making the transitions easy is to not abuse the language with too clever code. Write clear, straightforward and easily msinatainavle code and it will rarely be broken.
- deleted 9y ago[deleted]
- zoul 9y agoFWIW, my experience is almost exactly opposite. There’s not enough architecture in the iOS world. The norm is to stitch together the app without clear notion of the state or its transitions, everything is hidden in a giant tangle of view controllers, a lot of the state is crammed into the app delegate singleton, everything calls everything else via singletons and good luck finding the UI flow in a web of storyboards where arguments are passed in prepareForSegue. It’s a huge mess. Talking about target-action or delegation in this context is IMHO a misunderstanding. These are very nice and valid solutions, but in my experience they are simply not enough to build a structured non-trivial app with. They are the basic building blocks, but there has to be something above them. Of course, it’s also a mistake to go overboard with structure, drowning the important bits in architecture boilerplate. Architecture cannot and must not be followed blindly, as a cooking book. You have to aim for a reasonable compromise, a point of diminishing returns.
- bsaul 9y agoAgree with that. recently gave a talk at a iOS developper meeting, and less than 5% of the dev heard about the concept of a "service layer"
- hashmal 9y agoIt was my experience as well, but over time things "click" and your VCs are suddenly small, there is almost nothing in AppDelegate and the app architecture becomes obvious. I can't explain how to reach that state of mind, though. (and I'm not writing trivial apps…)
- lukeredpath 9y agoiOS is relatively young. It attracts a lot of new programmers. For years iOS suffered from lack of ideas around architecture and solid programming practices. In the last few years I've seen this start to change and now it seems a bit like "ARCHITECTURE ALL THE THINGS!!!". We're in a period of trying out new ideas and figuring out what works and what doesn't. Give it a few more years and these ideas will start to mature.
- bsaul 9y agoSmall hijacking / ad. i recently posted this template of a (decently) architectured app, to be used by anyone. https://github.com/SimpleApp/evc-swift https://github.com/SimpleApp/evc-swift It's focusing specificaly on the model layer (which i think most ios dev don't spend enough time on). But, like OP, it's also advocating to stay extremely close to the original MVC design. Free to use and contribute.
- htormey 9y agoOne big problem with using interface builder to build UI is code review & working on UI in parallel. This isn’t an issue in smaller apps but if you work on a larger team (5+) it becomes a real pain. I really wish that Apple had taken the approach that Google did with using xml (or something humanly readable) to describe the UIs generated by visual tools.
- herodotus 9y agoI agree with most of this article, but an issue that he does not address is the fact that Apple constantly "refreshes" the UIKit APIs - every WWDC shows the new cool way to do something or other, and their own Apps usually exploit these new things. Look at the Podcast App in iOS 11 for example - what used to be a very simple table based app now uses collection views and fancy presentation views that have multiple states. Unfortunately, App developers face pressure for their Apps to look relevant, so it is not easy to ignore these "improvements" to UIKit in ones own apps. Adopting the new UIKit stuff inevitably leads to bloat.
- gwbennett 9y agoArticle is right on! Read my mind. I've been a developer for 20+ years and iOS developers since developers could write iOS apps. Mac apps before that. I can't tell you how many hours I have had to fix "clever code" and clever architecture. It is so easy to jump into an app that follow the usual iOS design patterns. As soon as I see NSNotificationCenter or Event bus garbage going on, I know the app is a design/maintenance nightmare. Keep it simple, following patterns like MVC, delegates and protocols. Keep your view code, business code and controller code separate. That is 90% of the issues.
- thopkinson 9y agoconcur. My experience exactly.
- thopkinson 9y agoYes. Perfectly expresses what I've observed time and time and time again through the years. Nails it.
- apple4ever 9y agoNumber 4 is terrible and a big reason why I hate Swift. Don't make the code so clever you don't know how it works. Use Objective-C and you'll be good.
- kp1234321 9y agoI could understand the frustration working on a smaller project solo or with a few other developers. MVC is probably the best approach to get an MVP. But when you work on an app with 100+ other developers and need to support millions of customers, it's nice to have some more structured and verbose architecture.