indie iOS developer toolkit

Where do I start?

We’re frequently asked by fledgling developers, “where do I start?” and “what do I need?”. It’s a tough question to answer given everyone has different learning preference. That being said, we have come to realize that we send a pretty standard response. Whether our clients are interested in taking the plunge, our friends are curious about the inner workings of mobile software design, or the casual Reddit user asks for insight, we’ve found ourselves giving a similar response.

Well, okay then. What’s that response?

We’ll cut right to the chase. Our go-to list covers our favorite resources for the new indie (and cash-strapped) developer. We’ve personally used these tools and have grown so fond of them, that we still use a lot of them (in lieu of commercial grade software).

Our List

  • Learning Swift (or any other language, for that matter)iOS 13 & Swift 5 – The Complete iOS App Development Bootcamp by App Brewery on Udemy. We speak about this in our write-up on the perfect time to learn a new skill.
  • GitHub – This one is obvious, but we’d be remiss if we didn’t mention it. Get source control! While Xcode has a local repository, remote source control is imperative.
  • 2D graphics – We really like pixel art. It’s quick, easy to pick-up, and lightweight. We’d recommend starting your 2D graphics journey with one of the numerous apps on the App Store of your choice. We’ve had good experience with Pixel Studio.
  • 3D graphics – Just as we recommended pixel art for beginning graphics design, we’d recommend voxel art for 3D resources. Check out Magica Voxel to get started!
  • Text editors(-ish) – Thought we’d mention that we’re big fans of Atom for editing most text files (excluding Swift files). We also leverage PLIST Editor for working with property lists.
  • App Icon Generator – A nifty tool to convert your app icon to the required sizes.
  • GarageBand – The stock Apple app is perfect for creating your own loops and one-shot sounds. While it takes some time to master, you’ll be amazed by what you can generate quickly.
  • – In the event you’re not interested in learning a new (virtual) instrument. Splice has you covered. The 100% royalty-free for commercial use audio is great for DJs and app developers alike.

That’s not enough!

While having the right toolset certainly makes the job easier. You can’t accomplish much without a community. Be sure to find other like-minded folks who share your passion for development and design. Reddit is perfect for this. Indie Hackers is great too.

Similarly, marketing is everything! Don’t neglect graphic design. While advertising is out of scope for this article (stay tuned!), it can be incredibly helpful in sparking interest and getting your brand out there.

Finally, remember to pay it forward. Once you get going, you’ll pick it up quickly and will then share in the efforts to educate the newcomers.

What’re your favorite tools? We’re always eager to try out new things.

importance of documentation

Image by Ylanite Koppens from Pixabay

“Comment” on the journey

When was the last time you stopped to give pause and to reflect on where you’ve been and how you’ve arrived at the “now”? Yes, discipline in providing detailed code commentary and in crafting descriptive git commits is critical to the success of any coding project, however, that’s not what we’re getting at here.

While certainly analogous to project documentation, what we’re discussing here is keeping a written log of your journey. Whether you’re an aspiring business owner, established entrepreneur, or independent free lancer, you owe it to yourself to take inventory of your progress. Lessons learned are best recognized in written word. The power of writing has long been tied to an improvement in critical thinking skills.

Pick up a pen (or keyboard)

Where are you right now? How did you get here? What would you do differently or do the same? Answer tough, open-ended questions. Write until you’re exhausted – don’t worry about punctuation, spelling, or grammar. Focus instead on writing in a stream of consciousness fashion until you’ve expended all thoughts.

Start small. Reflect on the past day or the past week. Describe deeply how you’re feeling in the moment. This is real history. Recording the progress you’ve made with regard to assessing your feelings of doubt, motivation, failure, and success is a key, leading indicator of future performance.

Pick up a pen or sit down at a keyboard. Start writing for 15 minutes. Do this daily. Build the habit of reflecting.

Write for you

Write for yourself. This doesn’t have to be shared. Give an honest assessment of your progress toward your goals. To be honest, you don’t even need to reread what you’ve written. We’d argue that the process is more important than the content.

