How Blither uses the coordinator pattern and SwiftUI together

I never have enough time to work on the games that I make. So when I am working on them, I want to stay focused on the game screen, and spend as little time as possible writing the other boring (but still necessary!) screens for the App. Apple’s SwiftUI framework is very easy to use, and if you don’t much care about making things pixel-perfect, it can sure save a lot of time.

I am not yet convinced that SwiftUI is all that great at navigation, however. I feel like I only just got used to coordinators in UIKit (admittedly many years ago now), and maybe I’m still in the honeymoon stage with them or something.

So for my latest game, Blither, and somewhat by extension this open source Hexagon Grid Generator that I released, I’m using SwiftUI for all the straightforward UI, SpriteKit for the “interesting” views (game and grid), and UIKit mostly just for its UIViewControllers.

In Blither, I have a single UINavigationViewController, and a class named AppCoordinator that manages the navigation stack. It looks like this:

public final class AppCoordinator {

    public enum Route: Int {
        case about
        case appIcon
        case back
        case game
        case mainMenu
        case newGameConfig
        case options
        case rules
        case stats
    }

    public let navigationController: UINavigationController = {
        let controller = UINavigationController()
        return controller
    }()

    public func navigate(to route: Route) {
        if let presented = navigationController.presentedViewController {
            presented.dismiss(animated: true)
        }
        switch route {
        case .about:
            let viewController = AboutViewController()
            navigationController.pushViewController(viewController, animated: true)
        case .appIcon:
            let viewController = AppIconSceneViewController()
            navigationController.pushViewController(viewController, animated: true)
        case .back:
            navigationController.popViewController(animated: true)
        case .game:
            if let topVC = navigationController.topViewController, topVC is GameViewController {
                // already showing the GameViewController, so pop first
                navigationController.popViewController(animated: true)
            }
            let gameViewController = GameViewController(coordinator: self)
            navigationController.pushViewController(gameViewController, animated: true)
        case .mainMenu:
            if let topVC = navigationController.topViewController, topVC is MenuViewController {
                return // already showing the MenuViewController
            }
            let menuViewController = MenuViewController(coordinator: self)
            navigationController.pushViewController(menuViewController, animated: true)
        case .newGameConfig:
            let configVC = PlayerConfigurationViewController(coordinator: self)
            navigationController.present(configVC, animated: true)
        case .options:
            let viewController = OptionsViewController(coordinator: self)
            navigationController.pushViewController(viewController, animated: true)
        case .rules:
            let rulesViewController = RulesViewController(coordinator: self)
            navigationController.pushViewController(rulesViewController, animated: true)
        case .stats:
            let viewController = StatsViewController(coordinator: self)
            navigationController.pushViewController(viewController, animated: true)
        }
    }
}

That may look like a lot, but if you look closely, almost every switch case is the same. The AppCoordinator instance is created in the app delegate’s standard didFinishLaunching function:

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

    /// The root coordinator for the app.
    var appCoordinator: AppCoordinator?

    /// The main window
    var window: UIWindow?

    func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {

        let window = UIWindow(frame: UIScreen.main.bounds)

        let appCoordinator = AppCoordinator()
        self.appCoordinator = appCoordinator

        window.rootViewController = appCoordinator.navigationController
        window.makeKeyAndVisible()
        self.window = window

        Blither.setup()

        appCoordinator.navigate(to: .mainMenu)

        return true
    }
}

All of those View Controllers getting created in the AppCoordinator are UIHostingController subclasses, and look almost exactly like this one for the main menu:

public final class MenuViewController: UIHostingController<MenuView> {

    private weak var coordinator: AppCoordinator?

    init(coordinator: AppCoordinator? = nil) {
        self.coordinator = coordinator
        let menuView = MenuView(coordinator: coordinator)
        super.init(rootView: menuView)
    }

    @MainActor required dynamic init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

If you’ve worked with SwiftUI and UIKit together before, you’ll recognize the UIHostingController, but even if you haven’t, all you really need to know is that MenuView is a standard SwiftUI View, meaning it’s dramatically fewer lines of code to add something like a button. And because it also holds a reference to the AppCoordinator, the definition for a button can look like this one:

