Apple Networking Feedback

Recently Quinn, an engineer on the Developer Technical Support team at Apple, posted a request for feedback on Apple’s networking APIs. Here are his questions and my answers:

  1. If your product is still using the deprecated NSURLConnection or NSURLDownload APIs, is that because:
    • (A) You just haven’t got around to adopting NSURLSession
    • (B) NSURLSession is missing some feature that you need
    • (C) Other

    For B and C, please provide some details.

    Answer: There are times I’ve longed for the NSURLConnection API. In many respects, I find its execution model to be simpler, where a single connection has a single corresponding delegate. That’s really simple to follow and is the main thing I miss about the NSURLConnection API. However, I do not miss its reliance on a runloop; I’ve had situations where I’ve had to manually spin up a background thread and pump its runloop in order to keep NSURLConnection off the main thread.

  2. If your product is still using the deprecated CFHTTPStream API, is that because:

    • (A) You just haven’t got around to adopting NSURLSession
    • (B) NSURLSession is missing some feature that you need
    • (C) Other

    For B and C, please provide some details.

    Answer: Not applicable.

  3. If your product is still using the FTP protocol, is that because:

    • (A) It’s a legacy feature you haven’t got around to removing
    • (B) Your product interacts with hardware that only supports FTP
    • (C) FTP is an absolute requirement of the folks who pay the bills
    • (D) Other

    For B, C and D, please provide some details.

    Answer: Not applicable. Was it ever applicable to anyone?

  4. If your product is still using the FTP protocol, do you use:

    • (A) NSURLSession
    • (B) NSURLConnection / NSURLDownload
    • (C) CFFTPStream directly
    • (D) A third-party library that uses CFFTPStream
    • (E) A third-party library with its own core FTP code
    • (F) Other

    For D, E or F, please provide some details.

    Answer: Not applicable.

  5. If your product uses a third-party library layered on top of NSURLSession, did you choose that library because:

    • (A) It provides specific functionality you need
    • (B) It has a nicer programming interface
    • (C) Other

    In all cases, please let us know which library you’re using. In case C, please provide some details.

    Answer: (A) and (B).

    Taking AlamoFire as an example, it meets (A) because NSURLSession and friends don’t provide anything in the way of multi-part encoding. You occasionally come across the need for building up a form submission, and having to manually do that all yourself is extremely annoying, especially if that form submission involves streaming files off disk. AlamoFire’s form encoding isn’t perfect (since you can’t really compose NSInputStreams, it essentially just re-builds the entire form submission as a file on disk and then provides a single stream to that), but it’s infinitely better than a non-existent API from NSURLSession and having to roll your own encoder.

    If also meets (B) because AlamoFire generally has a shorter API than NSURLSession provides. And, as I’ll mention at the end, it uses Result<T>, which is amazing.

  6. If your product uses a third-party HTTP[S] library that is not layered on top of NSURLSession (one that uses its own core HTTP code) is that because:

    • (A) It helps with cross-platform compatibility
    • (B) It’s intrinsic to your development environment
    • (C) NSURLSession is missing some feature that you need
    • (D) The third-party library performs better than NSURLSession
    • (E) The third-party library is more reliable than NSURLSession
    • (F) Other

    For C, D, E and F, please provide some details.

    Answer: In the past I’ve used non-NSURLSession HTTP libraries mainly because of (A); when working for a company that offers their product on multiple platforms, it’s pretty common to have a bunch of the core product logic built in cross-platform frameworks (mainly C++).

    Otherwise, I rarely come across a situation where I need to “re-invent” the networking wheel.

  7. If your product uses the HTTP[S] protocol but does not use HTTP/2, is that because:

    • (A) You use HTTP, not HTTPS
    • (B) Your product talks to a variety of HTTP servers, some of which support HTTP/2 and some of which don’t
    • (C) Your product talks to a specific HTTPS server that’s outside of your control
    • (D) Your product talks to a specific HTTPS server that you control but you haven’t yet updated to use HTTP/2
    • (E) Other

    For E, please provide some details.

    Answer: (E): I’ve never had to care about HTTP 1.1 vs HTTP 2

  8. For NSURLSession [*], what are the enhancement requests or bugs that you’d most like to see addressed? Please list up to five in order from most to least desired. Ideally we’d like a list of bug numbers, with all the details in the corresponding bug report.

    [*] This includes the core NSURLSession API and all its related technologies, including:

    • Async API structure (delegates, blocked-based convenience APIs, and so on)
    • Swift integration
    • Requests and responses
    • Caching
    • Cookies
    • Authentication (including credentials and their storage)
    • Background sessions
    • Core HTTP and HTTP/2 protocol implementations
    • Debugging tools
    • Security (HTTPS)
    • Performance
    • Task metrics
    • Task prioritisation
    • Stream tasks

    Answer: I generally don’t have many complaints about the networking stack. Mainly I just want it to be simpler, but if I had to pick some…

    1. Swift integration (mainly better type-safety)
    2. Debugging tools (see answer to #16)
  9. If your app uses the reachability API (SCNetworkReachability, either directly or via a wrapper like the Reachability sample code), is that because:
    • (A) Someone said you needed reachability and you’re not entirely sure why
    • (B) You just haven’t got around to adopting the new waitsForConnectivity support in NSURLSession
    • (C) You want to preflight network requests, that is, you don’t make a request until reachability indicates that it might work
    • (D) You want to know when it’s a good time to retry a failed request
    • (E) You’re using SCNetworkReachabilityCreateWithAddressPair to monitor the state of a specific connection
    • (F) You want to know what type of networking is available, for example, WWAN or Wi-Fi
    • (G) You’re using it solely to update your app’s user interface
    • (H) Other

    For C, we’d really like some details on why you’re preflighting network requests.

    For F, G and H, please provide some general details.

    Answer: (B), (D), (F), and (G).

    I like control. By manually using SCNetworkReachability, I get the control to manually retry requests, update my app user-interface, proactively disable app functionality (why should I keep a sync engine turned on if I “know” the network is off?), and tune certain kinds of requests to the networking interfaces I feel are more appropriate for the app’s functionality (ex: when on WWAN, restrict communication to app-critical things; save WiFi for proactively downloading caches, etc).

    However, the reachability API is archaic. It desperately needs some Swifty love.

  10. If your product works directly on top of the TCP protocol, what API do you use:

    • (A) BSD Sockets
    • (B) CFSocket
    • (C) NSStream
    • (D) NSURLSessionTask
    • (E) NWTCPConnection
    • (F) A third-party library
    • (G) Other

    For F, please let us know which library you’re using. For G, please provide some details.

    Answer: Not applicable.

  11. If you answered the previous question, please provide information about your TLS (aka SSL) use:

    • (A) You don’t need TLS
    • (B) You use the TLS implementation provided by the API you’re using (for example, in NSURLSessionTask you can enable TLS by calling -startSecureConnection)
    • (C) You use Secure Transport to implement TLS
    • (D) You use OpenSSL to implement TLS
    • (E) You use some other third-party TLS library

    For D, please explain why you use OpenSSL. For E, please provide some details.

    Answer: Not applicable, although there are totally valid reasons for bundling OpenSSL in your app because the iOS Security APIs don’t provide enough functionality.

  12. If your product uses BSD Sockets for networking, is that because:

    • (A) It helps with cross-platform compatibility
    • (B) You have existing code that you don’t want to rewrite
    • (C) You’re using UDP, not TCP
    • (D) You’re using one of the more obscure features of BSD Sockets (raw IP, routing sockets, and so on) for which there is no equivalent higher-level API
    • (E) The equivalent higher-level API would otherwise be appropriate but is missing some small feature that you need
    • (F) Your code performs better than the equivalent high-level API
    • (G) Your code is more reliable than the equivalent high-level API
    • (H) Other

    For D through H, please provide some details.

    Answer: Not applicable

  13. Are you interested in adopting the QUIC protocol?

    Answer: I don’t know what QUIC is.

  14. Are there any other existing or future networking protocols that would be useful to your product? Remember that the focus here is on commonly-used user-space networking APIs, so please restrict yourself to protocols that make sense in that context.

    Answer: Web sockets. If you’re connecting to a realtime web service, it’s pretty common to have that implemented via websockets. In the past I’ve poked around at SocketRocket and Starscream. It’d be very nice if that were built-in.

  15. When debugging problems with the networking features of your product, which tools do you typically use?

    • (A) Wireshark
    • (B) Some other packet trace tool
    • (C) A debugging HTTP proxy
    • (D) CFNetwork diagnostic logging
    • (E) sysdiagnose logs
    • (F) Other

    For B, C and F, please provide details.


    (C): Charles Proxy

    (D): I put this in here because I explicitly don’t use it. There’s no obvious way to configure the verbosity of its logging, and it seems like every other release of iOS plagues your console with random spew from the networking layers that is difficult to disable. It’d be nice if this were useful in any degree, but honestly right now it’s an utter waste of console space and just obfuscates my logs.

    (F): Paw ← this is like the best thing ever.

  16. In the context of debugging problems with the networking features of your product, is there a specific tool that you’d like Apple to provide?

    Answer: I want an Instruments template that does HTTP inspection. There are templates for doing the byte-level traffic analysis, but usually I don’t care that much about it. I want a tool that shows me the actual HTTP requests and responses, like what I get in Charles. I want to see the hosts I’m connecting to, the raw HTTP request, various views of the bodies (raw, formatted, interpreted as JSON, interpreted as form encoding, etc), the headers, the latency, etc. And I want to see all this information for the response.

    Ideally, there would be a debug gauge in Xcode that shows a high-level view of this information, and then if I needed deeper analysis I would pop open Instruments to get it.

Other Thoughts: (These don’t particularly fit in to the questions above, so I’m putting them here at the bottom)

There are a couple things that I find annoying about working with NSURLSession in Swift:

  1. It’s a URL session, and not an HTTP session. This means I have to do lots of silly as? casting to make sure things are HTTPURLResponses before proceeding. I would really love to see a specialization of the API that is focused on only the HTTP use-case. I don’t think I’ve ever really needed anything except an HTTP session, and having to dig around the API to figure out what’s HTTP-specific and not and do the type-safe guarding is annoying.

  2. The Swift API desperately needs a Result<T> type. Getting a callback that is a (URLResponse?, Data?, Error?) is supremely annoying to deal with. I’d much rather have a Result<(HTTPURLResponse, Data?)>. That would be way easier to work with.

  3. It would be nice (but not required) to have some sort of protocol-defined serialization/deserialization support for bodies in requests and responses. If I know that I’m going to get back XML or JSON or an Image, it’d be great if I could have a generic way to simply say “execute this request and give me back the image that comes back in the body”.

Swift Protocols Wishlist

If I were Supreme Swift Potentate, there are a few things I’d change about how Swift deals with protocols, and how this gets manifest in the standard library.

In no particular order, here they are:

  1. If you’re adopting a protocol (especially one from the standard library), the tools don’t provide any help whatsoever in knowing what you actually have to implement. Because of this, it’s pretty much flat-out impossible¹ to make your own value-typed data structure (like, say, an AVL tree or whatever) that conforms to all of the expected data structure-y protocols.

  2. I wish protocols were generic instead of having associated types. For example, I wish I could declare:

    func processTheseIntegers(_ integers: Collection<Int>) { ... }

    Instead of having to make the whole thing generic:

    func processTheseIntegers<C: Collection>(_ integers: C) where C.Element == Int { ... }
  3. We don’t have generic protocols, because instead we have these things called Protocols with Associated Types (“PATs”). PATs are things that look great at first blush. Just take a look at how succinct this is!
    protocol Requestable {
        associatedtype ResponseType: InitializableFromData

    It’s so easy declare that “I have this request, and it has a related response type, and this response value has to conform to this protocol. Awesome!


    The rules around arrays and stuff in Swift mean you can’t create an array of anything that happens to be Requestable:

     var currentRequests: Array<Requestable> // not allowed

    In order to do something like this, you have to create type erasers or propagate the associated type of the protocol out as a generic. It’s maddening and it sucks the life out of you. Basically any time you find yourself using a PAT, you know that you’re either going to have to create a type eraser, or you’re going to have to make things generic that have no business being generic. They’re these parasitic things that end up infesting your code in ways you really don’t want.

  4. I wish the compiler generated type erasers for me. In the case of the Requestable stuff above, the common way to work around the problem of heterogenous arrays is to make them homogenous using type erasers. A type eraser is a value that hides some of this stuff and “homogenizes” the types to the type system. For examples of this, see pretty much anything in the standard library whose name starts with Any, like AnyHashable. Writing type erasers manually is an exercise in pain. You have to create a couple of layers of indirection and do some weird things that I can never remember off the top of my head and always have to google. It’s grunt work, and the compiler should do it for me.

  5. I wish there were a way to say “this protocol can only be adopted by value types”. We have the opposite, to say “this protocol can only be adopted by reference types”, which is great for defining weak var delegate: MyDelegateProtocol?.

    But there are times when you want a protocol-typed value, but don’t want to allow mutability. Normally in Swift you define immutability with let and var. However, you can’t do that with protocols. With a protocol, everything is a var, because it can be adopted by a reference type, and reference types have no restrictions on internal mutability. This is inherently unsafe, if you allow for things to change out from underneath you. This is why Array and String and everything became value types in Swift, because their internal-mutability creates for some nasty bugs in Objective-C, where they’re reference types.²

  6. This one is pretty niche, but occasionally you deal with a lot of single-requirement protocols, like this:

    protocol YearHaving { var year: Int { get } }
    protocol MonthHaving { var month: Int { get } }
    protocol DayHaving { var day: Int { get } }

    It’d be nice if there were a shorthand way to define a struct that just has all of those fields. Maybe something like this:

    auto struct YearMonthDay: YearHaving, MonthHaving, DayHaving { }

    That way you wouldn’t have to re-declare all of the properties you’re supposed to have, and they’d all come in as let properties (because they only have { get }), and then you get the default compiler-provided initializer of .init(year: Int, month: Int, day: Int). Yeah this is pretty specific, but when you need it, you need it.

  7. These last ones are all related, and they’re all really big. I wish I could provide default implementations of protocol methods that assign to self. For example:

    protocol URLRequestable {
        var url: URL { get }

    There are a bunch of different kinds of URLs. It’d be nice if I could do:

    extension URLRequestable {
        init(url: URL) {
            switch url.scheme {
                case "mailto": self = EmailRequest(url: url)
                case "ftp": self = FTPRequest(url: url)
                case "http": self = HTTPRequest(url: url)
                default: self = URLRequest(url: url)

    This is related to a concept in Objective-C called “class clusters“. A class cluster is basically an interface for a type, with a bunch of varying implementations that depend on certain conditions. To me, defining a class cluster’s interface via a protocol feels far more “swifty” than using an abstract superclass (like Objective-C), but there’s also no way to make it truly swifty and use an initializer to create your cluster instance; you have to use a static factory method if you want to do that.

  8. I wish I could extend a protocol to conform to another protocol. For example:

    protocol URLRequestable {
        var url: URL { get }

    If I know that all URLRequestable things have a protocol, then I should be able to do:

    extension URLRequestable: Hashable {
        static func ==(lhs: URLRequestable, rhs: URLRequestable) -> Bool { return lhs.url == rhs.url }
        var hashValue: Int { return url.hashValue }

    That would be super useful, because I could get incoming URLRequestable values, and then toss them in a Set to help ensure I don’t execute duplicate requests. Sadly, you cannot do this. I don’t know why. (Usually when I ask, I get told something intensely inscrutable that includes the word “existential” in it)

  9. Adding these all up leads me to my last wish: I wish that the API defined by the standard library was actually all just protocols. I wish String and Array and Dictionary and Set were protocols. If you had protocol clusters, you could still construct things like you do now, but you’d just get back private implementations of protocol String or whatever. This would mean that, when I ask a Dictionary<String, Foo> for its .keys, I could just get back a Set<String> and not a Dictionary<String, Foo>.Keys. Similarly, when I ask for a .lazy.something, I don’t have to get back some weird LazyRandomAccessCollection or whatever; I could just get an Array<Something> that happens to have a lazy implementation.

I look at these things on this list and think “wow, Swift would be awesome if it had all of this”. I really really wish it did; especially the last one. And maybe someday it’ll have a couple of these, but I get depressed when I think that it’s probably highly unlikely it’ll ever have all of them.

¹ – yeah, I know it’s not impossible. But doing it “right” requires way too much work to even figure out what “right” means.

² – yeah, I know you can make a struct that is internally mutable by having it wrap a reference type.

ⁿ – I posted about this on Twitter here.

Simplifying Swift framework development

I’ve developed a handy trick when writing frameworks in Swift that makes the overall process a little bit nicer, and it’s just adding a single file to your framework.

Let’s say you’re building CoreAwesome.framework for inclusion in your app, or publishing to Github, or whatever. There are a couple things you end up doing a lot:

First, you end up having lots of import OtherFramework statements scattered throughout your .swift files, so that portions of your framework can have access to pieces of functionality provided by dependencies (whether system frameworks or whatever). I find that sort of repetition (import Foundation, anyone?) to be pretty annoying.

Second, you don’t always have a good way of getting access to the Bundle that corresponds to the framework easily. You need this particularly if you’re loading bundle-specified resources.

So, based on these two things, I’ve developed this pattern, which is kind of like a swift framework pre-compiled header:

When I create CoreAwesome.framework, I get CoreAwesome.h, and that’s about it. So I immediately add CoreAwesome.swift at the top level next to the .h, and put this in it:

// CoreAwesome.swift
@_exported import Foundation
@_exported import DependencyA
@_exported import DependencyB

public let CoreAwesome = Bundle(for: CoreAwesomeMarker.self)

private class CoreAwesomeMarker { }

First, there’s this weird @_exported thing. The underscore indicates we need to be a bit wary of it, because it’s not a modifier you’re really supposed to use. But if you do…

@_exported will make an import-ed module visible to the entire module into which its been imported. This means you don’t have to import Dependency in every file you need it. You just @_exported that dependency once, and you’re good to go in any file in that module.

This is especially nice if DependencyA defines public operators, which aren’t always imported the same way that symbols are. That’s a topic for another day.

Second, I define a public constant that is the name of the framework, and whose value is the Bundle for that framework. I use the class-based look up (ie, find the bundle that declares this class), because it’s one of the few convenient Bundle initializers that doesn’t return a Bundle?, and thus I don’t have to deal with unwrapping. And then I use a special marker class for making that lookup resilient in the face of other functionality changes.

With the constant in-hand, I can easily load resources:

let resource = CoreAwesome.url(forResource: "Foo", withExtension: "plist")

This reads pretty naturally, and the entire file makes developing my framework just a little bit easier.

Update: I neglected to mention that it was Joe Fabisevich who clued me in to the @_exported trick. Thanks, Joe!!

Update #2: Both Harlan Haskins and Kevin Ballard pointed out that the constant to access the framework’s bundle will conflict with a module-qualified declaration. Like, if you have two modules that declare a Foo, then you need to disambiguate which one you want by doing Module1.Foo vs Module2.Foo. However, if Module1 is the name for a Bundle instance, this breaks.

Solving this problem is left as an exercise for the reader. 😉

Reading your own entitlements

When you’re writing an iOS or macOS app, you typically don’t need to dynamically know what your own entitlements are. However, there are a couple of rare circumstances when it could be Nice To Have.

I recently came across one of those situations. Like most developers, I have a set of core libraries I maintain that I use in my apps. These libraries tend to contain all of the common pieces of code I’ve found to be helpful. It’s like my own private SDK.

For example, I have a Sandbox type that represents a set of on-disk locations:

public class Sandbox {

    public static let currentProcess: Sandbox

    public let documents: AbsolutePath
    public let caches: AbsolutePath
    public let support: AbsolutePath
    public let temporary: AbsolutePath

    public init(documents: AbsolutePath, caches: AbsolutePath, support: AbsolutePath, defaults: UserDefaults)
    public convenience init?(groupIdentifier: String)

I got thinking that it’d be nice to add a static default property on Sandbox that would contain the “default” Sandbox. In a situation where my app doesn’t use a shared group container, the default sandbox would be the current process’s sandbox. If I do have one (or more) shared group containers, then the default sandbox would be the first one listed. This is similar to how CKContainer.default behaves. You could imagine wanting similar behavior if you have a wrapper around the Keychain APIs, for example.

However, entitlements end up getting embedded inside your app binary. They are not a copied-in resource, but are rather a blob of data stuck in your executable file.

After lots of googling and asking friends, I eventually found two resources that were exceptionally helpful:

1️⃣ The first was this answer by Cédric Luthi. In it, he shows how to use the dyld APIs to find your executable image, and then iterate through the sections defined in that image until you find the one you’re looking for. In his case, he wanted the LC_UUID section. In order to read your own entitlements, you want the LC_CODE_SIGNATURE section.

Once you’ve found the LC_CODE_SIGNATURE section, you know roughly where in your executable file the entitlements are located. However, the resulting __LINKEDIT section has a largely undocumented format, and it wasn’t until Daniel Jalkut suggested I find the codesign source that I made any progress.

2️⃣ After some targeted googling, I found this source code on This file appears to be a decent amount of the source for the codesign utility, but the really awesome bit is that lc_load_sig function. There, finally, is how to poke around in that special __LINKEDIT section and interpret what’s going on.

Armed with these two pieces of data, we can now build some code that will read the entitlements blob out of your own executable (and once you have the blob, you can run it through NSPropertyListSerialization to parse and introspect it):

#import <Foundation/Foundation.h>
#import <mach-o/dyld.h>
 * Structure of an embedded-signature MultiBlob (called a SuperBlob in the codesign source)
typedef struct __BlobIndex {
    uint32_t type;                   /* type of entry */
    uint32_t offset;                 /* offset of entry */
} CS_Blob;

typedef struct __MultiBlob {
    uint32_t magic;                  /* magic number */
    uint32_t length;                 /* total length of SuperBlob */
    uint32_t count;                  /* number of index entries following */
    CS_Blob index[];                 /* (count) entries */
    /* followed by Blobs in no particular order as indicated by offsets in index */
} CS_MultiBlob;

extern NSData *EntitlementsData(void) {

    // iterate through the headers to find the executable, since only the executable has the entitlements
    const struct mach_header *executableHeader = NULL;
    for (uint32_t i = 0; i < _dyld_image_count() && executableHeader == NULL; i++) {
        const struct mach_header *header = _dyld_get_image_header(i);
        if (header->filetype == MH_EXECUTE) { executableHeader = header; }

    if (executableHeader == NULL) { return nil; }

    // find if it's a 64-bit executable or not
    BOOL is64bit = executableHeader->magic == MH_MAGIC_64 || executableHeader->magic == MH_CIGAM_64;
    uintptr_t cursor = (uintptr_t)executableHeader + (is64bit ? sizeof(struct mach_header_64) : sizeof(struct mach_header));

    // iterate through the dyld commands to find the "LC_CODE_SIGNATURE" command
    const struct segment_command *segmentCommand = NULL;
    for (uint32_t i = 0; i < executableHeader->ncmds; i++, cursor += segmentCommand->cmdsize) {
        segmentCommand = (struct segment_command *)cursor;
        if (segmentCommand->cmd != LC_CODE_SIGNATURE) { continue; }

        const struct linkedit_data_command *dataCommand = (const struct linkedit_data_command *)segmentCommand;

        // jump to the offset specified by the command
        uintptr_t dataStart = (uintptr_t)executableHeader + dataCommand->dataoff;
        CS_MultiBlob *multiBlob = (CS_MultiBlob *)dataStart;
        if (ntohl(multiBlob->magic) != 0xfade0cc0) { return nil; }

        // iterate through the blobs in this segment until we find the one with the appropriate magic value
        uint32_t count = ntohl(multiBlob->count);
        for (int i = 0; i < count; i++) {
            uintptr_t blobBytes = dataStart + ntohl(multiBlob->index[i].offset);
            uint32_t blobMagic = ntohl(*(uint32_t *)blobBytes);
            if (blobMagic != 0xfade7171) { continue; }

            // the first 4 bytes are the magic
            // the next 4 are the length
            // after that is the encoded plist
            uint32_t blobLength = ntohl(*(uint32_t *)(blobBytes + 4));
            return [NSData dataWithBytes:(const void *)(blobBytes + 8) length:(blobLength - 8)];

    return nil;


It turns out that the code above only works when you’re deploying to a device. If you’re just building for simulator, then the entitlements actually go in a different location; they’re in the __TEXT segment in a section called __entitlements, and they’re the sole contents of that section. This means reading them is very easy:

NSData *ReadEntitlementsFromTEXT(const struct mach_header *executable) {
    uint32_t dataOffset;
    uint64_t dataLength;

    BOOL is64bit = executable->magic == MH_MAGIC_64 || executable->magic == MH_CIGAM_64;
    if (is64bit) {
        const struct section_64 *section = getsectbynamefromheader_64((const struct mach_header_64 *)executable, "__TEXT", "__entitlements");
        dataOffset = section->offset;
        dataLength = section->size;
    } else {
        const struct section *section = getsectbynamefromheader(executable, "__TEXT", "__entitlements");
        dataOffset = section->offset;
        dataLength = (uint64_t)section->size;

    uintptr_t dataStart = (uintptr_t)executable + dataOffset;
    return [NSData dataWithBytes:(const void *)dataStart length:dataLength];

A Better MVC, Part 4: Future Directions

Part 4 in a series on “fixing” Model-View-Controller:

  1. The Problems
  2. Fixing Encapsulation
  3. Fixing Massive View Controller
  4. Future Directions

There are other ways you can apply these principles to writing more maintainable apps.

View Controller-based Cells

One that I’m really interested in and am actively researching is how to use view controllers as cell content.

Cells can be really complicated things, architecturally. If you have any sort of dynamic content in a cell, you’re often faced with weird situations where you wonder “where does this logic belong?”. Do you put image loading in your view subclass? Allow your cell to handle complex business logic? Tack on additions to the list’s delegate protocol so you can message things back out (which then just complicates your list view controller)?

Using view controllers as cells helps answer these questions. It is natural to place this sort of code in the view’s controller, and the fact that the view happens to be a cell doesn’t really make a difference to the underlying principle.

Small finite lists

It’s really easy to make a view controller a cell when you have a list of a finite size. You have your “ListViewController”, and you give it an array of view controllers. It adds them as children, and then pulls out the appropriate one when its time to show a cell, and sticks the view controller’s view inside the cell’s contentView.

You can then apply the same principles of “flow view controllers” and “mini view controllers” to the content of the cell, and use child view controllers to manage portions or variations of the cell. I used to write a Mac app where I used this approach, and I could sometimes get upwards of 15 view controllers in a single cell. Granted, the cells were pretty complicated in what they could do, but none of these view controllers was longer than 100 lines of code. It made debugging issues trivially easy.

At this level of granularity in a finite list, you also probably aren’t very worried about view lifecycle callbacks, because you can pre-allocate everything.

Huge finite lists

Once you start moving past the point where you can pre-allocate everything, you have two main approaches you can take. The first approach (“huge finite lists”) is like what the current UITableView and UICollectionView API offer: you know up-front how many items are in a section. In this case, your ListViewController would likely have a similar looking datasource API as UITableView, where it progressively asks for view controllers and then uses the underlying “willBeginDisplayingCell:” etc callbacks to notify on lifecycle.

At this level you might also want to start thinking about view controller reuse, but I would probably avoid thinking about that unless I measured and determined that view controller deallocation and initialization was a measurable bottleneck.

Infinite lists

Then there’s the problem of infinity. A great example of this is the main screen of the Reddit app. You can scroll forever, and the content will just keep loading and loading… there’s no way to know up-front how much content there is. With this, you’ll be looking at loading in “slices” of the infinite view controller sequence, or taking a page (haha) out of UIPageViewController‘s book and using the “doubly-linked list” sort of API (“what’s the view controller after A? What’s the view controller after B? etc).

You’ll still have the underlying callbacks to help manage view lifecycle, and you’ll also still have to consider view controller reuse as an option.


As you get in to this style of programming, you’ll find that you end up developing a decent amount of boilerplate around embedding view controllers. That is to be expected, because the view controller containment APIs tend to offer the bare minimum to do what you need.

As you find situations where the API can be improved, please request that these improvements be made in the system frameworks.


There’s a lot to digest in these posts. Some people may scream in horror at the idea of “view controllers as cells”, but it’s an idea worth exploring.

So, the huge TL;DR of this is:

  • Decompose your UI using view controllers
  • Use view controllers to manage sequence
  • View controllers don’t have to fill the screen

I’d love to hear your thoughts on this topic. Hit me up on twitter or via email and let’s chat!

A Better MVC, Part 3: Fixing Massive View Controller

Part 3 in a series on “fixing” Model-View-Controller:

  1. The Problems
  2. Fixing Encapsulation
  3. Fixing Massive View Controller
  4. Future Directions

The principle behind fixing Massive View Controller is to unlearn a concept that’s inadvertently drilled in to new developers’ heads:

1 View Controller ≠ 1 screen of content

From our very first iOS apps, we’re taught the idea that 1 view controller == 1 screen of content. We see this in every simple “make a list and push a detail view” app. However, as our apps grow in complexity, so do our screens of content, and the default notion that 1 view controller == 1 screen of content quickly leads to Massive View Controller.

We can save ourselves from Massive View Controller by realizing that a view controller “controls a view” and that view doesn’t have to fill the screen.

Example: The WWDC App

Disclaimer: While I used to be the lead engineer on the WWDC app, I have not seen the code in quite some time and do not know if it is actually implemented this way. I am simply describing how I would build the screen if I were to build it today.

Here’s a screenshot of the WWDC app:

WWDC app session details page

On this one screen, there are five main pieces of content:

  1. The video
  2. The title
  3. The description
  4. The contextual actions
  5. The related content

There is a lot going on here, and if this were to be implemented as a single view controller, it would be a massive view controller.

So, let’s not do that.

Instead, we’re going to make each one of those 5 areas its own view controller, all contained within the SessionDetailsViewController. The outer details view controller will own the general layout of the screen, as represented by some empty container views. These will all be in a UIScrollView that manages its content bounds through auto layout.

The SessionVideoViewController would be in charge of loading up the appropriate poster frame for the video and responding to the user tapping the play button. When the user taps that button, the view controller will delegate out that the user intends to watch the video. The parent SessionDetailsViewController can then pass that intention up the chain until it arrives at a semantically appropriate level for that intention to be translated in to the corresponding WatchVideoOperation.

The SessionTitleViewController and SessionDescriptionViewController will be pretty simple, since all they’ll have to do is observe the model object for changes and update the labels. There’s also no interaction to delegate back out.

The SessionActionsViewController would basically be a UIStackView of buttons. The buttons would be created based on inspecting the model object, and interacting with the buttons delegates back out the corresponding intention: “toggle favorite”; “leave feedback”; “begin download”; etc.

Finally, the RelatedSessionsViewController would be a side-scrolling collection view. Tapping on a related session would delegate back out that the user wants to view the session. The SessionDetailsViewController, as we learned in the previous post, would not be the one to perform that action, but would instead relay the intention up to a more semantically appropriate level (such as the view controller that owns the UINavigationController).

At the end of this exercise, we end up with more view controllers (six instead of one), but each one is relatively small. The video view controller loads a poster frame. The title and description view controllers observe the model for changes. The actions and related content view controllers are a little more complex, but each one is focused on a very specific set of actions, and neither is onerous to understand.

Example: The Reddit App

Disclaimer: I have no idea how the Reddit app is built.

For this example, let’s take a look at the Reddit app.

The Reddit app

There are a bunch of interesting things going on here, but I want to focus on the top part of this post screen that contains the actual post. A cursory survey through the app shows that there are several different styles that this post content can take, in addition to having a title:

  • Text
  • Link
  • Animated gif
  • Static image
  • Video

It would be crazy to try and build the entire post page as a single view controller. At the very least, you’d want a “post content” view controller, and a “comments” view controller. But you can go further.

Imagine that the top post content is a PostContentViewController. You still have a large view controller as you have to handle one of these 5 different kinds of post content (showing all text vs loading a web preview vs animating a gif vs showing an image vs an inline video vs a link to an external video…).

So instead, make your PostContentViewController a “flow” view controller, and then have a different view controller for each kind of content. When you have a TextPostContentViewController, you never have to worry about dealing with loading callbacks. A LinkPostContentViewController only has to deal with loading a preview. A GIFPostViewController only ever has to load a gif. It’s easy, and you PostContentViewController just has to pick the right one, embed it, and then handle the odd delegation of user intent.

By combining both principles (view controllers as flow and small view controllers), you can easily decompose your UI in to small, manageable, testable, isolated, and grokkable chunks.

A Better MVC, Part 2: Fixing Encapsulation

Part 2 in a series on “fixing” Model-View-Controller:

  1. The Problems
  2. Fixing Encapsulation
  3. Fixing Massive View Controller
  4. Future Directions

In order to fix the encapsulation violation we saw earlier, we need to understand a pretty simple principle:

In general, a view controller should manage either sequence or UI, but not both.

A view controller that manages sequence is one that I jokingly call a “Manager View Controllers” because 1) “manager” and “controller” aren’t overloaded enough already and 2) it still has the acronym “MVC”. In reality, this is a variation on the “Coordinator” pattern that has captured some of our imagination.

The idea behind the Coordinator pattern (or flow controllers or whatever you call them) is that, in order to maintain encapsulation, you need a higher-level object to decide what comes next. It “controls the flow” in your app.

Where I tend to diverge from the “traditional” flow controller implementation is that I believe that these sorts of controllers should really just be view controllers higher up in the parent view controller chain. This saves you from having to hack a new kind of responder chain object in to UIViewController, and it means you don’t end up with a third parallel hierarchy of control to maintain in sync with the other two (the View hierarchy and the view controller hierarchy).

Using container view controllers as sequence “coordinators” makes a whole lot of things really easy. For example, consider a screen where you want to load a piece of remote content. But while it’s loading, you want a spinner to show up. If the content fails to load, you want an error screen and a “try again” button.

Implementing this as a single view controller would leave you in a place where you’re on the road to Massive View Controller. You’d have a view controller that’s probably hitting the network and then trying to rationalize which of the three different states it should be in (Error, Loading, or Success), then is responsible for making sure the right set of UI elements are visible and getting the model information into the proper set of out outlets.

Instead, abstract out the sequence from the UI. The sequence is the owner of the flow between the three states, and each of the states is its own view controller.

The ShowRemoteContentViewController (the owner of the sequence) has an empty view, and it embeds the proper content view controller depending on which state it should be in:

  • Show the ErrorViewController if your networking object reported back an error. The ErrorViewController delegates back out when the user taps on a “Try Again” button, which causes the delegate (the ShowRemoteViewController) to transition to the loading state while hitting the network
  • The LoadingViewController is an empty view controller that shows a loading indicator. It is literally zero lines of code, unless you want a simple init() method, in which case it is 4.
  • The MessageViewController is the view controller that handles the “success” state. It basically populates its UI from the injected model object, and delegates back out when the user taps a “Load Another” button.

A simple iOS project (Xcode 9.1, Swift 4) showing this in action is available here: iOS

We’ve taken something that was really complicated (a single object managing UI and state and flow) and turned it in to something eminently understandable; no view controller is longer than 100 lines of code long. Each one is isolated from everything else. A good use of delegation means that testing is trivial: we load up the UI, fake a tap on the button, and assert that the delegate method is invoked. There’s almost no cognitive load to understand any individual view controller. Even the “more complicated” ShowRemoteContentViewController is simple, because it’s just flipping back and forth between a couple of different child view controllers in reaction to some delegate method invocations or the network loading. It’s all really simple, and there are no violations of encapsulation.

The same pattern holds true when you’re dealing with more structured UI. If we imagine now a list UI, where tapping a list item brings up a detail view, we can apply this same principle.

First off, we don’t want the list knowing about the detail view controller or how to show it. So, we simply make it delegate back out to someone else what the user is intending to do. The list UI receives model objects from “the outside”, so that’s what it should send back. Therefore, in our implementation of didSelectRowAtIndexPath:, we simply translate the index path in to the corresponding model object, and then message the delegate what the user intention was: listViewController:userDidSelectModelObject: → “The user wants to look at this model object”.

So, who then is the delegate? You could argue that it might be the direct parentViewController, but in this case, the parent is likely a UINavigationController. The UINavigationController is already in charge of maintaining a stack of view controllers with its own UI (the navigation bar), so this doesn’t seem like a good candidate. Instead, let’s put the UINavigationController inside a container view controller, which we’ll call the ListFlowViewController.

The ListFlowViewController creates and embeds the plain UINavigationController in itself and gives it the root screen (the list view controller). Then, it makes itself the delegate of the list, because it’s the ListFlowViewController that created the list and (likely) knows what the model objects mean. Then when the user selects an item in the list, the ListFlowViewController receives the corresponding model object, knows how to turn it into the detail screen, and gives that screen to the UINavigationController to push. We again preserve proper encapsulation principles.

This same pattern also holds true on iPad (or regular width phones) where you deal with UISplitViewController. Having a container view controller own the split view means you have a natural place for the “master” view controller to message about the user intent, and handle how to appropriate display the detail view controller. This same container view controller could also decide to entirely eschew a split view controller if the app transitions back to a compact width size class.

The huge advantage of this approach is that system features come free. Trait collection propagation is free. View lifecycle callbacks are free. Safe area layout margins are generally free. The responder chain and preferred UI state callbacks are free. And future additions to UIViewController are also free.

In exchange, you have to suffer through cleaner code, smaller view controllers, and a few more delegate protocols, which unfortunately just make your code more isolated and testable. How on earth will you survive?? 🙃

A Better MVC, Part 1: The Problems

Part 1 in a series on “fixing” Model-View-Controller:

  1. The Problems
  2. Fixing Encapsulation
  3. Fixing Massive View Controller
  4. Future Directions

I recently ran across a great article by @radiantav called “Much ado about iOS architecture“. It addresses a topic that has been on my mind a lot. I gave a talk about it at the recent Swift by Northwest called “A Better MVC”. These blog posts attempt to capture the main points of my talk.

I apologize beforehand that there aren’t really any pictures in this. They’d definitely make the subject matter clearer, but I don’t feel like spending the time to make them. You’ll just have to use your imagination.

The “Problems” with MVC

The main reason that people decry MVC is that they tend to run afoul of two major problems when using it:

  1. MVC, as taught by Apple sample code, encourages you to violate encapsulation principles, which ends up leading to spaghetti code.
  2. Without proper discipline, your view controllers end up being huge, leading to the joke that “MVC” means “Massive View Controller”.

Violating Encapsulation

It’s pretty common to come across a UITableViewDelegate method that looks something like this:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let maybeItem = query?.object(at: indexPath)
    guard let item = maybeItem else { return }
    let detail = MyCustomDetailViewController(item: item)
    show(detail, sender: self)

There are two huge encapsulation violations that are occurring here.

The first is this line:

let detail = MyCustomDetailViewController(item: item)

The principles of encapsulation indicate that a thing should only really “know” about objects that it contains, and then only about one layer of abstraction down. However, this line, which constructs a subsequent screen-full of information, requires the view controller to know about the sequence of data flow in its parent abstraction.

In other words, this list isn’t just a list, but must also being aware of the context in how it’s used.

The second violation is similar to the first:

show(detail, sender: self)

Again, this violates the whole “don’t know your context” principle. And, it should be noted, these critiques hold true whether you’re manually creating and showing a detail view controller, or invoking a segue and using prepareForSegue:sender:.

Massive View Controller

It is sadly pretty common to come across a view controller that is thousands of lines long. Our view controllers quickly become cluttered with networking callbacks, delegate methods, data source methods, IBActions, trait collection reactions, model observation, and of course, our business logic. Heaven forbid if you’re doing any sort of progressive loading and want to swap in an indicator to show while things are loading… that will usually add in a couple hundred lines of code as you deal with swapping views around, managing yet another stateful property, and so on.

We end up with this situation because we don’t apply enough discipline to our view controllers. They’re convenient places to dump code. But they quickly become unmaintainable, fragile, and inherently untestable. Who wants to be the poor soul who has to debug some weird state going wrong in a 5,000+ line file?

Working around MVC

In my experience, these are pretty much the two fundamental reasons why developers find other architectural patterns so appealing. As a result, we turn to other architectural patterns to try and compensate. We reach for MVVM, or React, or MVP, or FRP, or VIPER, or insert-new-architecture-here.

To be clear, there is nothing inherently wrong with any of these patterns. They all solve problems in unique and interesting ways, and it is good to study them and learn the principles they teach. However, I’ve found that building apps based on these patterns tends to pay negative dividends in the long run.

All of these patterns tend to be “strangers” to UIKit and AppKit. Because of this difference, you end up with additional hurdles to clear when things change.

When your team members change, you have additional work to teach new developers about not just the business logic of your app, but often a whole new architectural pattern. This requires more up-front investment, and a longer lead time before team members can start being productive.

When the operating system changes, you have additional work to try and shoehorn new features in to architecturally-native concepts. You have to plumb through size classes, safe layout margins, dynamic type, localization, locale changes, preferred attributes (status bar style, etc), lifecycle events, state preservation and restoration, and who knows what else when new paradigms get inevitably added as iOS updates each year.

When your requirements change, you can sometimes be caught in the situation of having to fork someone else’s library, wait for them to catch up, or hope that they’ll accept your pull request. I won’t go in to the pros and cons of third-party dependencies here, but an architectural dependency has even more “gotchas” than a normal dependency, because of the way it can underpin your entire app.

Each step of the way, you may be celebrating that your code is clean and concise. However, you drift further and further away from what the system frameworks are providing, which means adopting new systems features requires more code to bring it to where you are.

Wouldn’t it be nice if you could just get it for free? Wouldn’t it be awesome if you could just use UIKit and AppKit and have it all “just work”? Wouldn’t it be nice to live in a world where you thought 300 lines in a view controller was excessively long?

In the next post, we’ll look at how we can fix the first problem.

Keynote’s awesome Outline Mode

So, I love It’s one of my all-time favorite apps. During my time at Apple, I got to use the app a lot and was constantly amazed by how powerful and capable it is. I grew very used to its precision and elegance, and its overall ease-of-use.

One of the really cool tricks I learned about Keynote was to quickly build slides using Outline Mode, like so:

Keynote Outline Mode

Outline mode is a powerful way to build slides, because it allows you to focus on the structure and flow of your content, without getting distracted too much by the visual aspect. In the early phases of building a deck, this is really important.

However… the visual aspect is still there. There are these huge slides sitting right next to your outline and you cannot make them go away. It is really easy to get distracted from what you’re doing and start focusing on text alignment, font sizes, animations, slide styles, and so on.

This morning I had the idea of “well, what about other outline modes, like the one in Pages?”. So I popped open Pages and started writing an outline and copied it to my pasteboard:

Building an outline in Pages

With this outline in hand (er, on my pasteboard), I headed back to Keynote and tried pasting it into the Outline view:

Paste an outline in to Keynote

A couple clicks to make sure the slides had the proper style (by reapplying the master style to the slides), and I had generated an entire presentation in a matter of seconds. At this point, with an outline built, I can easily create my Keynote presentation and start polishing it and adding in all the visual fanciness.

If you build presentations but get distracted by the slides, this could make your life a whole lot easier.

iOS Feature Wish: Contact Provider Extensions

For a while now, there’s been a major feature of iOS Contacts that I’ve felt has been sorely lacking, and that’s the ability for third-parties to provide their own contact card data. Here’s what I mean…

We live in a world where we have a whole bunch of different social circles that we run in, and it seems like almost every circle has a different way of keeping track of how to communicate with those people. I’ve got Twitter, LinkedIn, Snapchat, and Facebook. I’ve got a company directory, my account, and even an app for congregants of a nearby church.

None of these people show up in, and that really bothers me.

Sometimes I want to call someone, but I can’t just go to the phone app and start typing their name. I have to remember how I know them, go to the relevant social networking app, hope my credentials are still valid, find their info, and hope there’s a phone number in there.

Sometimes I want to text or email someone, but I can’t just go to Messages or Mail and start typing their name. I have to remember how I know them, go to the relevant social networking app, hope my credentials are still valid, find their info, and hope there’s a phone number or email address in there.

I really wish iOS offered a way for these apps (Facebook, Next Door, Twitter, LinkedIn, etc) to “donate” their contact information to the system database in a non-permanent way. (By “non-permanent” I mean “don’t just dump it in to my iCloud contacts and call it good”; deleting the app would cause that info to disappear, and the app could update it on-demand) There would need to be some pretty intelligent merging that happens, but generally it’s pretty safe to assume that an individual with a certain phone number and email address is probably the same individual as another with the same phone number and email address. You’d also have to consider how to handle apps that provide unboundedly-large data sets (like the corporate directory for a 50,000+ employee company). But, these are solvable problems.

Functionality like this would also enable what I consider to be the “holy grail” of contact services: a service where I can expose a certain subset of my contact information to specific groups of people. Facebook kind of lets you do this with your profile, but also carries a whole lot of extra baggage that a lot of people find undesirable.

In my opinion, the days of manually filling out and sharing vCards belong firmly in the past, yet that is just about the “state of the art” today. We have the technology to make far superior services, but just need a way to integrate that with the standard iOS (and macOS) experience.


Despite my recently-ended employment at Apple, I have zero idea of whether they have any plans to do this.

Also, I did file a bug report about this, but I do not have the bug number anymore. Please file your own copy! 🙏
Update: it’s been verified that my original bug report about this is rdar://17750541. Go forth and dupe!