That being said, sharing your insights is invaluable. Whether you’re sharing them with friends or writing to the vastness of the web, your unique insights and experiences are bound to resonate with an audience. Think of how differently our professional experiences would be if more wrote about their often-deemed “mundane” jobs (improperly categorized as such). Sharing personal reflections of daily learnings and observations in the workplace is invaluable to students (and we’re all students regardless of life stage).

Questions to ponder

We’ll finish by leaving you with a handful of questions to spur thought. Don’t feel pressured to answer every question. Create your own. Again this is more about exhausting your stream of consciousness and less about content.

  • What have I accomplished today (“nothing” is also an answer)?
  • How do I feel about what I’ve accomplished?
  • What decisions would I change if I had the chance?
  • What do I think would be the results if I had the opportunity to change those decisions?
  • What did I learn in the process?
  • What do I want to work toward?
  • How do I feel about my decisions and my path going forward?

We hope that you’ll take the time at the conclusion of this article to reflect on the previous day. While we obviously can’t force you to make a habit of it, we’re hopeful that you’ll entertain the idea.

graphic design for the new indie developer

Image by Lukas Bieri from Pixabay

Coding is the easy part

If we’re honest with ourselves, we’ll admit that coding most software is much easier than the more creative aspects. How many of us seem to effortlessly implement new features, but neglect the user interface and interaction? We’ve definitely fallen into that trap. Even more, as programmers, we tend to devote a disproportionate amount of time to writing code, testing, and fixing bugs than we do to streamlining the interface and creating graphics.

We’d argue that in many cases, taking the time to draft out the user interface and design can eliminate many of the tedious coding tasks that we find ourselves in. We can even do away with the late-night hours developing a complicated feature that wouldn’t even be necessary with intuitive and beautiful design.

It’s hard to be creative

We’ll be the first to admit that we’ll find ourselves neglecting graphic design. In fact, many of our clients are interested more in implementing their grand functional vision (especially when it comes to internal, enterprise applications).

It’s funny because all we hear is the now, almost old adage “marketing is everything”, however, we tend to totally throw it out the window when it comes to execution. We totally get it though. In our case, when we first started out, we were only technically savvy. We didn’t even know how to design graphics for our games and our interfaces. It’s an intimidating task.

Getting started with design

Our recommendation to the indie developer (more specifically, the indie game developer), is to dip your toes into pixel art. It’s a friendly introduction to graphic design and it goes a long way to making your applications look polished.

Backgrounds, buttons, and even animations are incredibly easy to whip up in no time. We’ve always been intimidated by the professional graphic design software. The cost and the learning curve is high (and subjective). But like most other skills, devoting the time (and building habits) will reap rewards (e.g. more app downloads!).

Take a break from coding and start designing

To wrap up, after finishing this article (and sharing it!), jump on the App Store of your choice and download one of the pixel art apps. Stop neglecting what you’ve put aside for tomorrow and start designing basic graphics. Even the most simple design will improve the look, feel, and ease of use.

We’ve used Pixel Studio on iOS extensively. And while it’s notoriously clunky, the results are excellent. Anyway, we’ll let you get to it!

If you like this article, please comment below! Any and all feedback is greatly appreciate. Stay tuned for another simple (no-BS) write-up on app wire-framing and UX design!

swift 5: gamekit leaderboard

Games on the Apple App Store are abundant. We all know this. That’s why it’s imperative to put on your competitive hat and face the action (a little marketing never hurt also). What better way than to introduce some social dynamics to your game via a competitive leaderboard?

We’ve been busy developing a new game and find it incredibly easy to implement basic social functionality using the native Apple Game Center (with GameKit). Most games use this to some extent, so we wanted to share with you all a quick way to implement a GameKit leaderboard.

For reference, GameKit is the framework that allows us to interact with Apple Game Center. You can read more about it in the Apple Developer Documentation.

Before we get started, we wanted to outline the steps at a high level:

  1. Enable GameKit in your Xcode project
  2. Create a Leaderboard Identifier on App Store Connect
  3. Write some code to read and write to Game Center

Very straightforward. Let’s dive right in.

Enable GameKit in your Xcode project