                Button("Read the Rules", action: {
                    coordinator?.navigate(to: .rules)
                })

When that’s tapped, the coordinator pushes the RulesViewController onto the stack.

If I wanted, I could get rid of the coordinator reference, and do something like this:

                Button("Read the Rules", action: {
                    (UIApplication.shared.delegate as? AppDelegate)?
                        .appCoordinator?.navigate(to: .rules)
                })

…but I don’t like how that looks quite as much, and it also closes the door on dependency injection.

Hopefully you can appreciate how simple this all is! I’ve been pretty happy with how easy I found it to create new screens using this framework. Let me know in the comments or over on mastadon if you have done something similar, as I’d love to hear about similar approaches.

Xcode tips and keyboard shortcuts

I love working in Xcode. It was my first “real” IDE experience, and while I still use vim pretty regularly it’s generally not for editing code (anymore). These days, whenever I’m not working in Xcode (lately it’s almost always Visual Studio on Unity projects), I’m wishing I was.

I read iOS Dev Weekly (https://iosdevweekly.com/) most weeks, and it was via that lovely resource that I discovered this great GitHub page full of Xcode-Tips (https://xcode-tips.github.io/). I already helped include one tip there (about enabling spell-check), and this post is inspired by one of the tips I found there in particular, about using `cmd-shift-j`. 

Xcode is a 3 panel layout. The middle panel where you actually edit code can be split up in a number of ways, (tabs within tabs? c’mon), but I won’t go into that in this post.

The left panel is called the “Navigator”. It has tabs across the top and defaults to the first tab, or “Project Navigator”, showing all the files in your project hierarchy. 

  • Filesystem tip/aside: When I first started using Xcode I was surprised to learn that files presented here are not necessarily 1-to-1 with the files on the filesystem. On one of my current projects, we are using the awesome open source XcodeGen (https://github.com/yonaskolb/XcodeGen) to generate the project from files on the filesystem. It’s actually called from a script that we run from a git checkout-hook, so we almost never have to think about it. This was a new-to-me workflow, but has a lot of benefits, including keeping the project files consistent with the filesystem!

Keyboard shortcuts relevant to the navigator:

  • Hide (or show) the whole Navigator pane with `cmd-0`. (That’s a zero.)
  • Jump to any of the tabs in the navigator with `cmd-<number>` where number is the index of the tab. So `cmd-1` opens the Project Navigator. This works even when the Navigator is hidden!
  • Best of all, the aforementioned `cmd-shift-j` will open the Project Navigator and select the file you are currently editing. You can then use the up or down arrows to browse different files, and `cmd-j` and then `enter` to return to the code editor.

The panel on the right side of Xcode is the Inspector. It too has tabs, and what’s great is that the keyboard shortcuts are very similar to the ones for the Navigator, but with the addition of alt:

  • Show/Hide the Inspector with `cmd-alt-0`.
  • You can also jump to one of the tabs with `cmd-alt-<number>`, again, where number is the index of the tab. What’s interesting here is that there are a different number of tabs here if you are editing an interface builder file. (I don’t think I’ve ever used these shortcuts.)

In general, I am far more likely to want to hide the Inspector pane than the Navigator pane, so it’s kind of a shame the shortcuts to show/hide them aren’t reversed (not to mention the fact that cmd-alt is a difficult combination on my Moonlander keyboard, but of course I could fix that).

I wrote this up in part so I can create another PR and reference myself as the source for a tip about showing and hiding these panes, but this post was also inspired by sharing with another member of my team that I do the majority of my development on a MacBook, without external monitor. <insert scream emoji> One of the aspects that makes that experience tolerable are all these keyboard shortcuts that let you maximize the space you’re using to edit code quickly and easily.

I hope you learned something from this, but if you didn’t, go check out that Xcode-Tips site, because you’re sure to learn something there!

iOS Updates and version numbers

First of all, the update to Catchup I mentioned a while back is finally live in the app store today! This got hung up a bit because Nick wanted me to make the new catchup rule the default. I told him I would definitely do this if he would handle translations of the rules update. (But of course wrangling a bunch of translators is much more difficult than the few lines of C++ needed to make the rule change itself!) So as of this writing, the rules change is still optional (and off by default). If and/or when we get some translated rules, I’ll probably push out another update to flip the default.

I’m also working on updates to some of my other apps. Unfortunately, it’s not really a straight-forward process, and there are some that will still probably not get an update at all. (Action Chess, for instance, just needs to be entirely re-written, which I’ve pretty much decided I’ll just do in Unity rather than go for iOS native.)

But in all the apps I’ve done so far, one thing I’ve had to do is change the code that shows the version number. I thought I’d write a mini-tutorial because this is kinda dumb. In pretty much all my apps, I previously had this block of code somewhere (usually in an AboutViewController class’s ViewDidLoad or ViewWillAppear method):

[self.versionLabel setText:[NSString stringWithFormat:@"v%@", [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"]]];

…but now I’ve changed it to the following:

[self.versionLabel setText:[NSString stringWithFormat:@"v%@.b%@", [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"], [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"]]];

This results in a version number that looks something like v1.4.b2.

(It’s worth noting that I highly recommend putting a user-facing build number in your all your apps somewhere. This is super important for getting bug reports and feedback. The technique above allows your code to update that user-facing number without having to include it in your code directly.)

In case it’s not clear, self.versionLabel is a UILabel instance, either initialized in code elsewhere, or (more likely) in a Xib or StoryBoard.

Anyway, Apple put out a technical note about version numbers and build numbers back in 2015, but somehow I missed it. Now I’m not 100% sure about this (possible it’s just that I was always confused about this), but my theory is that, at some point (maybe around 2015), the CFBundleVersion key changed functionality, from the version number to build number, and the CFBundleShortVersionString was introduced as the new version number. (This is really difficult to google for, I tried, so if anyone has a more accurate historical rundown, I’d be interested in hearing it.) Anyway, both string are required, but the build number is specific to the version number. (I.E. both have to increment for actual releases, but if you bump the version, you can reset build number back to 0 or 1, or whatever.)

These values are changed in Xcode, in the general project settings. Worth noting that the version number is shown to the user in the app store, but I don’t think build number is exposed anywhere (that I’ve seen). I usually try to follow semantic versioning, with the actual version number containing the first two dots (major and minor version changes), and more or less use the build number as the third “patch” number.

I guess the thing I find the weirdest about these bundle keys is that neither one is named “build”. And I would expect the build number to be the shorter one, not the version number. But maybe that’s just me! Hope this helps someone.

Protocols all the way down

As a programmer, one of the things I like to argue against is the concept of “magic code”, code that works because of some unseen bit of code elsewhere. In iOS, the principal is exemplified by “magic” methods you can include in various subclasses that do rather important things. Want to handle touches in your UIView? Just implement the method touchesBegan:withEvent:, touchesMoved:withEvent:, touchesEnded:withEvent:, and touchesCanceled:withEvent:, and you’re good to go. Want to set up your UIViewController‘s visual layout? Make sure you do so in the layoutSubviews method.

But how do you know about all these magic methods? This is definitely one of the questions that I found the most difficult when I first began iOS development. Learning about all this magic is basically the same thing as learning iOS development. Knowing Apple’s APIs is how you develop iOS apps. Knowing their quirks is how you get to be an expert.

But if you’re just starting out, it’s important to know that most of these magic methods are (generally, not always, but generally) defined in a protocol. When an object conforms to a protocol, it basically says that it (or one of its subclasses) will implement some set of methods. Want to know what protocols UIViewController conforms to? In Objective-C, you would simply open up its header and check it out. (Of course, a protocol might be defined even further up the chain, in one of the headers for a class the view controller inherits from.)

But how do you figure out what protocols a class conforms to in Swift? As near as I can tell, the only way is to open up Apple’s documentation. This seems like it would not be enough, since you might be working with a non-apple framework, or worse… it is possible (gasp) for Apple’s documentation to be spotty or outright incorrect. (I’ve done a few google searches, and read about 20 tutorials and blog posts, and I still don’t know how to figure this out from code alone, so I’m really asking this question. I’ve also started a stack overflow question on the topic.)

I don’t want this to be a “I think Objective-C is superior to Swift” post, but I do think there are legitimate reasons for header files, and this is one of them. Once you get beyond a certain level of iOS proficiency, poking around in those header files is akin to using the “view source” as an intermediate web developer. It’s one of the ways you learn how other people approach a problem.

How to play the game Go

I tweeted this idea the other day:

Book idea: popular board game rules re-written with the 1000 most common words á la Randall Munroe’s Thing Explainer.

Go is one of the most elegant and simple games around, yet the rules are often misleadingly complex. So without further ado:

How to play the game Go

Go is played on an area made of 19 lines going one direction, and 19 lines crossing them going the other direction. Black places first, and then black and White take turns placing a piece of their color on a space where any of the lines of the game meet. Once placed, a piece may not be moved to a different space.

Any pieces of the same color next to each other form a group. Only pieces on spaces exactly next to one another (on the game lines) can make a group. A group can be as small as only one piece. Groups may be made larger by placing another piece next to any of the pieces already in the group.

If White puts pieces on ALL the spaces next to a Black group, white takes the black pieces in that group out of the game. Same for black. Those pieces become points for the player that took them.

No player can place a piece that would make the game look like it looked after their last turn.

After both pass, each player points out any pieces they will be taking from inside their groups. If the other player doesn’t agree, the player must keep playing to take them.

Each player adds a point from each taken piece, as well as a point for each of their pieces still in the game, and finally a point for each empty space surrounded by their own groups. The player with more points beats the other player.

Notes:

1. I wrote this using The Up-Goer 5 Text Editor.

2. Obviously this is missing some of the important strategies that are included in any decent set of Go rules. Additionally, most rules of Go are complicated quite a bit with terminology that is not actually important to play, but might be important if you want to actually talk with anyone about your game. This is not usually a barrier to playing if you have someone to teach you, but if you are trying to learn from rules, it can be unnecessarily frustrating.

Edited (2016-01-28)

3. Removed the suicide rule, which as Matt pointed out is not universally accepted. (Incidentally, Matt taught me to play go, way back in the day.) I originally wrote it: “Black can not place a piece so that White would take it without playing another piece. White can not place a piece so that Black could take it without playing another piece.”

4. Re-worked capture paragraph. Less verbose and simpler.

5. Added paragraph about passing, re-worked the last paragraph a bit to explicitly count all stones. This is more consistent with New Zealand rules, which seems sane.

6. Removed “That’s it.” from the end. That was just silly.

Q&A – Porting Board Games to Digital

I recently answered a short barrage of questions by some non-technical folks researching the business feasibility of board game conversion. Since I gave them these answers freely, I thought I would also post them here. This is all based on my own personal experience, so feel free to exercise skepticism and I absolutely welcome your thoughts or differing opinions in the comments below.

1. What resources estimates and how much time do you feel is needed to do a strategy board game conversion to digital?

The answers for this question are as varied as the answers to the question “how much time is needed to do a mobile game?” In my experience, if you’re paying your programmer(s) what they’re worth (which is not a given in the gaming industry), you’re probably looking at a budget somewhere between 30k and 120k. Less is certainly possible with an experienced team, maybe with a code base they’re reusing, but it would raise a red flag for me. (I get a lot of potential clients who come to me with 2-5k, and I politely tell them that we can possibly make a prototype without graphics for that much.)

2. If using Unity as a gaming language, what do you think is involved in porting to another platform say from iOS to Android or vice-versa?

I am familiar with unity, but no expert. (So take this with a grain of salt.) My feeling is that android is more work, what with supporting all the different screen sizes and hardware/processor idiosyncrasies, so if you’ve already done that work, porting to iOS should not be that much more difficult. (Depending on the project, of course.) Going from iOS to android on the other hand could take longer, especially for complex games. (It’s going to depend on how many screens or “scenes” you’ve got to prepare in unity.)

3. Are you aware of what the maintenance/support costs would/could be, if so what do you believe is involved?

This is a great question! Not something a lot of clients think to ask. It’s easy to throw something in the App Store and forget about it, which is exactly what everyone else will do too.

There are obviously diminishing returns though, so I recommend planning a release with at least one maintenance update about a week or so after the initial lunch, and maybe evaluate then whether it’s worth doing another “feature” update a couple of weeks to a month later, also with a follow up maintenance update if your budget can stand it. If the game is still doing well at that point, it’s a good idea to plan to spend some time and push out littler updates as frequently as you can, more for marketing purposes than for any development related reason. All of this will require developer involvement, but it’s the person crafting marketing and messaging that should be spending the most time after launch. I generally think this is underestimated, and can easily be a full-time task.

4. Do you have an idea of hosting (storage/bandwidth) costs?

This is only relevant if you are hosting your own server for some reason. The game should have a website, which is another often overlooked marketing piece, but it will cost far more to create that than to maintain/host it. (Hosting fees shouldn’t run more than $20/ month, or you’re probably getting ripped off somewhere. I pay $5/month + $10/domain, but that comes with doing mostly my own support.)

If you ARE hosting your own backend multiplayer server, you can think of it as another domain name. (It definitely cost you more up-front to develop, so make sure your dev is including that in their estimates.) And unless the game is super successful, most hosting plans should include enough bandwidth. If you get to the point where you are paying ala cart for bandwidth, it still shouldn’t be more than a handful of dollars unless you’re at an extreme end of the spectrum, which is a problem you wish you will have.

5. What’s your thoughts on the digitization of family board games, and what may happen, and when?

Well, “family board games” is a term that might mean a bunch of different things, but here are some initial off the cuff thoughts:

a) it’s already happening to some degree, see Monopoly, Scrabble, Jenga.

b) The family market is much larger than the hobby market, but much tougher to crack. Quality is going to be a very important consideration, as is ease of use and first-run experience, including tutorials and teaching.

c) It’s possible that the aforementioned digital game examples are mostly getting played by board game hobbyists, rather than the general populous you’d expect to be playing a family game, which would be hard to prove either way unless you are the publisher of one of those games.

d) In general, (this is advice I like to give to anybody thinking about physical game conversion), the advantage that board game conversions have over their fully-digital counterparts is that there is already a population that knows about that game and to a lesser extent how to play that game. So the bigger that group, the bigger your advantage. How successful your board game conversion will be is very much influenced or enhanced by how successful a game you are choosing to convert.

6. Are you familiar with Steam, and would you recommend porting or building for that platform?

If you want to target desktops (OSX, Windows, or Linux), then I would highly recommend building working with Steam. I cannot make a recommendation about whether those platforms are viable for board game conversions in particular. Steam is a bit like Apple’s App Store and Game Center rolled into one, but cross platform for desktop games. There is an API that you as a developer can write to, and implement Steam achievements and various other social offerings.

7. Do you feel the effort to port from say Android/iOS phones requires more work to port to Tablet versions as well, or not?

Generally there is a portion of every project devoted to UI work. The amount of time spent will be different for every project, but generally I think it’s a higher percentage of the project for games than other application types. Let’s say, for a game, 50% of the development effort was put toward UI work. If you had only developed for one screen size at that point, you might have to re-do or at least re-touch much of that work. If you plan from the beginning of the project for multiple screen sizes, you can save yourself a lot of pain in “porting” to a different screen size, but it is still more work, no doubt about that.

8. What about PC/Browser porting, are you noticing or see the need/demand or value in doing that, and if so are you familiar with the effort in that case let’s say after a mobile version has been completed?

I do see this happen from time to time, though not with a lot of board game conversions. My concern would be monetization, since the folks who play web-based games are used to getting their games for free, and you have to have a very large active userbase (in the hundreds of thousands, from what I understand, although I’m no expert) to make money with advertising alone.

9. How many people do you believe is needed to convert and maintain a board game digital conversion, and what roles?

For a “full featured” conversion, I see the following needs:
– Programmer/developer
– Artist/graphic designer
– Sound Effects person and Musician (often can be the same person)
– Some kind of project manager or person making feature decisions
– A person (or team!) in charge of marketing

I have worked on a lots of projects where there were a couple of developers who split duties. This includes several apps with Tysen Streib, who would expertly craft the AI and game logic, while I handled all the rest of the application, including ultimately integration of his code into the project.

Another optional role I’ve found myself filling briefly at the start of smaller projects is that of UX designer. It is always nice to have a blueprint to work from, and good wireframes can really speed up development as well as help keep your team on the same page if there are multiple developers.

The mix and makeup of all of these roles will be different on every team, no doubt. There are certainly some indie developers who tackle all of these tasks for every project! I’ve found that keeping scope small is always a good thing, work toward manageable milestones, and you’re less likely to be surprised by how long something takes you to complete.

NSNumber+XYCoordinates

So I occasionally have the problem where I want to store a bunch of x,y coordinates. I have solved this a number of ways in the past, but most recently had the idea of writing a category on NSNumber that simply stores two 16 bit integers, bitshifted together. So without further ado, here’s the github project for NSNumber+XYCoordinates.

My first version of this I couldn’t get negative numbers to work, but after some patient binary math explaining today at the coffee shop from my friend Matt, I finally got it to support numbers between -32767 and 32767.

Essentially, my category just adds the following methods:

NSNumber *xyNum = [NSNumber numberWithX:10 andY:10];
int x = [xyNum xValue];
int y = [xyNum yValue];

This seems to work pretty great, and is way less annoying than my previous favorite technique, which was to convert between NSString and CGPoint all the time.

So I got to thinking tonight… this should be fast, right? But I have no idea how fast, really, or how to compare it. So I wrote some test cases. Each of them assigns and then reads back out again some number of sequential integers using various techniques that I’ve used in the past. I compiled the following lists for different numbers of values:

100 Values
CGPointToNSString – size of 100 string objects in multidimensional array is 2263 (0.002 seconds).
NSDictionary – size of 100 objects in NSDictionary is 2413 (0.001 seconds).
NSSet – size of 100 objects in set is 1545 (0.004 seconds).
NSNumber+XYCoordinates – size of 100 objects in multi-dimensional array is 2033 (0.001 seconds).

10,000 Values
CGPointToNSString – size of 10000 string objects in multidimensional array is 241803 (0.162 seconds).
NSDictionary – size of 10000 objects in NSDictionary is 289593 (0.076 seconds).
NSSet – size of 10000 objects in set is 199798 (0.044 seconds).
NSNumber+XYCoordinates – size of 10000 objects in multi-dimensional array is 203503 (0.046 seconds).

1,000,000 Values
CGPointToNSString – size of 1000000 string objects in multidimensional array is 31702088 (10.187 seconds).
NSDictionary – size of 1000000 objects in NSDictionary is 38735561 (121.886 seconds).
NSSet – size of 1000000 objects in set is 25866828 (118.003 seconds).
NSNumber+XYCoordinates – size of 1000000 objects in multi-dimensional array is 25919832 (114.918 seconds).

You see that the technique compares favorably against CGPointToNSString, at 100 and 10,000 values, but somehow, the CGPointToNSString technique just blows it out of the water in terms of speed when we get to a million objects. (Still much smaller though.) I don’t fully understand this, but I guess maybe the C API is faster at high volumes? Let me know if you think you might have some insight!

How long does it take to make an AdHoc build?

An AdHoc build is how you get iOS apps onto an Apple device without going through the App Store. They are typically used for testing. I was asked this question recently, and spent 15 minutes writing up this reply, so I thought I’d post it here. The obvious caveat is that it can of course vary from project to project. A bigger more complex project has more “moving parts” that can need fiddling with when creating a build.

So… How long does it take to make an iOS AdHoc build?

I use TestFlight to distribute my AdHoc builds, and typically, I tell clients an AdHoc build takes between 15 and 30 minutes to complete. Thankfully this work “stacks” quite a bit, so doing a few of them at once might only take 20 or 30 minutes. This process basically just involves opening the project, verifying a few settings related to provisioning profiles and “targets”, building an “Archive” of the project, uploading the new build to TestFlight, and writing some release notes as well as picking the users to receive the build. (Thanks to the awesome TestFlight OSX app, those last two steps can be done while the upload is in progress.)

This assumes, however, that all the devices are already registered with TestFlight. Everything takes longer when I need to add additional devices. This stacks too, so adding 1 to 10 or 15 new devices only takes another 15 or 20 minutes. The main additional thing that I need to do in this case is upload the device identifiers for the new devices to Apple’s provisioning portal, and download a new (or updated) provisioning profile that includes those new devices. This additional work has to happen BEFORE I can make the AdHoc build for those devices.

What I find frustrating is when all these tasks are split up over the course of hours or days. For instance, when I’m asked to send a build to some new individual, but they’ve never used TestFlight, and aren’t yet registered there. Then I have to send them an invite, wait for them to accept the invite, wait again for them to register their device, then finally I can get their identifier and begin the process. This means either waiting for the new person before creating the build (sometimes this can take days, of course!), or just creating two builds, one with the devices I already have, and another when I get all the important information from the new person. Considering the adage that a “a 15 second interruption results in 15 minutes of programmer downtime” (which is more or less verifiable), these build requests can really add up to lost productivity for me.

One final note about what AdHoc builds are not.

After an app is in the app store, unless you are testing a new version, you should really be using that version, and not an AdHoc build. There are many reasons for this, but notably: 1) AdHoc builds will expire when the provisioning profile expires. 2) You get the peace of mind that what you are seeing is what your users are seeing. 3) You will get the updates via the app store, as your users do. 4) You can instal the app on multiple devices without needing to provision all of them. Don’t forget about using promo codes to get “free” versions of apps to your testers or employees after an app goes live! (In my experience, you rarely use all of them for press as you should, and you get a “fresh” batch after each update anyway.)

