What Can RIV Do For You?
Rapture In Venice, LLC, has been building mobile apps for over 10 years! Working directly with our clients, and through other firms, we’ve built the full gamut of apps from fitness trackers, to visual measurement tools, to auto insurance.
We’re ready to build a solution for you! Contact us to find out what we can do for you.
Need to augment your mobile team with developers? We can do that, too.
SwiftUI is the Future: A Poem
SwiftUI is the future
Of this I can be sure
It’s slicker than writing UIKit
Its intentions nothing but pure
Yet still SwiftUI pains me
How do I do this? Do that?
SwiftUI can be so fantastic
And other times falls so flat
SwiftUI is the future
It’ll be here when I’m long gone
SwiftUI is the future
But right now my layout is all wrong
Going Full-Time
If I’ve been quiet for quite a long time it’s because I’ve been busy, busy, busy…but what’s changed even more is that I am now a full-time employee with Aetna working on their Design Systems team.
I had spent 8 years as a full-time freelance consultant absolutely dedicated to mobile development. Eight AMAZING years! That was such an adventure and I learned and grew so much from it. You can work at a company for your entire life, but being on your own, generating your own business, maintaining relationships with your customers all by yourself (maybe without much business acumen, cough cough…), that’s an entire skill altogether.
When I started consulting full time I had the luxury of having done side work for years before that. I had a handful of clients I’d already worked with, some more successfully than others, and I was able to take those lessons right into my own business starting with a long-term contract as a jumping off point.
And now, for the last 14 months, I haven’t needed to do that. It’s strange. I still do side work, but at my main work I’m just a developer. Developer #48194732. A guy in the corner. Writing code. I barely know or interact with our stakeholders and our customers are ultimately people who use Aetna health insurance.
That’s a loooooot of customers.
Do I miss it?
I do.
There are still a lot of perks to being an FTE, though. For instance, this week I am starting an 11-day Christmas vacation. I cannot remember the last time I was able to do that, but I do know taking 7 business days off in a row before was stressful. Unpaid. No backup. Always taking my laptop with me on road trips. Often starting the clock on an hour of work here or there…never fully disconnected.
Did I mention how much I love PTO?!
Health insurance is another nicety. You see, I wasn’t able to even launch Rapture In Venice until the Affordable Care Act was passed and started mostly going into effect in 2010. My wife and newborn son were not eligible for private insurance…a travesty if you ask me…but once my son’s pre-existing conditions were immediately covered by the ACA is when I could seriously launch on my own LLC.
So why did you stop?
I’ll be honest, I didn’t stop consulting work voluntarily. Over the last couple years prior to hiring on at Aetna, I was having a lot of trouble finding good work. The first signs of trouble came at the end of Fall 2017. It was when my client pipeline wasn’t just running thin…it was completely empty.
My project workload had been ending and I was unable to generate new leads. It had really been the first time in nearly 7 years that happened. Not only was there no work, the holidays were fast approaching, one of the hardest times of year to find anything. Managers are planning vacations and budgets and nobody’s interested in interviews or ramping up someone new. Like a squirrel, I hoard acorns as winter approaches, but my tree trunk was empty now and at the worst time!
Miraculously, a cold lead came in and within 2 days I had interviewed and signed paperwork to join a 3-month effort to finish out an app. Literally, the message I had gotten was “My client is desperate for iOS devs, I can have you signed up this week, what’s your rate?”
It was great work, too…I was hired along with 6 other consultants to work on a pair of apps together. In all those 8 years, it’s the most team-centric environment I had been in, but as the contract began to wind down I faced a familiar problem…once again, I had no leads.
What was I going to do next? How did I end up here…again?!
I’ll always remember what happened next, too. That team of 6 consultants was whittling away. The guy who sat next to me saw his contract end and he was gone. Then another…and another…until finally I was the last contractor left. It was like Survivor! Their resource needs were lessening, their budget was tightening, and they were choosing who would stay and who would go.
And I was the last one left on the island.
Each week they’d ask if I could stay one more week and I would. I never told them, “Well, ya see, the funny thing is that I don’t have anywhere else to go!” Every week I thought I was up a creek without a paddle and then I’d get to come home to my wife and say, “They extended me again!”
I didn’t know when I would find work, but I knew I’d have one less week of no income at the very least.
And on that last week, when I was all but sure there’d be no more extensions…and there were no more extensions…I found work! Once again, it happened fast, from contact to signed papers in 3 days, and it was perfect! Work from home, good rate, and fun stuff.
And the conga line moved a little bit further.
I had acquired new work less than 24 hours before being completely screwed.
Did it get better after that?
Nope.
Finding work continued to be a struggle. In the next year or so, panic became a recurring theme. I rarely had my next gig lined up. Fortunately, one of my favorite projects occurred in this timeframe, but yeah, I knew the end was coming. I’ve never been a business expert…I’m a coder…but the consulting market had become more difficult to navigate and I had seen plenty of consulting friends go full-time. More companies hiring than contracting. Less entrepreneurs hell bent on making a fortune on the App Store…a dream that was dying, if not completely dead already.
It ended in the summer of 2019
That summer, again at the end of my chain, I desperately reached out to an interesting contact of mine. He was a Manager at Schwab, a person that I had been in contact with a year earlier at that week-to-week gig. While the potential of interviewing with them loomed, that’s when I had finally found my next contract, but here we were again…coming off my favorite project but nothing to do.
And then it turned out that a former iOS developer and co-worker actually ran the team there and I was in. And consulting, too, not an employee. The streak was still alive! I worked at Schwab for 5 months and, while the work was one of my least favorite parts of that job, I loved the team. And it’s a good thing, because I knew it was likely to be my last contract.
As my long commutes to the DTC wore on along with the fundamental truth that I didn’t want to work there long term (a transition to FTE was likely going to be broached any day), the question became: what could possibly be next?
That’s when a friend recommended me for a job at Aetna. A full-time job. Over the next month, between interviews and salary negotiation and many panic attacks (a story for another day that will be a hard one to tell), I transitioned to my new normal.
An employee again.
Wow.
Going forward in the new normal…
Oh, don’t be so dramatic, I’m as busy as ever with Rapture In Venice! I have three clients right now and I can see going back to full-time consulting in the future as a possibility…albeit only if I’m confident in it again. For right now, I am also very happy being an employee. A tiny little cog in a huge company. In my role, I feel like I have a lot of responsibility and many days feel more stressful and urgent than as a consultant, honestly!
But I don’t have to stress about finding work all the time. It’s here and waiting for me.
And with paid holidays and PTO. :-)
Here’s Why: View Navigation Sucks in iOS
The “Here’s Why” series attempts to explain the what’s and why’s of basic iOS concepts and topics. What does this mean? Why is it this way? I’ll attempt to keep the focus on the theory rather than the minutiae of the code so we can learn the fundamentals of the issue to help in future understanding.
In the last few years, a new design pattern has emerged in the iOS space called the Coordinator. The Coordinator pattern is one that aims to remove all app navigation logic (push, present, pop, dismiss, etc.) from the View Controllers and handle it externally, from the outside. It’s separation of concerns as it should be.
But what’s really wrong with doing it in the View Controller?
Before I discovered the Coordinator pattern, I knew something was wrong with how we do navigation. Let’s start simple before we get into the problem areas.
Example #1: Simple Master-Detail (Acceptable)
Let’s say we have a UITableView of video games where, if we tap any one of them, a detailed view of that game is pushed into our navigation controller. The user interacts with that screen and then dismisses it by tapping the back button. When the user taps, we instantiate the detail view and then call navigationController?.push on it. This pushes the screen forward. We return to the list when the user taps the back button in the navigation bar.
This usage is fine. The detail view contains no dismissal logic since it never calls navigationController?.popViewController to dismiss itself. In this way, the detail view has no knowledge of how it’s presented.
Good to go.
Example #2: Not-So-Simple Master-Detail (Questionable)
Now let’s take that same Master-Detail example but, this time, the detail view lets you edit information and has two buttons, “Save” and “Cancel”. This seems similar, but now we’ve introduced a problem: the detail view needs to dismiss itself when one of these buttons are pressed.
We can do this in one of several ways, but here are the primary options:
- We call a delegate or closure on tap.
- We perform an exit segue on tap.
- We call navigationController?.popViewController on tap.
If we use the first method, we’re good to go. In this case, the detail view need not have any knowledge of how it was presented. What I mean here is that the list view presents the detail but the detail view need not care how it’s presented because it isn’t dismissing itself directly. The delegate is defined by the calling code and can decide how to dismiss the view on its own.
Awesome.
Using exit segues isn’t as hot an idea. While the dismissal code is abstracted out of the detail view, it relies on any view that presents it to provide an exit segue route somewhere in the hierarchy. You’ll get this right the first time you use this view in your storyboard, but later on someone who reuses this detail view in a different place will be surprised when they click “Cancel” and nothing happens, for example. The exit segue logic is always a hidden implementation detail which is why I’ve never cared for it. This is why I would prefer adding an onCancel closure so that I can easily check for it (type on<Escape> to see my options) and provide my own logic.
The third option, putting the dismissal code right in the detail view, is the worst idea. Sadly, this is extremely common to see as well. I ran into this problem on an app a while back when dismissals weren’t working because the specific view I was reusing was originally being presented by a UINavigationController but now I was using it as a modal. Calling popViewController directly in the view controller wasn’t dismissing it at all!
You never notice the error in doing things this way until you’re building an app that reuses view controllers a lot, but once I ran into this problem I vowed never to include self-dismissal logic in my view controllers again. When a view was presented, it would always have a closure such as onCancel or onSave that the presenting view controller should implement to handle it. If you tapped a “Cancel” button in my view controller, it would simply call onCancel?() and that’s all.
But even that wasn’t foolproof…
Example #3: Nesting View Controllers (Insanity)
On the most recent app I worked on, I had some complex view navigation logic that threw me into the fires of hell. The hierarchy looked like this:
A -> B -> C -> D
Here, A is on a UINavigationController that pushes B which presents C modally which presents D modally. The trick here is sometimes C needs to reset its data and sometimes it should go away. Also, sometimes B needed to be able to dismiss C or D. Not to get too deep into the weeds, each view controller only knew about its presented view controller and so the logic got hairy fast. I could call closures back one level at a time, but the logic became increasingly opaque and when the wrong thing happened it was hard to trace the logic from beginning to end. (Or in this case, end to beginning.) I’d have to trace through the whole chain of views each time to debug and it was taking up a ton of time.
The problem was that while I was doing the right thing by not having each view controller have its own dismissal logic, the chain as a whole (A, B, C, D) was a conglomerate and, therefore, housing its own dismissal logic anyway. Somehow, this view controller group needed to be treated as one thing and the logic needed to be factored out.
Enter the Coordinator Pattern
Using the Coordinator pattern, this group of view controllers can be completely controlled by one object, a coordinator. I won’t explain the details of the pattern here, but it’s best explained by Will Townsend. Quite simply, when A is presented, a coordinator is created that becomes the delegate to A, B, C, and D. When an action is taken, such as when D needs to dismiss back to B, we do so explicitly by calling a delegate method, perhaps something named onDismissReward(self.reward).
Yeah, that method is long, but it’s clear. :-) Not only is the view controller not having to handle its dismissal logic, but it’s also not relegating that task only to the one before it. It’s asking the coordinator to do it, and the coordinator is intimately familiar with all of A, B, C, and D.
The coordinator then implements this method and, having access to all of the view controllers in the chain, can decide the best way to dismiss back to B having full control of everything. The alternative, having each view controller only know about the next in the chain, would’ve required sequential and nested calls to closures to accomplish the same thing. With a Coordinator, the logic acts in one place and the view controllers merely have to describe what it is they want to have happen. This not only clarifies how this series of view controllers should present and dismiss as a group, but each individual view controller can be controlled easily in other contexts using the same delegate or an additional one. (Extending protocols is a great way to keep the delegate calls to a tight minimum.)
Additionally, because the Coordinator is based off protocols, it’s easy to discover the right thing to do. You don’t have to rely on hidden exit segues nor, really, storyboards at all. In fact, if your entire app uses the Coordinator pattern, you could easily build all your screens in individual XIB’s if you like. You won’t need any segue logic at all.
Conclusion
The Coordinator pattern isn’t for everybody and isn’t needed by every app. For most small apps, inline navigation code is perfectly fine. As your app gets bigger and, most importantly, view controllers get reused in various places, the Coordinator pattern is worth learning. Keep it in the toolbelt, you’re going to find some great uses for it!
No Longer a Hybrid Mobile Developer And No Longer Gone Insane
It’s been about 15 months since I retired from Android so I think it’s time for an update to see how it’s gone, yeah?
Firstly, I’ll say that the response to that blog post was shocking. I had tons of comments/support/criticism from Reddit and Hacker News and I read all of it. Did I make the right choice I’d think to myself and I spent a day re-evaluating based on the feedback.
But, yeah, I haven’t written a single line of Android code since that day.
In the time since, I’ve noticed several changes to my life and well-being, so I’d call the decision a huge success, but there were a few cons, too. Let’s take a look at it all.
Pro: Staying focused on iOS has kept my skills strong and my mind “in the loop”
The primary reason I decided to quit Android is logically the biggest benefit I’ve had from it. After spending 5 or so years toggling between the two platforms, I found I was becoming decidedly “average” at both. My work life was a pendulum where I’d fall behind on the latest and greatest API for iOS and once I caught up I was missing the must-have libraries for Android and, oh by the way, what’s this Kotlin thing?
That’s gone away now. I always feel like I’m progressing in my iOS development skills and keeping up to date with the latest Swift-iness and I’m always improving on how I architect my iOS apps. I can stay focused now.
This was the biggest reason and biggest benefit by far.
Pro: Less clutter
I’m a clean guy. I try to write clean, pretty code. (I was featured in a chapter of Clean Coder by Uncle Bob as a matter of fact.) I maintain a library of tech books to try to not only keep up to date on things but review what’s in the past to pick up on concepts I’ve missed or simply to refresh myself. (I always recommend reading a new iOS How-To book every year.)
The day I quit Android I deleted Android Studio, all my SDK stuff, put my dev phones away, put my Android books in storage, deleted my Android-related Kindle books, and even put my Droid toys somewhere else. Everything around me is iOS and it’s so clean.
And, oh the extra space on my laptop.
Con: Less contract work available
Also an expected consequence, this was the one thing that kept me from making the switch to iOS-only for months (if not years) previously.
And it’s held true.
Over the past year I’ve had to turn down work twice from previous clients because they only had Android work for me. If you’re a contract, you know how hard this is to do! I could’ve caved, but I stood firm and have had consistent work, but I’ll be honest there’s been moments where it’s gotten very hard to find something and it’s led to some sleepless nights.
If I was working on both platforms I’d have twice the work available to me.
Pro: Don’t Need to buy Android devices anymore
I’ve had four Android devices in my lifetime: a Nexus S, Nexus 4, S6 Edge+, and a tablet I can’t even recall what model at the moment. In general, I disliked all of ithem except the Edge+ which was my carry-along phone for about 10 months. The irony is that I started carrying that phone at a time when I was thinking of being a devoted *Android* developer. 2.5 months later I was done with Android completely.
Less devices to buy means more money available for…Nintendo products. :-) OK, and iPhones. (But really, Nintendo.)
Con: I don’t feel cool anymore
There was a time years ago when a developer who could do both iOS and Android was pretty rare. I was proud to be one of the few. Being able to talk to a client about both their platforms at once was invigorating and surely came off as a perk. “We have one guy who can handle both our apps,” they’d say and I even had a few clients where I did product work on both sides at once.
I sorely miss being that cool and now I’m just an iOS guy. Mind you, I still talk about Android whenever I can, but I know as time goes by I’ll be further and further out of date with things and then I’ll feel like I do now when I try to talk Perl.
Sad!
Pro: Time for my kids, my wife, and a healthy work-life balance
Isn’t this what it’s all about? I don’t have to tend to two different sets of dev conferences. I don’t have to study how tables work for two different platforms, I don’t have to have two sets of network libraries in my head at a given time…and lord knows 4 languages: Objective-C, Swift, Java, and Kotlin.
I have more free time to just have fun.
And for that, I’m happy with the choice I made and confident it was the right one now and in the future!