Skip to content

Apps Dissected Posts

Keep your debug toolkit handy but hidden using conditional compilation

When you’ve been working on an app for a while, especially as it gets large, you often start to include snippets of code in the app that have been useful for debugging your app in the past. Such debugging code may be as simple as log statements, to as complex as adding full screens to your interface, activated by controls that you add to your interface for debugging only.

Such tools become an integral part of your debugging environment; you don’t want to throw them out. But do you really want to ship those in your app? It makes your app bigger and slower. You could comment them out before you release, but after a marathon debug session, do you trust that you’ll comment out again all of the debugging tools you enabled?

How can I keep my debugging addons, but ensure they aren’t in the version I deploy to the App Store?

There is a way: you can use a feature of Swift called conditional compilation to enable debugging code on your debug build. If you still have Objective-C code, you’re still in luck: a similar feature called preprocessor macros can provide the same functionality.

I’ve done the courses, tutorials, videos. Where do I go from here to get hired?

You’ve been learning iOS development for months now. You been taking courses, like the Stanford iOS development course, or Angela Yu’s courses on Udemy. You’ve watched YouTube channels like Let’s Build That App. You’ve checked out random tutorials on the web from Medium, or you’ve bought some books from Ray Wenderlich (or even sprung for the full video subscription).

And still you’re frustrated… It doesn’t feel like I’m progressing anymore.

At some point, you realize that all of these resources only take you so far, and that you need something more.

What is the next step between learning, and getting hired?

There are several paths from there, but one easy way you can make yourself stand out is to make a “clone app:” an app that replicates the functionality of an existing, well-known app. Let’s talk about the many benefits of doing that.

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:

Method 'tableView(_:numberOfRowsInSection:)' with Objective-C selector 'tableView:numberOfRowsInSection:'
conflicts with previous declaration with the same Objective-C selector

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.