AdHoc builds are an integral part of iOS app development, but creating them is annoying to me because it’s not programming. Of course, neither is wring this blog post.

How to change the color of a transparent image in iOS

This is probably as good a time as any to mention the next project I’m working on. It’s a turn-based (yes, asynchronous) board game. I decided to work with an existing game, because I wanted it to be really awesome, but also really simple. It’s an abstract game that is well respected in some circles. (I’m not going to reveal which one just yet.) Anyway, I’m working closely with the game’s designer, as well as with the same AI programmer I worked with on For The Win. The main goal of the project is to get the async code really solid, so I can feel like I really understand how it works, and re-use it in future projects.

Anyway, I think I’m also going to try something I’ve wanted to do before, and that is implement a variable color scheme for the app. Essentially you’ll be able to change the app’s background color, and that will also programmatically change the color scheme. I spent about two hours and had the basic color change functionality working pretty great with some code based on an already pretty great open-source color picker.

Anyway, one tiny piece remained… I would need to be able to programmatically tint images I get from the designer on this project. He’s going to give me some icons and other assets that we’ll no doubt want to change colors along with the rest of the app.

Some unknown number of hours later, I’ve got a solution. The number of hours is probably around the same as the number of lines of code in the solution. Here are those lines, implemented in the drawRect: method of a UIView subclass with a UIImage property named image, and a UIColor property named colorToChangeInto.


CGContextRef context = UIGraphicsGetCurrentContext();

CGContextScaleCTM(context, 1, -1);
CGContextTranslateCTM(context, 0, -rect.size.height);

CGImageRef maskImage = [self.image CGImage];
CGContextClipToMask(context, rect, maskImage);

[_colorToChangeInto setFill];
CGContextFillRect(context, rect);

I hope this is fairly straight forward. These few lines stand on the backs of many stack overflow answers. (And I did actually write this up into a question of my own at some point.) None of the other answers were exactly what I needed, but several of them got me close. In the end, I was super frustrated because it really seemed like I should be seeing what I wanted to see, but the background of the image was black… turned out I was instantiating the image in IB (in a storyboard), but I hadn’t set the background color. Somehow that defaulted to black. That particular issue probably wasted me an hour or two.

And then writing this blog post… another half-hour, at least.