



Agenda
I want to talk about iOS app architecture and Test Driven Development.
For the past couple of years I’ve been developing the feeling that there’s something seriously wrong with how a lot of people are approaching iOS development. Apple has made certain decisions with their framework design and tools which I believe contributes to this problem.
Specifically I’m talking about where the application and business logic for an app belongs, and how the overall architecture of an app should be constructed. I feel I need to slap some people across the face and bring them to their senses (including myself).
This is going to be the first in a series of posts. Today we’re going to find out why Apple has created a total abomination of design with UIViewController
. Should be fun.
In future posts I will describe an Uncle Bob style “Clean Architecture” for iOS apps, driven by TDD. I haven’t seen anything like this from other writers/developers, so be sure to subscribe (or follow me on twitter) if that sounds interesting.
The Humble View Controller?
Way back in 2002, Michael Feathers (of “Working Effectively with Legacy Code” fame) wrote a piece titled The Humble Dialog Box. In it, he describes a particular approach to separating GUI-specific code from the actual application logic behind a simple dialog box.
We’ll revisit this piece sometime in the future, but for now I want to focus on the introductory problems he describes. Remember he is talking about building desktop applications here:
Let’s take a look at our friend the dialog box. […]
Tool vendors have made it easy to create dialog boxes. Nearly every IDE on the market has a GUI builder. You can drag and drop all sorts of components on dialogs and drill down to wire them up. […]
It is easy to just override an event from a component and drop your interaction logic right there in the dialog box class.
He goes on to describe the problems that typically arise with these dialog box classes:
- It’s difficult to get these UI classes under a test harness because they are so tied to UI-specific frameworks. There is no separation between the UI and interaction/application logic.
- The UI classes have a mixture of low level component API code as well as actual decision making code, making it hard to see what the code is doing or to share code between objects with similar behaviour.
These statements perfectly describe a typical iOS view controller. It’s easy to drop code into an IBAction
method or a delegate call on the view controller, and do everything right there and then. This can lead to a mixture of “component API” (i.e. UIKit) and important decision making code.
Apple has made UIViewController
the center of the iOS universe. When you add a new screen to your app, the only thing that Xcode gives you is a new UIViewController
subclass. And Apple makes it so easy to do everything from this view controller. If you aren’t really careful, you can end up with an application consisting entirely of view controller classes and little else.
Now of course there are good developers out there who are creating nicely decoupled classes, but if we list out some of the responsibilities that a view controller typically ends up dealing with, we’ll see just how pervasive this problem is, even in code written by experienced developers.
Spotted in the wild
View setup and layout code
By default, when you hook up a new control to your view controller’s XIB or storyboard (for example a UIButton
or UILabel
), the IBOutlet connection is going to go to a property on your view controller. The whole assistant-editor workflow is designed to do this. All of the sample code, tutorials and books you will ever read will do this as well.
If you need to tweak that control’s settings in code, your first stop will probably be the trusty -viewDidLoad
method:
- (void)viewDidLoad { [super viewDidLoad]; self.myButton.titleLabel.font = myCustomFont; UIImage *stretchableImage = /* ... blurgh ... */ [self.myButton setBackgroundImage:stretchableImage forControlState:UIControlStateNormal]; /* ... more 'blurgh' ... */ }
Over time, your -viewDidLoad
will likely grow. You may even create new controls in here that don’t exist in your XIB file. Even if you break things out into multiple methods, a significant part of your view controller’s code can end up dealing with view setup and creation. The situation is worse if you forgo XIB files entirely.
And what if you have custom layout requirements which can’t be solved in IB?
Well… you could create a UIView
subclass and implement -layoutSubviews
. But you already have all your IBOutlets going to the view controller. You would have to move all the IBOutlet connections and properties to this new view class — and why bother with all that when it’s so easy to add some code to -viewWillAppear:
:
- (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; self.myLabel.frame = /* ... */ self.myButton.frame = /* ... */ }
Even though using a UIView
subclass and overriding -layoutSubviews
is a far superior way to layout your controls (and is in fact the correct way), people end up putting this stuff in their view controllers because that’s the easiest thing to do.
And then they have to deal with view rotation issues, and not being told when the view’s frame changes. Even worse, because this stuff is so hard to do properly from the view controller, people often end up hard coding interface sizes and frames rather than implementing truly dynamic view layouts.
I’ve seen people doing layout in the -viewDidLoad
method, before the view is even part of the view hierarchy. And they wonder why things mess up. You can’t even blame them. After all, it is Apple who is encouraging people to connect their IBOutlets to the view controller.
It all becomes a hideous mess, and could easily be solved with UIView
subclasses. But Apple doesn’t teach us to do this. I doubt many novice or intermediate iOS developers have even heard of -layoutSubviews
or -sizeThatFits:
. All Apple gives us by default is a view controller subclass.
Even with Autolayout the problem doesn’t go away. The view controller still ends up being the place to create custom constraints, for the same reasons as above. That’s just how people do it. Even Apple engineers do it this way in their WWDC videos.

So the Xcode/Apple-approved default is to have all of your view setup and layout code in the view controller. Why is this a bad thing? Quite simply, because view layout and setup code should (in my opinion) always go in UIView
subclasses. That’s where it belongs, and life is a lot easier when you do it this way. Putting this stuff in the view controller is just contributing to an already bloated and confused class.
Core Data and NSFetchedResultsController
code
All of the Core Data sample code that I’ve seen from Apple creates and sets up the NSFetchedResultsController
in a -fetchedResultsController
method on the view controller. It’s usually a huge long method which sets up the fetch request, configures the fetchBatchSize
, predicate, sort descriptors etc.

Unfortunately I’ve seen a lot of people who have copy/pasted this kind of code into their view controllers. As time goes on, the view controller ends up with a dozen methods just dealing with Core Data - fetching results, updating records, performing background operations, merging contexts, etc.
None of this stuff belongs in the view controller. You have business logic like sorting and filtering rules mixed in with the details of the persistence framework (Core Data), and all of this inside the view controller. A “view controller” should not be dealing with this stuff, and Apple unfortunately does not show new-comers how to do this properly.
Be the delegate for everything
Even if you pull your Core Data code out into a nice class or interface, your view controller will probably end up being the delegate and datasource for the table view displaying that data. It’ll contain the code to create and configure table view cells for a given item, define section titles and row heights, handle insertion and deletion operations, and respond to any of the dozen or more delegate/datasource callbacks that are available.
If your app is making use of CLLocationManager
, your view controller will probably end up responding to and handling location events. It might even be the one that creates the location manager in the first place. Another of Apple’s tutorials does just this.

If your view controller makes use of MPMoviePlayerController
or QLPreviewController
or MFMailComposeViewController
you’ll probably be the delegate for those as well. You can also throw in Twitter and Facebook API callbacks (and sharing in general), quick one-off AFNetworking
or NSURLConnection
web service requests, NSTimer
s doing periodic background work, SCNetworkReachability
checks, and the list goes on.
Because UIViewController
s are such a central part of an iOS app, they end up being the delegate for everything. They end up accumulating all this crap. If the view controller was purely forwarding information and acting as an intermediary, this might not be so bad. But we all know that’s rarely the case.
You really have to be on the ball to keep this stuff nicely separated, and I’ve seen a lot of codebases which fail to do this.
Accessing global state
Because it’s so easy to drop code into a view controller, and because Xcode doesn’t give you any other place to start adding your code, inexperienced developers have trouble accessing the information they need.
They end up using hideous hacks like ((IHaveNoIdeaWhatImDoing*)[[UIApplication sharedApplicaton] delegate]).objectThatINeed
, or singletons, or notifications, to access everything they need. Stackoverflow and internet forums get inundated with questions of the form “How to I pass information from one view controller to another”?
The reason this is so difficult is that they haven’t been taught to write higher-level objects which deal with the interactions and flow of information in their app.
So not only do many view controllers have dozens of delegate calls coming in to them, they also have hideous clawed tentacles reaching out all over the application, accessing global state and further coupling the view controller to other parts of the application.


