I wrote an article for the MartianCraft blog about the Apple Watch, and what makes a good or bad watch experience.
Over the last few releases of iOS, things got complicated. First, we were able to share storyboards between iPad and iPhone projects, thanks to autolayout and size classes. Next, it turned out that iPad apps could be shrunken down to iPhone size, stretched out and shrunk back again during multitasking. Apps had to adapt themselves to different sizes at runtime, making sure that they displayed relevant content, appropriate to the current size.
Apple’s solution to this is
UISplitViewController. On the iPad, this maintains a two-column interface, with a smaller “primary” or “master” view controller on the leading side, and a larger “secondary” or “detail” view controller on the trailing side. On the iPhone, only one view controller is visible. Before multitasking, developers could get away with copy-pasting a delegate method from the template code, maybe checking
UIUserInterfaceIdiomin a few places, and the split view would work nicely on both devices without anyone having to think too much. Since multitasking, more thinking is required.
I recently completed a project involving a WatchKit app. It was not a pleasant experience, so here’s a screed of vague complaints with some half-baked possible solutions, and a possible ray of sunshine at the end.
In my talk at RWDevCon 2016 I described a way to handle custom view controller transitions in a way that didn’t lead to messing up your view controllers and leaving yourself with a lot of horrible cleanup code.
The secret to painless custom transitions is to do a lot of snapshots. In the talk I mentioned some utility methods for making snapshots, but there wasn’t time in the session to cover the details. Instead, I’ve written about them here.
A major difference between making your own apps and making apps for others as a contractor or “professional” developer (a common step as people move from hobbyist or indie developers to perhaps more lucrative work) will be the web services you’re asked to interact with.
Nobody’s going to pay you to make a Flickr or Twitter client, which is inconvenient because that’s what most of the online examples seem to use. If you’ve never written code that interacts with a web API before, it’s hard to approach these things with confidence, especially if you’re expected to talk to the developers of that API to work out any issues, and if those APIs are being written and rewritten in parallel with the development of the app.
In this article I’m going to go over the basics of your networking code. I’m going to assume you’re working with an API from this century so we’re talking about JSON and REST1. If you’re hearing terms like SOAP from your web people then run away.
I’m not going to define REST to mean anything other than “things are at a URL”, have that argument somewhere else ↩
You’re a great developer. Look at the quality blogs you read. If you’re starting a project today you’ll be using storyboards, organising your code in groups, everything will be well commented and it’ll be obvious in three years time what’s going on.
Meanwhile, back in reality, you’re working on an app that was first written for iOS4 and each of the dozen developers who’ve had a month to implement or fix things since then have gone in, done their stuff and moved on. Things get complicated. If you’re asked to work on an app, either to bolt more stuff onto it or (hooray!) to do some cleanup, then the very first thing you need to do is work out where you are and what’s going on.
I gave a lightning talk at iOSDevUK this year. I had five minutes to talk, so thought I’d cover the relatively simple(!) topic of how to navigate a massive, new codebase when you’re dropped in as a new developer and asked to fix problems or implement new features, right now. Here are the points I was trying to get across.
I recently worked on an app featuring a photo browser. The work involved updating the code (previously using Assets Library) to use the Photos framework.
I found out a few things that don’t seem to be represented very well in the documentation or the examples floating round online, so here they are.
When iOS 6 came out, we were in the early stages of planning for a major project. We managed to convince the client that the new app should be iOS 6 only, and decided to go all-in on the new features.
The two biggest new features, which we used almost everywhere in the app, were collection views and autolayout.
The app was built almost entirely in code, meaning a lot of constraint creation. My autolayout helper category was written to help build it.
Now it’s time for that category, and all the others (and there are loads), to be deprecated.
“Don’t Repeat Yourself” is a solid bit of programming wisdom. It’s so common it has been made into an acronym, DRY, which means that people get to make “jokes” about DRYing out their codebase.
If you write a bit of code that does something, and elsewhere in your program you need to do the same or a very similar thing, don’t copy and paste the bit of code. Make it accessible from both places, and make the minimum set of changes needed to make it reusable.
“Boilerplate” code refers to code that has to be included regularly and without much alteration to achieve basic functionality. There are plenty of frequent, common operations that require a lot of boilerplate code. The boilerplate code obscures what you actually want to do and makes the program harder to read. A good example is inserting managed objects into a context. For each type of managed object, the code looks almost exactly the same, but different types are involved.
I’m going to discuss some of the boilerplate code encountered in Core Data, and how you can use Swift generics to DRY out some of these operations. First, a few words about generics.
iOS devices have small screens. Sometimes we want more content to be included on a screen and adding it to a scroll view is a great way of doing this. I’m going to look at the various numbers and measurements that a scroll view uses to do its job.