Start by opening your application and verifying the bundle identifier. To enable GameKit, all that’s required is to click the ‘+ Capability’ button on your target. The steps are illustrated in the image below.

That’s it. Your application is set. Let’s set up the leaderboard in your App Store Connect account.

Create a Leaderboard Identifier

The next step is to create a unique leaderboard on your App Store Connect account. Go through the process of creating an app. Once finished, navigate to the Game Center tab under Features. Click the ‘+’ next to Leaderboard, select a single leaderboard, and populate the required information. We use the com.companyname.appname naming convention for our in-app purchases and Game Center content. Make note of the leaderboard ID as we’ll need to reference it when querying from our application.

Write the Code

The final step is to implement the necessary lines of code. What we want to accomplish:

  1. Authenticate the user with Game Center – Apple suggests we do this immediately
  2. Track a scoring metric and posting the high score – we need to track something (we’ll use a high score for this example)
  3. Load the leaderboard – we need a way to display the leaderboard results

It’s not too difficult to implement, however, there are a few hiccups that can occur along the way, which we’ll discuss below.

Authenticate the user with Game Center

Let’s start by authenticating the user when our root view controller’s view did load.

class GameViewController: UIViewController {
override func viewDidLoad() {

    func authenticatePlayer() {
        if SWGameManager.sharedGameDataManager.gameCenterDisabled == true {
        let localPlayer = GKLocalPlayer.local
        localPlayer.authenticateHandler = { (viewController, error) -> Void in
            if ( viewController != nil ) {
                self.present(viewController!, animated: true, completion: nil)
            } else if GKLocalPlayer.local.isAuthenticated == true {
                SWGameManager.sharedGameDataManager.gameCenterDisabled = false
                print("Player is authenticated!")
            } else {
                SWGameManager.sharedGameDataManager.gameCenterDisabled = true

This is all the code it takes to authorize a user. The SWGameManager code manages additional app-specific metrics (game mechanics, etc), however, the gameCenterDisabled property is one we’d recommend. For whatever reason, if a user declines to log in to Game Center multiple times, the authenticateHandler method won’t be called anymore. This requires the user to go into their general settings and enable Game Center manually. We track this with a flag and then notify the user if their Game Center is disabled.

Track a scoring metric and posting the high score

If you’re developing a game, then chances are you’re tracking some sort of score. When it comes time to sending the score to Game Center, then you’ll need to implement some variation of the following code:

    func postHighScoreToLeaderboard() {
        if GKLocalPlayer.local.isAuthenticated {
            print("\n Success! Sending highscore of \(score) to leaderboard")
            let scoreReporter = GKScore(leaderboardIdentifier: Constants.kGameKitLeaderboardID)
            scoreReporter.value = Int64(SWGameManager.sharedGameDataManager.highscore)
            let scoreArray: [GKScore] = [scoreReporter]
   { (error) in
                if error != nil {
                    print("An error has occurred:")
                    print("\n \(error!) \n")
                } else {
        } else {

What we’re doing here is:

  • Verifying that the user is authenticated
  • Creating a score object using our leaderboard identifier (the same one we used to create the leaderboard on App Store Connect)
  • Reporting the score and handling the output

We rely on delegate methods to handle the different outcomes (the functions labeled self.delegate?). These aren’t necessary but are definitely convenient.

Load the Leaderboard

Finally, it’s time to display the leaderboard. This is incredibly straightforward. All that’s required is to use the following code and implement the required delegate method.

    // Present the leaderboard scene
    func presentHighScoreLeaderboard() {
        if SWGameManager.sharedGameDataManager.gameCenterDisabled == true {
        } else {
            let leaderViewController = GKGameCenterViewController()
             leaderViewController.gameCenterDelegate = self // Make sure to implement the delegate method
             leaderViewController.leaderboardIdentifier = Constants.kGameKitLeaderboardID
   , sender: self)

Wrap up

That should do it. Now use a sandbox Apple ID to debug! While this was a relatively simple exercise, Game Center is much more powerful (e.g. tracking player achievements, sharing leaderboards, etc). Check out the Apple Developer Documentation for more information and stay tuned for additional write-ups!