Skip to content

Apps Dissected Posts

How Do You Get the Data From Your Custom UITableViewCells?

You don’t need to progress very far into iOS development before you need to deal with tables. This means: UITableView, and probably your own custom UITableViewCells. A common pattern is to have editable controls in those cells, so that the user can change data from the table itself. Now you’re faced with a problem:

How do you transfer that data back to your UIViewController so the app can use it?

You know how to do this with standard controls, like UITextFields, UIButtons, etc. But you have a UITableView with a bunch of UITableViewCells. They don’t really behave the same way:

  • They’re dynamically constructed by your UITableView
  • There are a variable number of them (usually)
  • Getting access to them from the UITableView is not easy
  • You don’t treat them the same way as “normal” UIViews, such as hooking them up using outlets in Interface Builder

But tear all this away, and your UITableViewCells are not special snowflakes, they are UIViews just like any other. You should treat them exactly that way. Then the answer becomes simple: you do the same thing that Apple does in their UIViews: use delegates. Here’s how.

Porting to Swift? Do it Gradually Using Extensions: Part 3

As a refresher from Part 1 and Part 2, we’re trying to make the process of porting Objective-C to Swift code more gradual by porting classes method by method using Swift extensions. This is very helpful in keeping with the idea of “When it comes to porting, smaller steps are better.” In this part, we’ll cover something I discovered when porting my custom UIKit code to Swift.

Porting UIViews and UIViewControllers is relatively straightforward using the techniques we’ve already discussed. But delegates, your most common extension point for UIViews and UIViewControllers, can be a different story.

You do the easy thing: take that first method from the delegate protocol and move it to your Swift extension. You will probably get away with this for a while, until you move a method, and Xcode suddenly expresses its unhappiness:

In this case, long ago, Apple decided to “help” you by providing a default implementation for certain methods of UIKit delegates. Whether this was a good idea in the first place is a topic for another article, but when porting the method to Swift, this causes nothing but problems.

Porting to Swift? Do it Gradually Using Extensions: Part 2

As a refresher from Part 1, we’re trying to make the process of porting Objective-C to Swift code more gradual by porting classes method by method using Swift extensions. This is very helpful in keeping with the idea of “When it comes to porting, smaller steps are better.”

This only gets us so far, though.

Some of the classes you want to port are going to contain business logic for your apps. Model data, calculations on that model data, transformations, etc.

Unfortunately, you cannot move those properties to your extension; extensions don’t support adding stored properties to a class.

What does that mean? You can’t use Swift-only types for your properties, such as structs, enums, Swift arrays, optionals, etc., because they need to be accessible from both Objective-C and Swift.

Does that mean I’m stuck with ugly Objective-C types like NSArray, NSDictionary, etc. in our Swift code, until the entire class is ported?

Thankfully not. While you can’t add stored properties in an extension, you can add computed properties in an extension. By creating computed properties that bridge between the Objective-C properties and a Swift representation of that property, you can still port your class method by method, while still writing your new Swift methods using all of the power of the Swift type system.

Porting to Swift? Do it Gradually Using Extensions: Part 1

Despite the fact that Swift has been available to iOS developers for over 4 years now, it’s likely that many long-lived apps still have Objective-C code in them. To keep things up to date, and to take advantage of the more modern Swift language, you will need to port those at least some of those classes to Swift.

You are instantly drawn to your small, simple classes, and you think, “Sure, those won’t be a problem at all. I could knock these out in a couple hours a piece.”

But then you open up one of your large classes. And you freeze.

You know which one. Every codebase has (at least) one. It is one of the core classes of the app: hundreds (or thousands…) of lines of code, many dependencies on other classes in your codebase. It’s a core part of the app; porting this class and testing that the porting doesn’t completely break everything else could takes weeks. Nobody has time for “weeks” anymore.

So you surrender, and those big, hairy Objective-C classes stay big, hairy Objective-C.

It saves unnecessary rework to only refactor code that you are actually changing for another reason. But if you’re only changing one method, you don’t want to port the rest of the class you aren’t touching, because it means extra coding work, extra testing work, extra review work…

Is there a way to port Swift like this, method by method, property by property? There is, by writing Swift extensions for your Objective-C classes.

Xcode and its iOS DeviceSupport directory: can I delete it?

Many of you are trying to do iOS development on a budget. I’ve mentioned it before: Macs are expensive. You may be trying to get by on a small SSD, or this is your main machine and Xcode is competing for space with, well, the rest of your (computing) life.

So you occasionally run your favorite disk usage tool, and you see something like this:

What the heck, Xcode? Gigabytes of space per iOS version?

I could be using that space for something useful. What is it for, and can I delete it?