Thursday, April 24, 2014

Switching to Storyboards on iOS

I came across this tweet today and had some thoughts on it from my experience:

Like many iOS devs, I inherited a project built by others who, shall we say, were new to iOS. They combined the networking, data object serialization, and views into the View Controllers. It was a mess that was hard/impossible to unit test and hard to extend.

I had to come up with a better way to let us extend the app with future features, to refactor the UI without breaking backend processing, and let us support more than just a single iPhone size (there was no iPhone 5 support and no iPad support). One of my first candidates for fixing this was to refactor the UI. But to do that I had to decrease the muddy layers in the app's View Controllers since they were littered with the Model the View and the Controller code.

After much effort to move the Model into a backend library for processing networking and data object serialization, I now just had the views to pull out of the view controllers. Here is where I started with Storyboards.

We had a lot of custom code in the views that was drawing for just one iOS platform size. This custom code also used a lot of magic numbers to handle placement, sizing, etc. Being all in code we also had to rerun the app every change to see how layout was impacted. This was a pain.

I decided to replace the hand written code with Storyboards. For a couple reasons:

  • We'd be able to see the design without running the app.
  • We could mock up and show new layouts for new views faster for Product Owners.
  • We could layout a Storyboard for the iPhone and one for the iPad and then launch with the one for the platform we were running on.
  • We could get rid of more view code. Back to this one later.
The refactor was a success. We split out our Model code which was a big win and we started writing unit tests for the Model code that was impossible before due to the tight coupling of Model-View-Controller.

The Storyboards refactor was a success in the following sense:
  • We could see the app layout making it easier for new devs to see the design.
  • We could make additions to the views and show them to Product Owners for faster feedback.
  • We took advantage of Segues to make the flow of the app easier to understand.
  • We got rid of hand-written views that had a lot of magic which just broke on other form factors.
Our biggest problems with Storyboards were:
  • Merge hell. The XML backing the Storyboards just would not happily merge if two devs went into the Storyboard.
  • Xcode hell. Xcode would make changes, wide sweeping changes when you opened a Storyboard. This make some bad single dev merge pop-up and we had to roll-back to reapply changes.
    • Ok, what do you mean wide sweeping? Xcode would change GUIDs across the Storyboard or our favorite, add/remove whole sections of references in the XML.
    • We had a working rule. If you open the Storyboard by mistake or to take a look, you reverted the changes Xcode made.
    • When you changed something for real, you had the other dev check your changes once you were ready to commit since Xcode seemed to miss some changes.
    • When Xcode missed changes you would delete the Storyboard files, pull them from the repo again, and apply your changes again.
  • It did not always save time due to the merge and Xcode hells.
  • A lot of knowledge is in the Storyboards and new devs need to know how Storyboards interact with the code. But then the previous hand-written code was no better for new devs to iOS. So I think this is not a large problem since iOS devs should be expected to know how to use Storyboards I think.

Now, with hindsight, on a large team I am unsure how I would deal with storyboards. I have heard Xcode is getting better for merging but the merging hell people talk about was encountered on a team of 2. We had to limit any work in the storyboard to only one person at a time. For a fairly simple app this was ok and being a team of 2 also easy to manage. For a larger team with view broken up across team members this could be a pile of hurt.

Personally I think the advantages of Storyboards outweigh the growing pains. I am intrigued by comments that Microsoft went this way and then reverted some of it and moved a lot of the UI back into code.

Is Apple repeating the same mistakes with Xcode as Microsoft learned with Visual Studio? That UI design tools are hard?


Grant McSheffrey said...

As storyboards grow the merging becomes completely hellish and Xcode has serious trouble with performance too. We let our main storyboard grow out of control and now nobody wants to touch it.

If the main concern is using Xcode's visual design tools then individual XIB files give you that while maintaining some much needed modularity.

Mark Thistle said...

One problem I found with Xcode was that it made merges hell since it would just change the Storyboard without a perceptible change by the user. This would make times when you really did change something near impossible to decipher if there was a merge conflict.

We were only able to manage our storyboard by locking it down to one dev at a time could make changes. Others had to wait, pull the new changes, and then add their changes on top.

It is a definite bottleneck in the development process but what we went with.

I can see XIBs being better in that sense. At the loss of segues and unwind segues. I think there is a great value in the segue and the unwind segue and for non-large layouts I would use Storyboards again.