You can argue that this is just a problem of inexperienced developers, but Apple really does not help people to develop good coding practices. I’ve seen Apple sample code using [[UIApplication sharedApplicaton] delegate]
to access global state, and it’s really a terrible practice to encourage. In fact I already have a blog post half-written which deals precisely with this topic.
Navigation logic and other “decision making” code
When the user selects a cell from your table view, you are going to handle the tableView:didSelectRowAtIndexPath:
method.
Your app now has to decide what to do. In a typical drill-down style of navigation, you want to push some sort of “details” screen for the selected item.
Apple makes this really easy with convenience methods on UIViewController
like -navigationController
, -tabBarController
, -splitViewController
, etc. Your view controller can directly grab a reference to the container that holds it.
You can then do something like this:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { id item = [self itemAtIndexPath:indexPath]; DetailsViewController *detailsVC = [[DetailsViewController alloc] initWithItem:item]; [self.navigationController pushViewController:detailsVC animated:YES]; }
Perfect! The navigation logic can be dropped right there in the view controller!
But what if you later make your app universal, and the details screen needs to appear in a split view controller on iPad devices?
Well, no problem. We’ll add a little runtime check:
DetailsViewController *detailsVC = /* ... */; if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { // display details in the split view controller's details pane } else { // push details to the current navigation controller }
We also need to keep the cell selected on the iPad, but deselect it in viewWillAppear:
on iPhone devices (this is what UITableViewController
does by default). This adds a few more if statements to the controller.
But what if you now want to present this view controller modally at some point in your application so the user can select one item for a task? In that case you need to dismiss the view controller and somehow notify the parent about which item was selected.
We can’t keep adding more and more if statements to our view controller. It’s pretty clear that this kind of navigation logic doesn’t belong in the view controller.
A view controller should not know about the high level work flow of your app. It shouldn’t know about its surroundings. It shouldn’t know that it’s being presented modally, or that it’s contained by a navigation controller, or a split view controller, or a tab bar controller. It shouldn’t even have references to these things, even though Apple decided to “help” us out by tacking on all these category methods. It shouldn’t even know about the DetailsViewController
. That’s an entirely different screen of our app.
If our view controller is displaying a list of items (think a typical table view controller), that’s all it should be concerned with. It should provide some delegate callbacks for when a given cell or item is selected, and perhaps a few ways to customize the display or behaviour of the cells, for example to enable a check-multiple-items style of selection.

The view controller should only be concerned with the behaviour of the view that it presents. By putting navigation logic in the view controller, you are coupling it to the specifics of your app’s UI and navigation. If you want to change the workflow later (e.g. for other devices), or reuse that view controller in a different context (or even a different app), you are going to encounter a lot of pain.
So where should this navigation logic go? Well… somewhere else. We’ll get into that in a later post. All that matters for now is that the view controller should delegate UI actions like this to somebody at a higher level, who has access to and knowledge of the specifics of your app’s UI workflow.
This is also why I have a big problem with Storyboards. When you implement a Storyboard app, you are forced to put application-specific navigation logic in the view controllers by implementing the various UIViewController
segue-related methods. There’s no other way to do it. And delegating this stuff out to somewhere else really confuses the matter because you have this extra level of indirection between the storyboard XIB and the segue code. Reusing view controllers in other apps or screens suddenly becomes impossible to do (or at least very difficult) without creating a total mess of things.
Official UIKit responsibilities
So far we’ve mostly looked at logic and code that could theoretically be pulled out of the view controller and put somewhere else. You’ll probably be doing this already to a greater or lesser extent.
But what about the stuff that a UIViewController
must deal with? What about it’s official UIKit responsibilities?
In fact, what the hell is a “view controller” anyway? Does anybody actually know? Why do we now have view controller containment hierarchies as well as regular view hierarchies? How does it differ from a UIView
in this case? What does this all have to do with MVC?
What is a view controller?
To figure this out, we are going to start pulling code out of some hypothetical view controller and see what’s left at the end.
First we’ll move all that horrible view setup and layout code into a UIView
subclass. Done.
Then we’ll move all the core data and model code into some nice protocols/classes, which are injected into the view controller through public properties or an -init
method. Done.
We’ll move the table view delegate/datasource code into dedicated classes. Done.
Any miscellaneous framework code, url requests, etc. will also be pulled out behind nice interfaces, and our view controller will simply funnel data back and forth between the view and these interfaces. Done.
Finally, let’s delegate navigation events like certain button presses and cell taps to somebody else, so the view controller’s behaviour can be customized easily for use in different contexts. Done.
What are we left with at the end of all this?
We’re left with a class that:
- Lazily loads a view (by calling
-loadView
when the-view
property is accessed for the first time) - Can load its view from a NIB file in a convenient manner.
- Provides access to various events like
-viewDidAppear:
,-didRotateFromInterfaceOrientation:
, and-didReceiveMemoryWarning
. - Deals with state restoration to restore state between launches of your application.
- Handles storyboard segues to pass data to the view controller that is being transitioned to.
- Can provide accessibility information about the content it displays.
- Allows you to define which interface orientations are allowed when its view is at the top of the view hierarchy.
- Can be inserted into UIKit’s standard containers like
UINavigationController
andUITabBarController
(alsoUIWindow
), with a bunch of properties likenavigationItem
andtabBarItem
to customise its appearance in these. - Can be nested inside another view controller in a UIKit-safe way.
- Happens to be part of the responder chain, so can respond to and handle certain types of input events.
Wow. That’s a lot of stuff, and I’ve probably forgotten some things. It also sounds a hell of a lot like a view to me. The lines are starting to blur. It certainly doesn’t sound like a place for important business or application logic.
If you look at the actual interface for UIViewController
— the methods and properties it declares, it’s almost all view/presentation related. Go on, pop open Dash and take a look right now. I can only count 5 methods out of 86 that are not presentation related. These are -didReceiveMemoryWarning
and the 4 state restoration methods that came with iOS 6. Everything else is related to the view. And that’s not even including all the category methods that get added on by other UIKit headers.
An identity crisis

What if we continue to pull stuff out of UIViewController
?
-viewDidAppear:
and all the other view-related events would be much happier sitting on the UIView
class instead, for instance.
Lazy loading also seems to be a detail that belongs elsewhere. Don’t we just want something like this?
UILazyLoadedView *lazy = [[UILazyLoadedView alloc] initWithLoadViewBlock:^{ MyView *v = [[MyView alloc] init]; // restore view state return v; }];
Then we just change the UINavigationController
and other container classes to accept a UILazyLoadedView
where applicable. When our view needs to be displayed or loaded, UIKit can invoke the block and get a view returned to it. Any view state can be captured/restored in the block, making it work well when the view is unloaded/reloaded (prior to iOS 6 anyway).
Let’s look at the navigationItem
/tabBarItem
/etc. properties now.
These properties are used to customise the way the view controller appears in navigation controllers, tab bar controllers, etc. These customizations are always going to vary depending on the context in which the view controller is presented.
So do these properties really belong on the view controller? They’re actually part of the interfaces for the various container controllers that Apple gives us. But they’ve been “helpfully” tacked on to UIViewController
via categories. Is this really a good idea? Didn’t we already establish that a view controller should only know about the content it displays and manages?
If a view controller represents a screen of your app, why does it need to know the title of its back button when another screen is being displayed? Why does it need to have access to the icon image in its tab bar button? Shouldn’t that be managed by the class that set up the tab bar controller, or that pushed it onto the navigation controller?
When we consider the multitude of responsibilities a view controller already has, does it really need to deal with the specifics of all these container controllers as well?
Couldn’t we remove these category methods entirely and provide the information when we do the actual push? Something like this:
UILazyLoadedView *lazyView = /*...*/; UINavigationControllerItem *item = [[UINavigationControllerItem alloc] initWithLazyView:lazyView title:NSLocalizedString(@"foobar", nil) backButtonTitle:/*...*/ /* etc */]; [navController pushItem:item];
I don’t know. We’re getting dangerously close to the realm of pure fantasy here. But we need to think about these things to figure out exactly what a view controller is, and what it’s main roles should be. Everything we’ve seen so far seems to belong somewhere else.
The other thing view controllers can do is “view controller containment”. This can only be described as a complete (and unnecessary) mess.

Because a view controller is just a wrapper around a view, people ended up needing to nest or compose view controller views in a single screen. But things like rotation events, -viewDidAppear:
etc. get all screwed up if you do this by manipulating the view hierarchy directly. This wouldn’t even be a problem if these methods were part of UIView
instead.
So to make this work nicely, Apple has given us the view controller containment APIs, with weird-ass requirements in the order you call the various willMoveToViewController/didMoveToViewController/addChildViewController/etc.
methods.
And now that we have this view controller containment, a view controller no longer represents an entire screen of content. It represents a portion of the screen and can be nested arbitrarily with other view controllers. So… doesn’t that just make it a view? A view with some additional UIKit details hacked on?
Somehow this all feels like a big mess to me. I’ve only covered a few items from UIViewController
’s interface, but it’s already starting to look like this weird “miscellaneous crap that UIKit needs” class with a lazy loaded view inside it. It’s a confused mess of responsibilities.
It also happens to contain the majority of our application code. This is a problem.
A black hole of bad design.

Let’s summarise the key points so far.
UIViewController
is the centre of the iOS world. Apple’s tools like Xcode and Interface Builder, and the workflow they encourage, put the view controller at the centre of everything. The default place to start when you’re adding new code or features is the view controller. When you add a new screen to your app, all you’re given is a UIViewController
subclass and a lot of helpful methods to shoot yourself in the foot.
Because of this, code and logic tend to gravitate towards the view controller. The view controller ends up being the delegate for a large number of different objects. It ends up doing view setup and layout, it ends up dealing with core data, table view datasource/delegate methods, and a huge number of other responsibilities.
Apple has tacked on a large number of “convenience” methods which let you directly access the enclosing containers like navigation controllers or tab bar controllers. This makes it very easy to couple the view controller to the specifics of your app’s navigation, and to the other view controllers it interacts with. Storyboards also contribute to this problem. This makes it difficult to reuse the view controller in other contexts or applications.
Even if you manage to keep your own interfaces/APIs nicely decoupled and separated into other classes, UIViewController
is the only place to deal with certain UIKit details, like: lazy-loading of views, configuring the display of tab bar items and navigation controller elements, view events like viewDidAppear
, rotation events, and view controller containment when you need to nest multiple view controllers inside one another.
If you have any kind of decision making logic in your view controller, it is completely coupled to the UIKit framework. As we’ll see in my next post, trying to get these things into a test harness is a disaster waiting to happen.
UIViewController
is just a detail of UIKit’s implementation. It’s more of a view than a controller, and certainly isn’t anywhere close to being a Controller in the classical MVC sense, despite what Apple tries to tell us:

“Controllers” are supposed to be nice thin objects funnelling data and events between the model and the view. They shouldn’t contain details of a specific UI framework. iOS’ View controllers are nothing like this. They sit firmly in the presentation layer.
So why are we putting so much of our important application and workflow logic into our view controllers? I feel like the iOS developer community has forgotten everything we have learnt about good OOP design in the last 20 years or so. Remember the Single Responsibility Principle? One Reason To Change? Mixing application logic in amongst the spaghetti of UIKit APIs is just plain wrong.
Isn’t there a better way? Isn’t there an escape from this madness?
I’m happy to tell you that there is a better way.
I’m going to take you on a journey, Dear Reader. A journey of self-discovery and enlightenment. Or… something like that. We’ll figure it out as we go.
We’re going to develop a Clean iOS Architecture together, driven by TDD. We’re going to find out why so many people are doing iOS TDD wrong, and how to do it right. And we’re going to see some really nice benefits from this new approach.
Won’t you join me?
PS: I’m currently looking for new job opportunities, preferably in the UK. London would be ideal. Please contact me using the email address at the top of this page if you have any offers.
Interesting and enlightening article :) I must confess that I am one of the people who overburdens the view controller like you pointed out. Most of the tutorials that I looked at when I began iOS development used that method and so I went with it without pausing to think about it. But I see the reasonableness of your arguments and am looking forward to the rest of the articles in the series so that I can see how you go about this from beginning to end.
ReplyDeleteIf it's a workable solution, I'd definitely want to switch to what you propose since that sounds more logical :)
Food for thought. I agree on some points (Core Data absolutely does not belong in a VC class. Storing globals in the App Delegate - punishable by death) but Apple is clearly pushing a design that you don't like. Whether or not you agree with it, it's the way it is. If you build your own road, nobody but you will be able to work on your iOS projects because it will be incomprehensible to anyone schooled in The Apple Way. To paraphrase Douglas Adams, if it's wrong, at least it's definitively wrong.
ReplyDeleteFor what it's worth, I find the concept of view controller code reuse to be completely overrated. How often have you been able to reuse code without any modifications? How often have you wanted to?
@jsd The kind of thing I've been doing doesn't actually depart from "The Apple Way" that much. There are still views and view controllers, we just move some logic into real controller objects (NSObject subclasses) which can be unit tested without pulling in entire UI frameworks and requiring an iOS simulator to run. As for view controller reuse, I think it depends on the kind of work one does. Doing Contract/Agency work, we have a huge number of projects and there are always things we can reuse between projects. This may not be relevant to others.
ReplyDeleteThanks a lot for this blog post. Really made me think about myself and how I develop applications. I also found out the those pesky ViewControllers really slow you down because you aren't flexible at all regarding your navigation and ViewController hierarchy. Also unit testing is really hard to do up to impossible due to wrong/non existing encapsulation. It really becomes a huge moloch. I can't wait for the next article in the series :)
ReplyDeleteI agree with most of your points, but I don't see a sane way out. I wrote an iPhone application for some friends and am very happy with it. I have been going crazy trying to convert it to an universal application. The interface that seems most natural to the end-user has a search bar, dynamic table and webview on the same screen (not to mention a custom button bar at the top). How do you let each of these components update the others? The architecture that Apple presents, ends up with a mess of cross messaging. Everything got hopelessly coupled. I'm very much looking forward to see how you clean up the ViewControllers.
ReplyDeleteBill, you should be able to do it without cross messaging if you implement proper MVC separation. In this case, the model is application state rather than traditional user data. The way I do it is with an ApplicationState singleton (you can make this a normal object that is pushed into all the view controllers if you are opposed to singletons on philosophical grounds). Usually you just need a bunch of state properties. Using KVO your view controllers can respond to changes in the app state without having to wire them all up as delegates of each other. This decouples the view controllers from each other and makes it trivial to add new ones. The other bonus is you can make your ApplicationState class save itself on any state change, and restore when the app restarts. Makes it a lot easier to remember user preferences and is much cleaner than just jamming everything into NSUserDefaults (although you could do that behind the scenes).
DeleteSo let's say I have button that changes the sort order of a tableview. All I have to do is something like [[ApplicationState sharedState] setSortMode:AppSortModeByAuthor] from the button view, and the tableview's controller which is observing sortMode gets the message via KVO. It can then re-sort its rows and reloadData.
@jsd I actually considered something along those lines a couple of times. I'm going to first try NSNotificationCenter. If the GUI response times are poor, then I will implement a singleton with global state and probably KVO. My data model is fairly well developed and only needed a few changes for the iPad. But I spent a lot of time trying to follow Apple's SplitView controller approach to migrating iPhone apps to the iPad - doesn't work for me. The good news is that I have something that works; just ugly dependencies everywhere and too many differences between the "controllers" for iPhone and iPad. Thanks for the useful suggestions.
DeleteInteresting, my feeling is that it is largely due to the delegation structure - the view controllers handle features by implementing other view controllers thus introducing more unrelated methods to the controllers. But then the models should be outside which will at least allow seperation of the data. But yes another layer for business logic sounds sensible
DeleteMore more more!
ReplyDeleteIt's so frustrating hearing from fellow iOS developers the phrase "I usually don't Unit Test my UIViewControllers, it's just too much effort" over and over again while them keeping 300+ lines of untested code in these classes. We need a way out of this mess!
Motivated by Uncle Bob Martin and his great book "Clean Code", I've increasingly looked into clean ways to decouple business logic and UIViewController business.
Some general rant from Bob Martin: http://blog.8thlight.com/uncle-bob/2011/11/22/Clean-Architecture.html
Ron Lisle attempts to do so with a thing he calls "VIP" architecture: http://iosunittesting.com/category/architectures/
@Mike Weller: You're looking for a job in London, you wrote. Incidentally I've read about a job offer in London today - no idea if there still is an open position, as the blog post was from March.
Source (at the bottom): http://www.merowing.info/2013/03/overlaying-application-version-on-top-of-your-icon/
iOS development is not a piece of cake! It requires a lot of creativity and new ideas. Many developers have tried their hands in development but there are only a few who have been successful in the field. ~keep posting~
ReplyDeleteEven Apple states that a view controller is not a pure controller as in MVC:
ReplyDelete"One can merge the MVC roles played by an object, making an object, for example, fulfill both the controller and view roles—in which case, it would be called a view controller. In the same way, you can also have model-controller objects. For some applications, combining roles like this is an acceptable design."
http://developer.apple.com/library/ios/#documentation/general/conceptual/CocoaEncyclopedia/Model-View-Controller/Model-View-Controller.html
Cocoa for OSX has bindings which allow to tie a model to a view and thus encourages better separation of the model from the controller.
ReplyDeleteSearching for an alternative in the iOS world, I came across BlocksKit. One of its categories, NSObject(BlockObservation), could potentially result in a much thinner controller which observes its model and notifies its view.
MVVM with ReactiveCocoa also looks delicious for separating concerns:
ReplyDeletehttp://cocoasamurai.blogspot.co.at/2013/03/basic-mvvm-with-reactivecocoa.html
At last I'm not the only one thinking that iOS architecture is a big mess which tends to be really difficult to maintain because even Apple does not show best practises to developpers :)
ReplyDeleteThanks for this great article !
Waiting for new posts!
ReplyDeletePLEASE hurry and write the next post.
ReplyDeleteSorry guys. I start a new job back in London in a month, so things are a little hectic at the moment. I will try and find the time to finish the next post in the coming weeks.
ReplyDeleteThis comment has been removed by the author.
ReplyDeleteYou're killing us! I got all the way to the end to find out the next post isn't ready yet :(
ReplyDeleteYou did an outstanding job expressing the flaws in the UIViewController madness that I'd always felt but couldn't properly articulate.
Great work.
Please tell me if you'll publish the next post about this problem?
ReplyDeleteGreat article. I am somewhat new to iOS so I wasn't sure if my apprehension about the "view controllers do everything" pattern was just a matter of me not fully drinking the Kool-Aid. Good to hear I'm not the only one looking for a better way. Looking forward to the follow-up article.
ReplyDeleteInteresting stuff! Please release the next post soon!
ReplyDeleteHey! Great article. I've been thinkin the same way for 2 years of my iOS developer practice. What about next part?
ReplyDeleteHere in my company, there're 2 (and more to come) exact cases,
ReplyDeletehijacked by a self-proclaimed iOS guru who happens to be a Senior Programmer,
so you can imagine my disappointment when I reached the end
and realized part 2 has yet to come.
Really anticipating the follow up!
Very nice post. Looking forward for the follow-up article.
ReplyDeleteThis post is a mind blow, please add some comment to briefly explain how to solve this. I think it would be very useful to many many developers out there.
ReplyDeleteThanks a lot, changes my way to implement VC.
ReplyDeleteWhere is the second part, we want it!
ReplyDeleteComing from the java world, I always thought there was a bit of a problem with this. Never thought it was great in terms of separation of concern. I'm just facing problem regarding the others who have been taught the "messy" way. I'm trying to be an evangelist but it's not an easy one. Carry on the good work.
ReplyDeleteLoved your post. But I too am anxious to see this explained more fully. However, I would certainly settle for a sample project using tables, data, business logic- simple, but with enough code to see how it's done. Do you have a sample project? Or could you whip one up fairly quickly as a show and tell? Would be pretty cool to see this in action.
ReplyDelete"So where should this navigation logic go? Well… somewhere else. We’ll get into that in a later post. All that matters for now is that the view controller should delegate UI actions like this to somebody at a higher level, who has access to and knowledge of the specifics of your app’s UI workflow."
ReplyDeletereally interested to see how achieve this
When is the next post due to come out? Really eager to gain some insight into the "right way"!
ReplyDeleteAfter six month, where is the next post?
ReplyDeleteI also would like to see a modest app done the right way.
ReplyDeleteI already knew shoving everything in a View Controller was wrong...
I would like to see a modest app done this way, too. However, I would say that it would have to have at least 3 different screens, and perhaps some network access as well. A tableview would be nice. Maybe something like the BrowseOverflow app done in Test Driven iOS Development.
DeleteToo many of these examples have only the one screen, and so they really fall flat on demonstrating that they're usable for more complex apps.
OK, sounds good. I totally agree. We're all awaiting the next post!
ReplyDeleteInteresting. I did a talk on the exact same subject here: https://speakerdeck.com/smorel/how-to-avoid-the-spaghetti-code-monster
ReplyDeleteI manage an open source framework that helps dealing with this kind of problems. you can have a look at it here: https://github.com/wherecloud/AppCoreKit
Found a similar article in german about the whole stuff... brought me to this post
ReplyDeletewww.ir-technology.net/blog/2014/01/uiviewcontroller-problem-ios-architektur
This comment has been removed by the author.
ReplyDeleteYou can't just leave us hanging, makes me wonder if you have any valid answers to your valid questions, or are just blowing off steam! Come on, next post or fess up that you have no answers!
ReplyDeleteim grateful for your ideas too and have often thought and discussed the same things. The way forward is clear tho people, you needn't be bugging the author for more material, what do you want him to write your projects too? Its simple, stop thinking UIViewController is the 'C' in 'MVC' and start thinking of it as the top of the food chain in the 'V' hierarchy.... And go write some 'C' classes!! (which I would say need to be fired off from -(BOOL)applicationFinishLaunchWithOptions...... i expect)
ReplyDeletewe have some world class mobile experts. if you wanna develop your iOS Apps, please visit http://www.taoteapps.com, By visiting the website you can develop your iOS Apps.
ReplyDeleteI think you see all these problems because most people (including you) have fundamentally misunderstood what MVC means in the Apple world. I recommend reading "MVC as a Compound Design Pattern" in the Apple documentation to clear up how Cocoa MVC is different from classical MVC.
ReplyDeleteThe clearest indication IMO that you have misunderstood the purpose of controllers is that you state:
"Controllers are supposed to be nice thin objects funnelling data and events between the model and the view. They shouldn’t contain details of a specific UI framework. iOS’ View controllers are nothing like this. They sit firmly in the presentation layer."
But this is wrong. Cocoa Controllers ARE supposed to know the details of a specific UI framework. In fact that is the whole point of a view controller. The philosophy of Cocoa is that you are supposed to be able to buy an UIView and a Model object from two different vendors who have nothing to do with each other. In other words model and view objects are supposed to be completely reusable. But somehow you need to make both of these classes who know nothing about each other talk to each other. You need some glue. This glue needs to know about both the model and and the view. This glue is the controller. The UIViewController is not a reusable component. The fact that you write so much about the inability to reuse UIViewController if you do this or that, indicates that you have missed this important part of Cocoa design philosophy. Controllers is where you dump all your non reusable, application specific code.
But this does not mean that you need to make every UIViewController a huge bloated mess. You should split it into multiple controllers. A controller can be made up of multiple controllers. Your business logic should be moved into model classes. If you got a table view create a specific controller just for implementing the DataSource protocol.
I think the real problem here is that a lot of people have only ever done iOS development and UIViewController is pretty nifty. But if you come from OS X Cocoa development you would be used to making controllers from scratch. Back in the day a controller was usually just a subclass of NSObject. Don't forget this is still valid to do. Not every controller needs to subclass some specific class like UIViewController.
I see your point with the horrible Apple example code though. That is a pitty. I never thought of example code as something to look at for the purpose of good application architecture. The Apple documentation does in fact give quite good explanations for how to structure your application. But nowadays it seems people learns almost exclusively by example. I am not sure what the solution to this is. If example applications showed good software design that would increase the size and complexity of the example and take focus away from the specific API being taught.
Perhaps Apple should have specific example programs just to show good Cocoa Software design.
Totally agree with you, controllers are the glue and should now about the model and the UI so that UI can be reusable and model is reusable.
DeleteThe business logic should not go into the controllers of course. Business logic only deals with the model layer and should be hosted in a service layer.
To sum up, the model contains the state, the service manipulates the model, and the controllers watch the model to propagate changes to the UI and listens to the UI to modify model state or call service methods.
Can not agree more. Using tranditional MVC you can still create good architecture. The point is making viewcontroller small and simple. Experienced developers know how to separate functions into different models which could be viewcontrollers or regular controllers.
DeleteWe have lived with VC the monster for years. Would love an alternative suggestion.
ReplyDeleteThis comment has been removed by the author.
ReplyDeleteThis comment has been removed by the author.
ReplyDeleteThis is great stuff, Mike. Growing up as a developer through Smalltalk, all of this is part of my DNA, but I, too, have succumbed to Apple's pressures and muddied my code by bloating ViewControllers (I hate VCs... and don't even get me started on ModelControllers...). Reading this has reminded me of my roots and inspired me to refactor my current project, and for that I thank you. Keep posting in this series, please!!
ReplyDeleteFor those advocating the virtues of VCs, while I agree that we need to constantly be evolving as developers and scientists, this experiment has proven more disastrous than advantageous, as evidenced by the proliferation of outright bad codebases written by so-called experience OO developers, and the number of apps that crash and fail for, apparently, no reason whatever.
MVC as a design archetype was created when things were much simpler (it was forged in the fire that gave us Smalltalk), admittedly, however, it has persisted for its simplicity, and most of the so-called enhancements or evolutions of it (MVVC, VCs, MCs, etc.) are nothing more (IMHO) than the hackings of folks who are not getting the essence and beauty of true MVC.
As a technology consultant who has interviewed over 800 technology applicants I can attest to the sparse few who could articulate the actual responsibilities of the constituents of the MVC pattern, and many of these folks had Master's degrees from prestigious universities. The teachings now are based on faulty thinking and shallow understanding of OO fundamentals, as they have become dilute over the generations of developers such that the collective thinking is flawed at its heart, yet is propagated as correct and accepted.
So, thank you Mike, for casting a harsh light on a dark shadow.
That's just my opinion... I could be wrong. ;)
** steps off soapbox ** and runs from tomato-hurlers...
DeleteWhere is the continuation post, did you get a chance to write it?
ReplyDeleteGreat article, much appreciated as I thought I was just being mad. One concise question for people out there - IBOutlets and IBActions: I can wire them in to my view or my controller (or both). Logic says they should be in the view but then one must implement a protocol/delegate to interact with the controller/model. This seems like a lot of effort for nothing much. Alternative is wiring all the IBOutlets/IBActions into the viewcontroller which seems a problem if you need different views for iPad/iPhone ... thoughts/opinions?
ReplyDeleteHey, this is a good article you wrote there. Since I am one of these devs (1 year exp.) I am looking forward to reading your articles about solving these problems. But when will you write them?
ReplyDeleteMike! I really wanted to read the rest of the series you decided to begin a year ago (but didn't). I can glean your intent from reading the post, but it would have been cool to see where it actually leads.
ReplyDeleteI'm guessing you'd replace all of the business logic common to View Controllers with bite size objects that can be unit tested? I have done this before when implementing UITableView Datasource protocols that started to get out of hand when everything was tossed into a single View Controller. Totally makes sense.
Anyway, please post more articles. I want to see your unique solution to the problem.
Thanks for this great article. I am very disappointed that you didn't make the next one with your solutions. I'd be glad to read it.
ReplyDeletePlease finish the series! I was nodding the whole way through your post. I'd love to see the next one. It's never to late to resurrect the series!
ReplyDeleteThe first issue of objc guides you on how to make your view controllers cleaner and lighter: http://www.objc.io/issue-1/
ReplyDeletePlease finish this series!!
ReplyDelete2015 is here, and we're still waiting. Please teach us the right way!
ReplyDeleteHey! Couldn't you at least post a few more pics of kittens?
ReplyDeleteMike, all we are looking forward for you to continue!
ReplyDeleteAre you alive?
What's the alternative? It's easy to criticism.
ReplyDeleteHere is the good solution
ReplyDeletehttp://www.teehanlax.com/blog/model-view-viewmodel-for-ios/
Nice post! Please keep working on new articles!
ReplyDeleteThis is awesome article. It made me actualize many past errors and i do still have some I'm working on to reduce. Definitely a wonderful article on why View Controller go beyond the point of frustration and you don't want to touch it again.
ReplyDeleteExcellent post by Mike on the problem with massive view controllers.
ReplyDeleteI've studied different iOS architectures such as MVC, MVVM, ReactiveCocoa, for the last two years. I found Uncle Bob's Clean Architecture the best way to decouple classes and make your dependency graph very simple. I've organized our code into 3 main components - view controller, interactor, and presenter, and abstract away model data by creating request, response, and view model objects to pass through their boundaries.
The result is amazing. With multiple developers on the project, we are able to know exactly which file and method to look when finding things. The other day, I had to fix a bug on a profile screen that was developed by another developer. I didn't write one line of this code but I know exactly where to find it. The methods are also very short as a result of apply Clean Architecture. I also added a router component to it and now we can use multiple storyboards with ease. This also allows us to write tests much easier as we only need to test methods at the boundaries.
I wrote about my experiences with Clean Architecture at http://clean-swift.com/clean-swift-ios-architecture/
This comment has been removed by a blog administrator.
ReplyDeleteThis is an excellent post. I am still holding out hope for a continuation. Thanks, hope you are doing well.
ReplyDeleteI would love a follow-up post! This was a great read.
ReplyDeleteThis comment has been removed by a blog administrator.
ReplyDeleteThis comment has been removed by a blog administrator.
ReplyDeleteThis comment has been removed by a blog administrator.
ReplyDeleteApple has made certain decisions with their framework design and tools which I believe contributes to this problem.click here
ReplyDelete
ReplyDeleteclash of clans mod apk
th11 war base
best th9 war base
sniper elite 4 download
Nier automata free download
ghost recon wildlands download
Though cool and hip, these cell phones are extremely sensitive. They have internal elements very delicate that a single drop might render the phone dead. So with this, having a cellular phone is synonymous to having cellphone cases.
ReplyDeleteHow to fix a dead phone
If you have your mind set on an iPhone app, then I urge you to also consider what happens when it is a success? Yes, I am assuming that your iPhone application will be a success because they are growing so rapidly.
ReplyDeleteMac Repair Bangor Maine
Established in 2013 to provide exciting, effective design solutions. Since its inception, Globalwebsolution has grown considerably into a recognised brand design and digital marketing innovator. Rewarding our clients with compelling visual solutions that create value and recognition in their marketplace.
ReplyDeletehe clients can exploit the component to flip between light foundation and dull foundation consistently. my review here
ReplyDeleteGood article knowledge gaining article. This post is really the best on this valuable topic. Mobile App Developers
ReplyDeleteExcellent website you have here: so much cool information!.. 24 hour truck tire repair
ReplyDeleteExcellent website you have here: so much cool information!.. cell phone deals
ReplyDeleteI think that thanks for the valuabe information and insights you have so provided here. TweakBox
ReplyDeleteI truly adored perusing your online journal. It was exceptionally all around wrote and simple to undertand. Not at all like extra online journals I have perused which are truly not tht great. I likewise discovered your posts extremely fascinating. Truth be told subsequent to understanding, I needed to go demonstrat to it to my companion and he ejoyed it also! AirShou Screen Recorder
ReplyDeletei am surprisingly here. I discovered this board and I in discovering It really accommodating and it helped me out a great deal. I would like to present something back and help other people, for example, you helped me. FtiOS iOS 11
ReplyDeleteThis was a really great contest and hopefully I can attend the next one. It was alot of fun and I really enjoyed myself..
ReplyDeleteIT managed Services Chicago
Great site, Distinguished criticism that I can handle. Im pushing ahead and may apply to my present place of employment as a pet sitter, which is exceptionally charming, yet I have to extra grow. Respects. Tinyumbrella Download
ReplyDeleteFabulous web journal! Do you have any tips and indications for trying authors? I'm wanting to begin my own particular site soon however I'm somewhat lost on everything. Would you propose beginning with a free stage like WordPress or go for a paid alternative? There are such a large number of alternatives out there that I'm totally overpowered .. Any proposals? Much obliged! Tutu Helper
ReplyDeleteGreat post yet I was thinking about whether you could compose a litte more on this subject? I'd be extremely grateful on the off chance that you could expound a smidgen further. Welcome it! Panda Helper
ReplyDeleteIt is really a great work and the way in which you are sharing the knowledge is excellent.Thanks for your informative article
ReplyDeletesoftware testing course in chennai
Thanks for the precious information. I m really grateful to you.
ReplyDeleteimessage on pc
Really thanks to you because valuable information. Track Easily throught blue dart courier tracking
ReplyDeleteGreat Article
ReplyDeleteAndroid Final Year Project Ideas for Computer Science
FInal Year Project Centers in Chennai
JavaScript Training in Chennai
Java Training in Chennai
Numerous mixture versatile apps today use Apache Cordova, a basic stage that comprises of an arrangement of JavaScript APIs for getting to cell phone capacities through modules that are worked with local code. clash royals
ReplyDeleteReally cool post, highly informative and professionally written and I am glad to be a visitor of this perfect blog, thank you for this rare info!
ReplyDeleteindustrial safety course in chennai
It's interesting that many of the bloggers to helped clarify a few things for me as well as giving. Most of ideas can be nice content. The people to give them a good shake to get your point and across the command.
ReplyDeleteoffshore safety course in chennai
Great Posting…
ReplyDeleteKeep doing it…
Thanks
Digital Marketing Certification Course in Chennai - Eminent Digital Academy
Thanks for sharing the details! thanks for sharing information,nice article.
ReplyDeletei would like to more information from your side!
please added more then tips!Am working in
Excel Training In Hyderabad
imessage online
ReplyDeleteemoji apps
best massage chair review
cpu benchmark software for windows
it asset management software
ReplyDeleteThe post you wrote which is full of informative content. I Like it very much. Keep on posting!!
ReplyDeleteAngularjs Training in Chennai
Angularjs course in Chennai
Big Data Training in Chennai
German Classes in Chennai
AngularJS Training in Porur
AngularJS Training in Velachery
AngularJS Training in Adyar
Excellent post, it will be definitely helpful for many people. Keep posting more like this.
ReplyDeleteRobotics Process Automation Training in Chennai
RPA Training in Chennai
Blue Prism Training in Chennai
Blue Prism Training Institute in Chennai
UiPath Training in Chennai
Data Science Course in Chennai
RPA Training in OMR
RPA Training in Porur
I am so glad today fortune turned to face me and not the booty as usual there were financial difficulties and I decided to play online casino stumbled upon this site reliable online casino list how good it was that I found it
ReplyDeleteWell written post with worthy information. It will definitely be helpful for all. Do post more like this
ReplyDeleteapple service center chennai
apple service center in chennai
apple mobile service centre in chennai
apple service center near me
Looking for iMovie? Download iMovie for Windows 10 Free
ReplyDeleteLooking for File Sharing Application? Here is the Best File Sharing Application of 2019 to Transfer Files from PC to Android/iPhone Mobile. Written by Meet Patel
ReplyDelete
ReplyDeleteTutuApp APK
TutuApp APK iOS
Tutu App
www.tutuapppro.com
Tutuapp Download
Panda Helper APK
Awesome post, I found this article very interesting check out my blog android app developers.
ReplyDeletehttps://themacsmack.com/parental-control-apps-for-ios/ nice one
ReplyDeleteThere is no doubt in the app you can easily download the app the most exciting features are waiting for you can easily go with Tutu App. There are nothing extra features required in this app because the most important items are already available in his update versions. Download Latest Version. Also love Snaptube For PC
ReplyDeletewho don't want to download a paid app for free? Well, in this post we are going to introduce such app that will allow you to download any app at free of cost. We are talking about Panda Helper APK for Android.
ReplyDeletePanda Helper VIP
Indonesia
ReplyDeleteEasy
Learning
Indonesian
Jual Beli HP
bimbelLampung
Service HP
lampungservice.com
Gamers
Emoji icons are cute little images that represents something in our daily lives. You could, for example substitute "I love you" with a simple emoji icon that represents a heart. It is commonly used and supported by most cell phones in Japan.
ReplyDeleteemoji
When I initially left a comment I appear to have clicked the -Notify me when new comments are added- checkbox and now each time a comment is added I receive four emails with the exact same comment. There has to be an easy method you can remove me from that service? Kudos! get it now
ReplyDeleteTutuapp
ReplyDeleteCervical Ayurvedic Treatment Delhi
ReplyDeleteGout Treatment In Delhi
Hair Fall Treatment Delhi
Ayurvedic Clinic for Chronical Diseases Delhi
Psoriasis Ayurvedic Treatment in Delhi
Slip Disc Treatment without Surgery in Delhi
Ayurvedic Treatment for Kidney Failure Delhi
Top Company to Develop website in PHP
ReplyDeleteBest Website Development Services
Website Redesign Services
Best Graphic Design Agency Rohini
Digital Marketing Company in North Delhi
Web Services
Best Web Development Institute Delhi
Nice blog...!!! Really so good post, I like your unique post and I gladly waiting for your new post...
ReplyDeleteExcel Training in Chennai
Excel Course in Chennai
Tableau Training in Chennai
Linux Training in Chennai
Oracle Training in Chennai
Spark Training in Chennai
Pega Training in Chennai
corporate training in chennai
Power BI Training in Chennai
Excel Training in T Nagar
Sharp
ReplyDeleteAdvan
Metro
Lampung
Panasonic
pulsa
lampung
Lampung
Lampung
Thank you for sharing some cool information regarding wordpress website design. Here I found one company in Brisbane area and it is very popular in Australia. They provide many service like seo birsbane, website design, digital marketing. Thank you!
ReplyDeleteIt was good explanation and it looks more impressive!thank you for sharing precious information with us..
ReplyDeleteIELTS Coaching in Chennai
IELTS Training in Chennai
French Classes in Chennai
pearson vue
Japanese Language Classes in Chennai
Best Spoken English Classes in Chennai
German Language Course in Chennai
IELTS Coaching in Velachery
IELTS Coaching in Tambaram
IELTS Coaching in Anna Nagar
This is an awesome post. Really very informative and creative contents.
ReplyDeleteios app Devlopment company in chennai
Aptoide PC
ReplyDeleteTweakbox for android
ReplyDeleteThank you for this informative blog
ReplyDeleteTop 5 Data science training in chennai
Data science training in chennai
Data science training in velachery
Data science training in OMR
Best Data science training in chennai
Data science training course content
Data science certification in chennai
Data science courses in chennai
Data science training institute in chennai
Data science online course
Data science with python training in chennai
Data science with R training in chennai
I am very happy to visit your blog. This is definitely helpful, eagerly waiting for more updates.
ReplyDeleteccna course in Chennai
ccna Training in Chennai
ccna Training institute in Chennai
AngularJS Training in Chennai
Ethical Hacking course in Chennai
PHP Training in Chennai
ccna Training in Tambaram
ccna Training in Velachery
CCNA course in Anna Nagar
If you are intrested in the thai lottery result tips and updates and thai lottery result get it from the Link
ReplyDeleteGreat blog thanks for sharing Looking for the best creative agency to fuel new brand ideas? Adhuntt Media is not just a digital marketing company in chennai. We specialize in revamping your brand identity to drive in best traffic that converts.
ReplyDeleteNice blog thanks for sharing Is this a special day for you? Beautiful and fragrant flowers are sure to make it even more amazing of a day no doubt. This is why Karuna Nursery Gardens offers you the best rental plants in Chennai that too at drop dead prices.
ReplyDeleteExcellent blog thanks for sharing Run your salon business successfully by tying up with the best beauty shop in Chennai - The Pixies Beauty Shop. With tons of prestigious brands to choose from, and amazing offers we’ll have you amazed.
ReplyDeleteSoma pill is very effective as a painkiller that helps us to get effective relief from pain. This cannot cure pain. Yet when it is taken with proper rest, it can offer you effective relief from pain.
ReplyDeleteThis painkiller can offer you relief from any kind of pain. But Soma 350 mg is best in treating acute pain. Acute pain is a type of short-term pain which is sharp in nature. Buy Soma 350 mg online to get relief from your acute pain.
https://globalonlinepills.com/product/soma-350-mg/
Buy Soma 350 mg
Soma Pill
Buy Soma 350 mg online
Buy Soma 350 mg online
Soma Pill
Buy Soma 350 mg
Best information
ReplyDeleteairtel recharge list
Really nice post. Thank you for sharing amazing information.
ReplyDeletePython training in Chennai/Python training in OMR/Python training in Velachery/Python certification training in Chennai/Python training fees in Chennai/Python training with placement in Chennai/Python training in Chennai with Placement/Python course in Chennai/Python Certification course in Chennai/Python online training in Chennai/Python training in Chennai Quora/Best Python Training in Chennai/Best Python training in OMR/Best Python training in Velachery/Best Python course in Chennai
Really nice post. Thank you for sharing amazing information.
ReplyDeleteJava Training in Credo Systemz/Java Training in Chennai Credo Systemz/Java Training in Chennai/Java Training in Chennai with Placements/Java Training in Velachery/Java Training in OMR/Java Training Institute in Chennai/Java Training Center in Chennai/Java Training in Chennai fees/Best Java Training in Chennai/Best Java Training in Chennai with Placements/Best Java Training Institute in Chennai/Best Java Training Institute near me/Best Java Training in Velachery/Best Java Training in OMR/Best Java Training in India/Best Online Java Training in India/Best Java Training with Placement in Chennai
If you're an employer and you want to keep an eye on your new employees and their activities on the Internet, this page will be perfect for you - spy-apps-software.com Top lists of the best spy apps!
ReplyDeleteTutuApp is a trending app nowadays because it contains many new and good features of games, music, etc. Tutuapp APK
ReplyDeleteTutuApp APK
Tutu App
Tutu App APK
TutuApp Free
TutuApp ios
A IEEE project is an interrelated arrangement of exercises, having a positive beginning and end point and bringing about an interesting result in Engineering Colleges for a particular asset assignment working under a triple limitation - time, cost and execution. Final Year Project Domains for CSE In Engineering Colleges, final year IEEE Project Management requires the utilization of abilities and information to arrange, plan, plan, direct, control, screen, and assess a final year project for cse. The utilization of Project Management to accomplish authoritative objectives has expanded quickly and many engineering colleges have reacted with final year IEEE projects Project Centers in Chennai for CSE to help students in learning these remarkable abilities.
ReplyDeleteSpring Framework has already made serious inroads as an integrated technology stack for building user-facing applications. Spring Framework Corporate TRaining the authors explore the idea of using Java in Big Data platforms.
Specifically, Spring Framework provides various tasks are geared around preparing data for further analysis and visualization. Spring Training in Chennai
ReplyDeleteTutu Helper is the one of the best ios,android App store to get the tons of free app and game. Here the latest version of TutuApp of free.
Tutu Helper
Tutu App
TutuApp is a trending app nowadays because it contains many new and good features of games, music, etc. TutuApp APK
ReplyDeleteTutu App
Thanks for sharing valuable information.
ReplyDeleteDigital Marketing training Course in Chennai
digital marketing training institute in Chennai
digital marketing training in Chennai
digital marketing course in Chennai
digital marketing course training in omr
digital marketing certification in omr
digital marketing course training in velachery
digital marketing training center in Chennai
digital marketing courses with placement in Chennai
digital marketing certification in Chennai
digital marketing institute in Chennai
digital marketing certification course in Chennai
digital marketing course training in Chennai
Digital Marketing course in Chennai with placement
digital marketing courses in Chennai
ReplyDeleteShowbox Apk is a meta-search engine scraper that scrapes data from the world wide web and provides you with the best for your movies and TV shows.
It works directly as well as p2p i.e peer to peer.
if you are looking for free movies and tv shows you can find them on showbox app its easy to download and install
you can stream movies and tv shows on tvtap for free its great app for all types of live stream
if you wanna watch free movies and tv shows you can tune in to beetv app for free
whatsapp status
RedBox TV App has introduced a lot more features than any other TV Channels Streaming App. It does have categories, depending on Counties as well.
To find out your native language you can swipe to Country based categories, where you’ll find the channels which are highly native to your region and language. That’s an extra of RedBox TV App.
Apart from this, RedBox is available for almost every possible platform. Unlike the other apps, Redbox tv don’t claims any fake hoax, all the stuff where are features in this post will be served.
great post as always! https://naukry.net/ppsc-jobs/
ReplyDeleteAwesome blog thankks for sharing 100% virgin Remy Hair Extension in USA, importing from India. Premium and original human hair without joints and bondings. Available in Wigs, Frontal, Wavy, Closure, Bundle, Curly, straight and customized color hairstyles Extensions.
ReplyDeleteVery useful blog thanks for sharing IndPac India the German technology Packaging and sealing machines in India is the leading manufacturer and exporter of Packing Machines in India.
ReplyDeletebest php training in chennai
ReplyDeletebest php developer institution chennai
best php training with placement in chennai
best php training center in chennai
best php course in chennai
Good job! Fruitful article. I like this very much. It is very useful for my research. It shows your interest in this topic very well. I hope you will post some more information about the software. Please keep sharing!!
ReplyDeleteSEO Training in Chennai
SEO Training in Bangalore
SEO Training in Coimbatore
SEO Training in Madurai
SEO Course in Chennai
SEO Course in Chennai
SEO Course in Bangalore
SEO Course in Coimbatore
Nice information, valuable and excellent design, as share good stuff with good ideas and concepts, lots of great information and inspiration, both of which I need, thanks to offer such a helpful information here.
ReplyDeletedigital marketing course in chennai
digital marketing training in chennai
seo training in chennai
online digital marketing training
best marketing books
best marketing books for beginners
best marketing books for entrepreneurs
best marketing books in india
digital marketing course fees
high pr social bookmarking sites
high pr directory submission sites
best seo service in chennai
I feel very grateful that I read this. It is very helpful and very informative and I really learned a lot from it.
ReplyDeletebusiness analytics course
data science interview questions
Thanks for sharing valuable information.
ReplyDeleteDigital Marketing training Course in Chennai
digital marketing training institute in Chennai
digital marketing training in Chennai
digital marketing course in Chennai
digital marketing course training in omr
digital marketing certification in omr
digital marketing course training in velachery
digital marketing training center in Chennai
digital marketing courses with placement in Chennai
digital marketing certification in Chennai
digital marketing institute in Chennai
digital marketing certification course in Chennai
digital marketing course training in Chennai
Digital Marketing course in Chennai with placement
I finally found great post here.I will get back here. I just added your blog to my bookmark sites. thanks.Quality posts is the crucial to invite the visitors to visit the web page, that's what this web page is providing.
ReplyDeletedata science course Mumbai
data science interview questions
data analytics course in mumbai
I wanted to thank you for this excellent read!! I absolutely loved every little bit of it. I have got you book marked to look at new stuff you post…
ReplyDeleteTech geek
I got some clear information from this blog.. Thanks for taking a time to share this blog...
ReplyDeleteAWS Training in Chennai
AWS Training in Bangalore
Best AWS Training in Bangalore
AWS Training Institutes in Bangalore
AWS Certification Training in Bangalore
Data Science Courses in Bangalore
DevOps Training in Bangalore
DOT NET Training in Bangalore
AWS Training in BTM
Best AWS Training in Marathahalli
Poker online situs terbaik yang kini dapat dimainkan seperti Bandar Poker yang menyediakan beberapa situs lainnya seperti http://62.171.128.49/hondaqq/ , kemudian http://62.171.128.49/gesitqq/, http://62.171.128.49/gelangqq/, dan http://62.171.128.49/seniqq. yang paling akhir yaitu http://62.171.128.49/pokerwalet/. Jangan lupa mendaftar di panenqq
ReplyDeleteshopeetoto
ReplyDeleteshopeetoto
shopeetoto
shopeetoto
shopeetoto
shopeetoto
shopeetoto
shopeetoto
This is a wonderful article, Given so much info in it, Thanks for sharing. CodeGnan offers courses in new technologies and makes sure students understand the flow of work from each and every perspective in a Real-Time environmen python training in vijayawada. , data scince training in vijayawada . , java training in vijayawada. ,
ReplyDeletehttp://62.171.145.61/anugerahtoto/
ReplyDeleteTogel Online
Poker Online
bandarq
Bandar Kometqq
capsa online
agen online qq
agen poker
pelangiqq
ReplyDeletepelangiqq
pelangiqq
pelangiqq
pelangiqq
pelangiqq
pelangiqq
pelangiqq
Allinfodesk: Jobs in Pakistran 2020 Latest Vacancies
ReplyDeletehttps://allinfodesk.com/category/jobs-in-pakistan/
Jobs in Pakistan
https://allinfodesk.com/category/jobs-in-pakistan/
Impressive! I finally found great post here. Nice article on data science . It's really a nice experience to read your post. Thanks for sharing your innovative ideas to our vision.
ReplyDeleteData Science Course Training in Bangalore
ReplyDeleteThank you for taking the time to provide us with your valuable information. We strive to provide our candidates with excellent care
http://chennaitraining.in/creo-training-in-chennai/
http://chennaitraining.in/building-estimation-and-costing-training-in-chennai/
http://chennaitraining.in/machine-learning-training-in-chennai/
http://chennaitraining.in/data-science-training-in-chennai/
http://chennaitraining.in/rpa-training-in-chennai/
http://chennaitraining.in/blueprism-training-in-chennai/
Great blog !It is best institute.Top Training institute In chennai
ReplyDeletehttp://chennaitraining.in/openspan-training-in-chennai/
http://chennaitraining.in/uipath-training-in-chennai/
http://chennaitraining.in/automation-anywhere-training-in-chennai/
http://chennaitraining.in/microsoft-azure-training-in-chennai/
http://chennaitraining.in/workday-training-in-chennai/
http://chennaitraining.in/vmware-training-in-chennai/
You made some decent points there. I looked on the internet to learn more about the issue and found most individuals will go along with your reviews views on this website.
ReplyDeleteExcellent web site you have got here.. It’s hard to find excellent writing like yours nowadays.lap I truly appreciate people like you! Take care!!
ReplyDeletehttps://togelhoky1.blogspot.com/
ReplyDeletehttps://togelresmi8.blogspot.com/
https://togelsgphk8.blogspot.com/
https://situstogelkita.blogspot.com/
https://togelonlinejudi.blogspot.com/
https://togel2020wap.blogspot.com/
Thanks for your unique post and Keep doing...
ReplyDeleteOracle Training in Chennai
best oracle training institute in chennai
Corporate Training in Chennai
Embedded System Course Chennai
Unix Training in Chennai
Graphic Design Courses in Chennai
Pega Training in Chennai
Spark Training in Chennai
Excel Training in Chennai
Soft Skills Training in Chennai
JMeter Training in Chennai
Oracle Training in Anna Nagar
ReplyDeleteTeaTv Apk Is Another One Of The Best Online Streaming Application For Smartphone Users. This Application Is Available For Android & IOS Users. Also, You Can Connect This Application Easily With Amazon Firestick, Android Smart TVs, Start Settop Box, Etc. There are more apk to online streaming is Mediabox apk for smartphone users ( Android and ios ) and
Best Wishes Quotes
Watch Free online Movies
onhax
onhax android
Hulu Apk
I have to search sites with relevant information on given topic and provide them to teacher our opinion and the article.
ReplyDeletebusiness analytics courses
keep up the good work. this is an Ossam post. This is to helpful, i have read here all post. i am impressed. thank you. this is our courses in data analytics
ReplyDeletecourses in data analytics | https://www.excelr.com/data-analytics-certification-training-course-in-mumbai
I have scrutinized your blog its engaging and imperative. I like your blog.
ReplyDeletecustom application development services
Software development company
software application development company
offshore software development company
custom software development company
Appriciable article, We at Property Hunters shifted this service to a level much higher than the broker concept. you can see more details like this article Good location in pearl qatar
ReplyDeleteThank you so much for sharing this nice informations.
ReplyDeleteandroid training institutes in coimbatore
data science course in coimbatore
data science training in coimbatore
python course in coimbatore
python training institute in coimbatore
Software Testing Course in Coimbatore
CCNA Course in Coimbatore
wonderful article. Very interesting to read this article.I would like to thank you for the efforts you had made for writing this awesome article. This article resolved my all queries. keep it up.
ReplyDeletedata analytics course in Bangalore
Excellent Blog. Thank you so much for sharing.
ReplyDeletesalesforce training in chennai
salesforce training in omr
salesforce training in velachery
salesforce training and placement in chennai
salesforce course fee in chennai
salesforce course in chennai
salesforce certification in chennai
salesforce training institutes in chennai
salesforce training center in chennai
salesforce course in omr
salesforce course in velachery
best salesforce training institute in chennai
best salesforce training in chennai
The thought on iOS app architecture and Test Driven Development has been a great concept to discuss. The ideas has been articulated with professional skills and efforts. I wish you further success in the next jot down.
ReplyDeleteWeb Designing Course Training in Chennai | Web Designing Course Training in annanagar | Web Designing Course Training in omr | Web Designing Course Training in porur | Web Designing Course Training in tambaram | Web Designing Course Training in velachery
I have honestly never read such overwhelmingly good content like this. I agree with your points and your ideas. This info is really great. Thanks.
ReplyDeleteSAP training in Kolkata
Best SAP training in Kolkata
SAP training institute in Kolkata
I'm not one of those readers that comments on articles often, but yours really compelled me. There's a lot of interesting content in this article that is interesting and bold.
ReplyDeleteSAP training in Mumbai
Best SAP training in Mumbai
SAP training institute Mumbai
Learn Adobe Analytics from Experts
ReplyDeleteAdobe Analytics Trainings
I feel very grateful that I read this. It is very helpful and very informative and I really learned a lot from it.
ReplyDeleteCorrelation vs Covariance
It's so great to know you are a writer that cares about the information you provide. This is smartly done and well-written in my opinion.
ReplyDeleteSAP training in Kolkata
SAP training Kolkata
Best SAP training in Kolkata
SAP course in Kolkata
SAP training institute Kolkata
I have express a few of the articles on your website now, and I really like your style of blogging. I added it to my favorite’s blog site list and will be checking back soon…keep it up
ReplyDeleteAi & Artificial Intelligence Course in Chennai
PHP Training in Chennai
Ethical Hacking Course in Chennai Blue Prism Training in Chennai
UiPath Training in Chennai
Very interesting to read this article.I would like to thank you for the efforts you had made for writing this awesome article. This article inspired me to read more. keep it up.
ReplyDeleteCorrelation vs Covariance
Simple linear regression
Awesome blog. I enjoyed reading your articles. You can install all paid games for free with tutuapp
ReplyDeletetutuapp download
Gilotyna
ReplyDeleteLutownica transformatorowa
Adwokat Łódź
Gilotyna
Taxi Zgierz
Mediator Łódź
After reading your article I was amazed. I know that you explain it very well. And I hope that other readers will also experience how I feel after reading your article.
ReplyDeleteData Analyst Course
Great Article… I love to read your articles because your writing style is too good, its is very very helpful for all of us and I never get bored while reading your article because, they are becomes a more and more interesting from the starting lines until the end.
ReplyDeleteRobotic Process Automation (RPA) Training in Chennai | Robotic Process Automation (RPA) Training in anna nagar | Robotic Process Automation (RPA) Training in omr | Robotic Process Automation (RPA) Training in porur | Robotic Process Automation (RPA) Training in tambaram | Robotic Process Automation (RPA) Training in velachery
Neither a transistor nor an artificial neuron could manage itself; but an actual neuron can. artificial intelligence training in hyderabad
ReplyDelete
ReplyDeleteThanks For sharing such a useful and informative stuff
workday studio training
workday studio online training
workday course
workday studio online training india
workday studio online training hyderabad
workday studio training india
This is my first visit to your blog! We are a team of volunteers and new
ReplyDeleteinitiatives in the same niche. Blog gave us useful information to work. You
have done an amazing job!
artificial intelligence training in Bangalore
Thanks for sharing great information!!
ReplyDeleteData Science Training in Hyderabad
To establish a network by putting towers in a region we can use the clustering technique to find those tower locations which will ensure that all the users receive optimum signal strength.
ReplyDeletedata science training bangalore
wonderful one. I would like to thank you for the efforts you had made for writing this awesome article. This article inspired me to read more. keep it up.
ReplyDeleteCorrelation vs Covariance
Simple linear regression
data science interview questions
I like viewing web sites which comprehend the price of delivering the excellent useful resource free of charge. I truly adored reading your posting. Thank you!
ReplyDeletedata science interview questions
Thanks for sharing helpful information. Data science course in Pune
ReplyDeleteAwesome blog. I enjoyed reading your articles. You can install all paid games for free with tutuapp
ReplyDeletetutuapp download
https://greetingly.tumblr.com/post/622354268926656512/keep-in-touch-with-your-star-through
ReplyDeletegreat information about ios development.....
ReplyDeleteacte velachery reviews
acte tambaram reviews
acte anna nagar reviews
acte porur reviews
acte omr reviews
acte chennai reviews
acte student reviews
Download panda helper on iOS and Android APK
ReplyDeleteDownload and install panda helper on Android and iOS devices
ReplyDeleteThis Was An Amazing ! I Haven't Seen This Type of Blog Ever ! Thankyou For Sharing, data sciecne course in hyderabad
ReplyDeleteAttend online training from one of the best training institute Data Science Course in Hyderabad
ReplyDeleteYou have shared a nice article here. After reading your article I got very much information and It resolved many of my doubts. Thanks for sharing this article here.
ReplyDeleteIELTS Coaching in chennai
German Classes in Chennai
GRE Coaching Classes in Chennai
TOEFL Coaching in Chennai
spoken english classes in chennai | Communication training