Larder Blog on Larder and related developery things.en-gbTue, 13 Oct 2020 04:38:08 -0000 What&#39;s in your Larder: Rust web frameworks <p>I&#39;ve long had my eye on Rust as a language to try out, and recently I&#39;ve been playing around with writing a web app and API in Rust. I picked Rocket as my framework, but as the Rust ecosystem is still early, there are a lot of options for frameworks. Each has their own strengths and weaknesses, and to me there&#39;s still no clear winner. I thought I&#39;d round up those worth looking at. I&#39;ve done my best to represent the frameworks accurately, but these are still qualitative assessments, so your opinion may differ :)</p> <h3><a >Rocket</a></h3> <p>Rocket is a framework in its teens &mdash; more developed than many of the others, but still not quite mature. Its special feature is its use of macros to annotate request handler functions with their routes and provide parameters and required data, such as valid deserialised forms, with a kind of dependency injection. Also, the docs are quite good, development is active, and along with Actix, this is one of the most commonly-used frameworks, so you benefit from increased community knowledge. Rocket requires a nightly version of Rust.</p> <h3><a >Actix-web</a></h3> <p>Actix-web is a framework built on Actix, an actor system for Rust. It hasn&#39;t been around as long as Rocket, but has gained features quite rapidly and is another community favourite. The unique actor approach means that separate components, like database access and background tasks, are each implemented as asynchronous actors that communicate to each other by message passing. Actix-web is probably best-known for appearing near the top of the TechEmpower <a >Web Framework Benchmarks</a>. Actix-web is under active development and has fairly thorough documentation.</p> <h3><a >Gotham</a></h3> <p>Gotham is an asynchronous web framework that I think has been around about as long as Rocket, but in less active development in 2018 as the original developers stepped away. I like its simple, explicit approach, but it could be considered a little verbose for some common tasks, and is falling behind the more popular frameworks lately in terms of features.</p> <h3><a >Tower-web</a></h3> <p>Tower-web is another approachable framework that aims to provide all the standard features. It&#39;s built on <a >Tower</a>, a library of network client/server components, meaning it should eventually gain &quot;batteries included&quot; status. It&#39;s also developed by one of the core contributors to Tokio, Rust&#39;s most popular asynchronous runtime library, which seems like a plus. Tower-web, like Rocket, uses macros to reduce boilerplate, but doesn&#39;t require nightly Rust. As it&#39;s quite new it&#39;s still missing features and much in the way of documentation, but is under active development.</p> <h3><a >Warp</a></h3> <p>Warp is a framework with the unique angle of composability, allowing you to chain together reusable &quot;filters&quot; for things like parameter extraction and required application state in order to build routes and request handlers. It&#39;s also quite new and light on documentation, but under active development. It has <a >a relationship with Tower-web</a> that isn&#39;t quite clear to me, but it seems like the developers know each other and may merge Warp and Tower-web as alternative APIs on top of a single framework in future.</p> <h3><a >Rouille</a></h3> <p>Rouille is a synchronous micro-framework that provides the building blocks of a web framework and leaves the rest to you. It&#39;s small and simple and doesn&#39;t have as much in the way of documentation, but does appear to be under active development.</p> <h3><a >Shio</a></h3> <p>Shio is an asynchronous micro-framework that has a lot in common with Rouille. It doesn&#39;t seem to get a lot of active development and doesn&#39;t have a lot in the way of documentation, although it does have some examples.</p> <h3><a >Nickel</a></h3> <p>Nickel is a lightweight framework inspired by the Express JavaScript framework. It was one of the first frameworks to appear for Rust and still sees some maintenance, but doesn&#39;t appear to be under active development. Its documentation is pretty sparse.</p> <h3><a >Rustful</a></h3> <p>Rustful is another micro-framework. It doesn&#39;t seem to see much active development, but I&#39;ve included it here in case it looks like your thing.</p> <h3>Bonus: <a >Yew</a> (Front-end)</h3> <p>Yew takes advantage of Rust&#39;s ability to compile to WebAssembly to provide a front-end framework inspired by Elm and React. I&#39;ve not looked at it in detail but it seems like it has good interop with JavaScript and is mature enough to take for a spin. It doesn&#39;t have a lot of docs but does have many examples, and is under active development.</p> <h3>Bonus: <a >Diesel</a> (ORM)</h3> <p>Diesel is the de-facto ORM solution for Rust. It supports migrations, schema generation, and has a nice query building DSL. I had issues using it with MySQL in the past, and it seems like Postgres is the favoured database (fair enough), but development is active and my issue was resolved not long after.</p> What&#39;s in your Larder: Libraries for Kotlin Android development <p>I&#39;ve recently started exploring Android development in Kotlin, and I&#39;ve been enjoying it a lot. Coming from Swift, Kotlin has a lot of really similar syntax, which is helpful. I&#39;m brand new to Android development, so there are probably lots more useful libraries I haven&#39;t had a chance to explore yet, but these are some that I&#39;ve saved to my Larder account that I&#39;ve already found useful, or am planning on trying out soon.</p> <h3><a >Kovenant</a></h3> <p>Kovenant is a promises library for Kotlin. I use <a >PromiseKit</a> in most of my iOS projects these days, so I wanted to find something I could rely on for using promises in Android. Kovenant seems to cover most of the use-cases I need (I haven&#39;t found an equivalent to PromiseKit&#39;s <code>recover</code> function yet, but that&#39;s the only gap I&#39;ve noticed), and it&#39;s really nice to use.</p> <h3><a >Picasso</a></h3> <p>If you handle downloading and displaying images at all, Picasso makes this super easy. As well as handling asynchronous downloading and caching of images, you can add transformations, like so:</p> <p><code>Picasso.get().load(url).resize(50, 50).centerCrop().into(imageView)</code></p> <p>I also use this <a >picasso-transformations</a> library to make it easy to add extra transformations to Picasso, such as cropping to a circle shape.</p> <p>For what it&#39;s worth, I recently found out Google recommends <a >Glide</a> for handling image loading, rather than Picasso. I haven&#39;t tried Glide yet, but considering Google also recommends Volley for networking, which has barely any docs and some really strange bugs, I&#39;m not sure how much I&#39;d trust that recommendation.</p> <h3><a >DressCode</a></h3> <p>I haven&#39;t tried this Kotlin library yet, but it offers an easy way to add theming to your app, which I&#39;ve never tried before. I&#39;m keen to give this a go when I need to add theming options for an app in future.</p> <h3><a >Anko</a></h3> <p>I saw Anko mentioned all over the place for a while before I dug into what it is and why everyone loves it. Anko is basically a collection of convenience methods to make Android development in Kotlin easier and more succinct. It has some really great stuff, like this super-succinct method for creating and showing a toast:</p> <p><code>toast(&quot;Hi there!&quot;)</code></p> <p>And for a SnackBar:</p> <p><code>longSnackbar(view, &quot;Wow, such duration&quot;)</code></p> <p>It also makes creating intents a lot more simple, for example:</p> <p><code>startActivity&lt;SomeOtherActivity&gt;(&quot;id&quot; to 5)</code></p> <p>And there are built-in convenience methods for common intents, like <code>browse(url)</code> and <code>share(text, [subject])</code>.</p> <p>I haven&#39;t tried it yet, but Anko also offers a nice-looking DSL for creating layouts. Here&#39;s an example from the docs:</p> <pre> <code>verticalLayout { val name = editText() button(&quot;Say Hello&quot;) { onClick { toast(&quot;Hello, ${name.text}!&quot;) } } } </code></pre> <p>There&#39;s lots of other stuff, too, so Anko is definitely worth a look.</p> <h3><a >Fuel</a></h3> <p>After dealing with the weird bugs and lack of docs for Volley, I stumbled across Fuel, which is now my favourite networking library for Android. Fuel uses lambdas for handling responses, rather than requiring listeners. Coming from iOS, this feels more familiar to me. It also works great with Kovenant, if you want to wrap your networking in promises, which I always do.</p> <h3><a >Forge</a></h3> <p>I haven&#39;t needed to use a library for JSON parsing yet, but I&#39;m planning on trying Forge when I do. It&#39;s written by the same developer who&#39;s behind Fuel, and seems nice and simple to use.</p> <h3><a >Result</a></h3> <p>I&#39;m a bit late to the party with Result types, but I&#39;ve just started exploring them in iOS, so I&#39;m happy to have found this library for Result types in Kotlin. The README for this project offers a nice example of how Result types can be used to improve our code, too.</p> What&#39;s in your Larder: iOS testing frameworks <p>One of the main things I&#39;ve focused on in 2018 has been adding tests to my iOS apps. I&#39;ve fumbled my way from having no tests at all in a fairly big, one-person project, to refactoring code to be testable, and even using TDD to develop new features. Along the way I&#39;ve tried many testing frameworks. Here are some that I&#39;ve had the most experience with, and why I do or don&#39;t like them.</p> <h3><a >Quick</a></h3> <p>Quick is a popular BDD (behaviour-driven development) testing framework. It helps you structure your tests in a way that I found appealing at first, but ultimately moved away from.</p> <p>Because Quick wraps <code>XCTest</code> under the hood, it sometimes <a >behaves in unexpected ways</a>, and I had trouble writing my Quick tests in a way that let me share code and use helper functions between different tests. I&#39;m sure this is possible&mdash;it just wasn&#39;t simple or obvious enough for me to stick with Quick.</p> <p>I also had a lot of trouble getting Quick to work with EarlGrey or Sencha (mentioned below), and I think that&#39;s because they both extend <code>XCTestCase</code> so I was essentially putting one test case inside another.</p> <h3><a >Nimble</a></h3> <p>Nimble is made by the same team as Quick, and I&#39;m still using it in most of my tests, even without Quick. Nimble is a matching framework to help you write more readable expectations. Though this might seem like overkill, it makes writing tests much nicer, and I found the syntax easy to pick up.</p> <p>Here&#39;s an example of a simple <code>XCTest</code> assertion:</p> <p><code>XCTAssertEqual(1 + 1, 2, &quot;expected one plus one to equal two&quot;)</code></p> <p>And here are some examples of how you might write assertions with Nimble, taken from the README:</p> <pre> <code>expect(seagull.squawk).to(equal(&quot;Squee!&quot;)) expect(seagull.squawk).toNot(equal(&quot;Oh, hello there!&quot;)) expect(classObject).to(beAKindOf(SomeProtocol.self)) expect(actual) == expected expect(actual).to(beGreaterThan(expected)) expect(actual) &gt;= expected expect { try somethingThatThrows() }.to(throwError()) expect(actual).to(beEmpty()) </code></pre> <p>Anyway, you get the idea. There are lots, lots more supported assertion types in Nimble. Check the project&#39;s README for lots of examples.</p> <h2><a >Nimble Snapshots</a></h2> <p>I try to avoid snapshot tests, as I&#39;ve found them to be the most flaky variety of tests, especially when dealing with animated UIs. But when I do write snapshot tests, I use <code>Nimble_Snapshots</code> by Ash Furrow. This library is a wrapper around <code>FBSnapshotTestCase</code> formerly by Facebook and now maintained by Uber. It lets you use Nimble assertions to create and compare snapshots, so your assertion can look something like this:</p> <pre> <code>let view = ... // some view you want to test expect(view).to(haveValidSnapshot()) </code></pre> <p>If you&#39;re already using Quick and/or Nimble, it&#39;s really handy to be able to use snapshots without changing the style of your tests.</p> <h3><a >EarlGrey</a></h3> <p><code>EarlGrey</code> is a functional UI testing framework from Google. It lets you write and run UI tests like unit tests, and waits for things like animations to complete before checking for UI elements. <code>EarlGrey</code> is handy for interacting with your app as a user would, and testing that the UI looks and behaves as expected. You can scroll, swipe, and tap, as well as checking the visibility of labels, buttons, and other UI elements. The library supports both Objective-C and Swift, which is handy for mixed projects.</p> <p>Here are some examples of how you might use <code>EarlGrey</code> to interact with your app during tests:</p> <pre> <code>// perform a tap [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@&quot;ClickMe&quot;)] performAction:grey_tap()]; // assert something is visible [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@&quot;ClickMe&quot;)] assertWithMatcher:grey_sufficientlyVisible()]; // scroll down, then tap [[[EarlGrey selectElementWithMatcher:aButtonMatcher] usingSearchAction:grey_scrollInDirection(kGREYDirectionDown, 50) onElementWithMatcher:aScrollViewMatcher] performAction:grey_tap()]; </code></pre> <p>It&#39;s surprisingly fun to watch these tests run in the simulator, as it feels like watching someone use your app very quickly.</p> <p>There&#39;s also <a >EarlGreySnapshots</a> in case you want a snapshot testing wrapper to use alongside <code>EarlGrey</code> tests. It lets you write assertions like so:</p> <pre> <code> grey_kindOfClass(AViewToSnapshotClass.self)) .assert(grey_verifySnapshot()) </code></pre> <h3><a >Sencha</a></h3> <p><code>Sencha</code> is a wrapper around <code>EarlGrey</code> that gives it a nicer syntax to work with. It also offers handy convenience methods for opening view controllers and embedding them in navigation controllers, which I use a lot when setting up tests.</p> <p>Compared to <code>EarlGrey</code>, using <code>Sencha</code> is much nicer. Here are some examples of what it can do:</p> <pre> <code>tap(.accessibilityID(&quot;AnythingTappableID&quot;)) tap(.text(&quot;ButtonTitle&quot;)) type(&quot;Username&quot;, inElementWith: .accessibilityID(&quot;UsernameTextFieldID&quot;)) tapKeyboardReturnKey() assertNotVisible(.text(&quot;EmptyStateText&quot;)) assertVisible(.class(UIActivityIndicator.class)) assert(tableViewWith: .accessibilityID(&quot;TableViewID&quot;), hasRowCount: 30) assertSwitchIsOff(.accessibilityID(&quot;SwitchID&quot;)) </code></pre> <p>I use <code>Sencha</code> in all my UI testing these days and find it really handy, but it is limited, and I often have to use <code>EarlGrey</code> for things that aren&#39;t wrapped by <code>Sencha</code>, such as swiping.</p> <hr /> <p>Finally, here are some other testing frameworks I haven&#39;t tried that you might want to check out:</p> <ul> <li><a >KIF</a> (Keep It Functional&mdash;functional UI testing)</li> <li><a >Cedar</a> (BDD-style testing in Obj-C)</li> <li><a >Specta</a> (TDD/BDD framework in Obj-C)</li> <li><a >Snap.swift</a> (Snapshot testing alternative to <code>FBSnapshotTestCase</code>)</li> </ul> <p>Happy testing!</p> What&#39;s in your Larder: iOS layout DSLs <p>If you&#39;re using Auto Layout to write layouts in code for iOS, it can easily get tedious and verbose. DSLs (domain-specific languages) wrap the underlying APIs to make it easier and faster to read and write code. There are plenty of these for Auto Layout, and even a couple that support manual frame layouts, too.</p> <p>Here are some I&#39;ve come across that I&#39;ve added to my Larder (don&#39;t forget you can star repos on GitHub and have them automatically sync to your Larder account).</p> <h3><a >SnapKit</a> [Swift] &amp; <a >Masonry</a> [Objective-C]</h3> <p>I&#39;ve been using SnapKit for a while now, and Masonry before that. SnapKit is the Swift successor to Masonry, but both worth with similar ideas.</p> <p>SnapKit uses closures (Masonry uses blocks) and dot syntax to chain together auto layout constraint requirements. Here are some examples of how you might add constraints in SnapKit:</p> <pre> <code>view.addSubview(label) label.snp.makeConstraints { (make) in make.label.leading.bottom.equalToSuperview() // Label top == anotherView bottom + 12 make.width.equalToSuperview().dividedBy(2).labeled(&quot;label width&quot;) // Label width == view width / 2 } view.snp.makeConstraints { (make) in make.edges.equalToSuperview() // SnapKit offers some handy shortcuts like .edges and .size to constrain multiple attributes at once } </code></pre> <p>One thing I love about SnapKit is that you can chain <code>.labeled()</code> to give your constraint a name, which will show up in Xcode when your constraint conflict. It helps enormously to figure out which constraints are the problem and get your layouts working, but you don&#39;t need to create a reference to each constraint in order to give it an identifying label.</p> <h3><a >EasyPeasy</a> [Swift]</h3> <p>EasyPeasy offers a nice way to add multiple constraints to a view at once. With SnapKit, you can constrain different aspects of your view in the <em>same</em> way, e.g.: <code>view.leading.trailing.equalToSuperview()</code> but you can&#39;t chain together constraints for <code>leading</code> and <code>trailing</code> that are different.</p> <p>With EasyPeasy, you can do so like this:</p> <pre> <code>myView.easy.layout( Width(200), Height(120) ) </code></pre> <p>Another interesting aspect of EasyPeasy is the ability to add conditions to constraints like so:</p> <pre> <code>var isCenterAligned = true view.easy.layout( Top(10), Bottom(10), Width(250), Left(10).when { !isCenterAligned }, CenterX(0).when { isCenterAligned } ) </code></pre> <p>On iOS, you can also access context about the <code>UITraitCollection</code> of the view you&#39;re constraining, in order to adjust your layouts more easily for different devices and orientations.</p> <h3><a >Stevia</a> [Swift]</h3> <p>Stevia is part of freshOS, a project to bring together a set of libraries for iOS developers to use in their projects. While Stevia has some similar ideas to SnapKit, there are a few differences that make it really intriguing.</p> <p>One is that Stevia offers its own visual layout API. So if you like the visual aspect of Apple&#39;s VFL but want something a little less verbose, that doesn&#39;t rely on strings and dictionary lookups, Stevia can help. Here&#39;s a quick example of the visual layout API in use from the Stevia docs:</p> <pre> <code>layout( 100, |-email-| ~ 80, 8, |-password-forgot-| ~ 80, &gt;=20, |login| ~ 80, 0 ) </code></pre> <p>You can also use Stevia like SnapKit, by chaining together various attributes:</p> <pre> <code> image.fillContainer() </code></pre> <p>And you can use the equation-based API to lay things out like this:</p> <pre> <code>email.Top == 100 password.CenterY == forgot.CenterY </code></pre> <p>One thing I love about Stevia is that you can constrain multiple views at the same time with functions like these:</p> <pre> <code>alignHorizontally(password, forgot) equalWidths(email, password) </code></pre> <p>With a little set up, you can also get live reloading working with Stevia, to make development a lot faster.</p> <h3><a >Mortar</a> [Swift]</h3> <p>Unlike SnapKit and Stevia, Mortar doesn&#39;t offer chaining at all. It&#39;s a highly opinionated library that purposely avoids chaining to improve readability.</p> <p>Like Stevia, however, it does offer a visual layout API, as well as very concise syntax for creating Auto Layout constraints in code.</p> <p>Here&#39;s an example of Mortar&#39;s visual layout API from the docs:</p> <pre> <code>viewA | viewB[==viewA] || viewC[==40] | 30 | viewD[~~1] | ~~1 | viewE[~~2] // viewA has a size determined by its intrinsic content size // viewA is separated from viewB by 0 points (| operator) // viewB has a size equal to viewA // viewB is separated from viewC by the default padding (8 points; || operator) // viewC has a fixed size of 40 // viewC is separated from viewD by a space of 30 points // viewD has a weighted size of 1 // viewD is separated fom viewE by a weighted space of 1 // viewE has a weighted size of 2 </code></pre> <p>Mortar also lets you set constraints on multiple views at once, which I find extremely useful. Here&#39;s a look at the different ways Mortar constraints can be created:</p> <pre> <code>[view1, view2, view3].m_size |=| (100, 200) /* Is equivalent to: */ [view1.m_size, view2.m_size, view3.m_size] |=| (100, 200) /* Is equivalent to: */ view1.m_size |=| (100, 200) view2.m_size |=| (100, 200) view3.m_size |=| (100, 200) </code></pre> <p>I&#39;m a bit turned off by the heavy use of symbols in Mortar, but it does make the syntax extremely concise. I imagine once you get your head around the syntax, it could be a lot faster and easier to read and write constraints in Mortar. It&#39;s also nice that Mortar doesn&#39;t leave out constraint attributes that some of these other libraries don&#39;t support, such as <code>firstBaseline</code>.</p> <h3><a >Bamboo</a> [Swift]</h3> <p>While Bamboo seems similar to the other options I&#39;ve mentioned, it does have some unique aspects that make it worth exploring. One thing I love about Bamboo is its <code>fill</code> methods. For starters, you can simply call <code>fill()</code> to pin all the edges of a view to its superview. But you can also call, for example, <code>fillLeft()</code> to pin the left, top, and bottom edges of a view to its superview, or <code>fillWidth()</code> to pin the leading and trailing edges.</p> <p>Another set of methods I love are <code>before()</code>, <code>after()</code>, <code>above()</code>, and <code>below()</code>. I often think about positioning my views in this way, so it&#39;s nice to be able to express my constraints in code that matches my thought process. Each of these methods takes an optional spacing argument, so you can easily lay out a view after another one, with spacing between.</p> <p>And again, one of my favourite features is present here: you can constrain multiple views at once using Bamboo:</p> <pre> <code>// Constrain on each item. // e.g., Set each item&#39;s width to 10. [view1, view2, view3].bb.each { $ } // Constrain between every two items. // e.g., view1.left == view2.left, view2.left == view3.left [view1, view2, view3].bb.between { $$1) } [view1, view2, view3].bb.left() // align all left [view1, view2, view3].bb.width(10) // set width of all to 10 </code></pre> <p>Bamboo also offers a neat option for distributing views evenly along an axis:</p> <pre> <code>[view1, view2, view3].bb.distributeX(spacing: 10) // [view1]-10-[view2]-10-[view3] </code></pre> <p>And finally, Bamboo also offers <a >similar syntax for handling manual frame layouts</a>, for those times when Auto Layout won&#39;t do the job.</p> <h3><a >Cartography</a> [Swift]</h3> <p>Cartography uses a closure-based approach to constraints, where each closure can take multiple views to constrain against each other. Here&#39;s an example from the docs:</p> <pre> <code>constrain(view1, view2) { view1, view2 in view1.width == (view1.superview!.width - 50) * 0.5 view2.width == view1.width - 50 view1.height == 40 view2.height == view1.height view1.centerX == view1.superview!.centerX view2.centerX == view1.centerX &gt;= view1.superview!.top + 20 == view1.bottom + 20 } </code></pre> <p>You can also do this for just one view at a time, like so:</p> <pre> <code>constrain(view) { view in view.width == 100 view.height == 100 } </code></pre> <p>And you can keep a reference to all the constraints within a closure as a <code>ConstraintGroup</code>:</p> <pre> <code>let group = constrain(button) { button in button.width == 100 button.height == 400 } </code></pre> <p>Or you can capture a single constraint from your closure:</p> <pre> <code>var width: NSLayoutConstraint? constrain(view) { view in width = (view.width == 200 ~ 100) } </code></pre> <p>Like many of the other DSLs in this post, Cartography offers <code>edges</code>, <code>center</code>, and <code>size</code> compound attributes to speed things up. It also offers a way to align multiple views easily:</p> <pre> <code>constrain(view1, view2, view3) { view1, view2, view3 in align(top: view1, view2, view3) } </code></pre> <p>And to distribute views evenly, like Bamboo does:</p> <pre> <code>constrain(view1, view2, view3) { view1, view2, view3 in distribute(by: 10, horizontally: view1, view2, view3) } </code></pre> <h3>Other options</h3> <p>You might also want to check out some of these libraries:</p> <ul> <li><a >LayoutKit</a> [Swift, Objective-C], an alternative to Auto Layout made by LinkedIn</li> <li><a >PinLayout</a> [Swift], a DSL for manual frame layouts</li> <li><a >FlexLayout</a> [Swift], a Swift interface for Yoga/Flexbox, made by the team behind PinLayout</li> <li><a >Layout</a> [Swift], a framework for writing layouts using XML template files</li> </ul> <hr /> <p>There are some other Auto Layout DSLs I came across but didn&#39;t add to my Larder or include here. Mostly this is because they&#39;re either old and not actively maintained, or they&#39;re very simple and didn&#39;t seem to offer anything particularly unique. That doesn&#39;t mean they&#39;re not useful, but I was looking for what&#39;s most interesting and unique about these different approaches to Auto Layout sugar.</p> <p>Hopefully you&#39;ll find something new to try out from this list! If you think I&#39;ve missed a library that&#39;s worth exploring, please share it with us on Twitter at <a >@LarderApp</a>.</p> What&#39;s in your Larder: Onboarding libraries for iOS <p>I recently rewrote the onboarding flow in one of my iOS apps. I ended up writing the whole thing myself, because I wanted control and the ability to tweak everything, but I started out by looking into some libraries that could take care of the heavy lifting for me.</p> <p>If you don&#39;t need as much control as me and you want to get something up-and-running quickly, these libraries I found might be useful. I haven&#39;t used any of them, but they all seemed interesting enough to save to my Larder account for future reference.</p> <h3><a >OnboardKit</a> [Swift]</h3> <p><img alt="OnboardKit example" src="" /></p> <p>The docs are sparse for OnboardKit, but I like that it takes an object for configuring the UI details, so you can set everything in one go like this:</p> <pre> <code>AppearanceConfiguration(tintColor: .green, textColor: .white, backgroundColor: .black, titleFont: UIFont.boldSystemFont(ofSize: 24), textFont: UIFont.boldSystemFont(ofSize: 13)) </code></pre> <p>Most of the other libraries I looked at have a set of properties you can change, but I think this approach is neater.</p> <h3><a >SwiftyOnboard</a> [Swift]</h3> <p><img alt="SwiftyOnboard example" src="" /></p> <p>SwiftyOnboard takes a very Apple approach by using separate delegate and data source protocols for managing the onboarding&#39;s behaviour. There&#39;s not much talk in the docs about customising the design, and it seems like each page is limited to a title, subtitle, and image, but the examples give a good idea of how much you can achieve within that framework.</p> <h3><a >Tutti</a> [Swift]</h3> <p><img alt="Tutti example" src="" /></p> <p>Tutti is quite different to the other libraries mentioned here. It&#39;s based on the idea of a hint-style tutorial, where small pop-ups lead the user around and teach them how to use your app. I included it in this list because it also lets you make full-screen swiping tutorials, and if you need to include hints in your app, it could be nice to have one library to handle both approaches.</p> <h3><a >LUNTutorialViewController</a> [Objective-C]</h3> <p><img alt="LUNTutorialViewController example" src="" /></p> <p>Like SwiftyOnboard, LUNTutorialViewController uses a delegate and data source to manage the onboarding. Compared to some of the other libraries mentioned, LUNTutorialViewController seems a bit more complicated, and hasn&#39;t been updated for a while. Still, if you need something in Objecitve-C, it could be worth looking into.</p> <h3><a >Surfboard</a> [Objective-C]</h3> <p><img alt="Surfboard example" src="" /></p> <p>Surfboard hasn&#39;t been updated for several years, but it offers a simple approach in Objective-C in case that&#39;s what you need. It also lets you create panels for your onboarding using JSON format, which is nice.</p> 11 principles that help me write better code <p>Since leaving behind my day job to work full-time on Hello Code, one of my focuses has been on reading and learning a lot. I&#39;m at the point now where I know enough to realise how bad some of my old code is, but I don&#39;t always know how to improve it. So I&#39;ve been learning about generic principles and ideas that I can use to guide me in writing better code in future.</p> <p>In case it&#39;s helpful to others, I wanted to share the principles and style decisions I&#39;ve decided to use as my guideposts.</p> <p>Since I&#39;m only writing native iOS apps in Objective-C and Swift for now, this guide is written specifically for that use-case. Keep in mind that if you work in different areas or with different languages these ideas might not fit perfectly.</p> <h2>1. Pure functions</h2> <p>Pure functions avoid side effects, taking and returning values instead.</p> <h3>Principle</h3> <p>All functions should take all objects they need to do their work as arguments and return a value when done, rather than altering global state or creating other side effects.</p> <p>For example, this function alters global state, which counts as a side effect, because it&#39;s not directly returning a value, but rather changing code outside its own scope:</p> <pre> <code>// defined somewhere else in your code let usernameLabel = UILabel() func updateUsername(_ username: String) { self.usernameLabel.text = username } </code></pre> <h3>Advantages</h3> <p>Pure functions make it easier to reason about your code because they state up-front what objects they require (they&#39;re all defined as arguments), and they return a value when they&#39;re done. Functions that create side effects, on the other hand, require you to inspect the implementation details to figure out what will happen when you call that function. Functions that modify global state can also create bugs that are difficult to track down, since their effects are not always obvious, and can even behave differently depending on that state!</p> <p>Pure functions also make your code easier to test, because everything required for each function to run is passed in as an argument. Rather than using a global singleton, for instance, if that object is passed into the function, you can pass in a mock version during tests.</p> <h2>2. Avoid using generic types to represent data</h2> <p>I used to use arrays and dictionaries all through my code to represent JSON coming from an API. Since I needed to serialise that JSON into native objects before I could work with it, it would be represented as basic arrays and dictionaries from the first time I could use it.</p> <p>The problem with leaving my data this way is that the actual shape of the data is extremely unclear. I was constantly following my code through a whole series of steps and comparing to the direct API output to figure out the shape of the data I was using in a particular method, so I&#39;d know what keys were available and what kind of values they contained. It was confusing and a big time-waster.</p> <p>Using custom types lets me clearly define the structure of each type for easy reference, and adds more clarity to my code by replacing generic types with custom-named types that make it clear what kind of data they hold.</p> <h3>Principle</h3> <p>Rather than relying on generic, built-in types, create custom types to represent your specific data. These can be simple wrappers around arrays and dictionaries with more descriptive naming and documentation, custom classes, or even enums to represent specific states rather than using Bools (see <a >Ash Furrow&#39;s post</a> on this idea).</p> <h3>Advantages</h3> <p>Using custom types, especially with a strongly-typed language like Swift, means the compiler can help you avoid bugs and unexpected behaviour by ensuring you&#39;re always working with the exact type of values you expect. You&#39;ll also avoid coercion bugs when working with dynamic and loosely-typed data such as JSON (e.g. expecting an array but receiving a dictionary).</p> <p>This principle also makes your code more clear, as the shape of your values and objects is clearly defined and documented within your codebase.</p> <h2>3. Write code that explains itself</h2> <p>I have lots of bad habits around writing comments in my code. I either don&#39;t do it enough, or I write comments in places where they&#39;re unnecessary and not where I actually need them, or I rely too heavily on comments because my code is hard to read and understand. This principle is designed to avoid over-reliance on comments and to put comments in their place&mdash;where they&#39;re most useful and necessary.</p> <p>I found most of the inspiration for this idea and the examples below in <a >this post on the Google testing blog</a>.</p> <h3>Principle</h3> <p>Make your code more expressive, rather than relying on comments to clarify functions, variable names, etc. Use those names to express clearly and succinctly what&#39;s happening, and save comments for explaining <em>how</em> and <em>why</em>.</p> <p>For example, this is more clear:</p> <p><code>let widthPx = 50</code></p> <p>than this, which requires a comment to explain the code:</p> <p><code>let width = 50 // width in pixels</code></p> <p>But don&#39;t go overboard with long variable or function names either&mdash;aim for brevity as well as clarity.</p> <p>You can also add variables for extra clarity rather than combining calculations into a single complicated expression. For example:</p> <pre> <code>// This is more clear: let price = numItems * itemPrice let discount = min(5, numItems) * itemPrice * 0.1 let finalPrice = price - discount // Compared to this, which is harder to read and requires a comment to explain what&#39;s happening: // Subtract discount from price. let finalPrice = (numItems * itemPrice) - min(5, numItems) * itemPrice * 0.1</code></pre> <p>If your functions are so long they require comments to explain each step (guilty!), extracting chunks of code into pure functions (see #1) can make your code easier to read.</p> <p>You can also use your code to check assumptions, rather than leaving comments to explain them. For example:</p> <pre> <code>// This is more clear and easy to read: guard let height &gt; 0 else { return 0 } return width / height // Compared to this, which requires a comment: // Safe since height is always &gt; 0 return width / height</code></pre> <p>In the example above, the first approach is also safer, as it <em>checks</em> assumptions, rather than <em>relying on</em> those assumptions. We&#39;ll explore this idea in more detail again when talking about assertions.</p> <h3>Advantages</h3> <p>Since code can compile and run without accurate comments, it&#39;s too easy for comments to become out-of-date or incorrect as your code changes. Relying on comments makes your codebase fragile for future colleagues or future you, as those comments aren&#39;t guaranteed to be in-sync with your code.</p> <p><img alt="code comments" class="img-responsive" src="/static/media/public/codecomments.jpg" style="max-height:400px" /> <strong>Code comments.</strong> Via <a >imgur</a></p> <p>And, as we all know, code is written for humans to read first, and computers to read second, so making our code clear and easy to follow is always a good idea.</p> <p>Finally, this approach can help avoid regression bugs that come from misunderstanding code that&#39;s confusing, unclear, or has comments that are incorrect or out-of-date.</p> <h2>4. Document functions and comment often</h2> <p>When I <em>am</em> writing comments or documenting my code, I try to follow the notes below to ensure my comments are useful, and don&#39;t become just noise.</p> <h3>Principle</h3> <p>If I use the right formatting for my comments to make these parse as function documentation (both Xcode and AppCode have keyboard shortcuts to help with this), I can take advantage of my IDE&#39;s documentation pop-ups for my own code. This is really handy for quickly checking a function signature, or reading notes about how a function works. I try to make sure all of my functions include documentation to make working with that code easier on future me.</p> <p>I also try to keep my future self or a stranger in mind when writing new code, and add comments to any code that they might be confused about. Comments can help explain decisions I&#39;ve made, and any compromises I&#39;ve made that I might forget about in future, as well as explaining any code that&#39;s tough to understand quickly.</p> <h3>Advantages</h3> <p>Documentation makes it fast and easy to use your own APIs and makes it obvious what to expect from those APIs. This makes working with your own code in future much easier and more enjoyable.</p> <p>Comments can quickly clear up decisions and compromises that would be confusing or lead to future you/other developers making changes you&#39;ve already decided against. They can also make it faster and easier to put code back into your head when you&#39;ve been away a long time, and can help when dealing with generic data (e.g. JSON from an API) that&#39;s not obvious from the types (e.g. basic, nested arrays and dictionaries vs. strict custom models and types).</p> <h2>5. Single-responsibility functions</h2> <p>A trap I fall into a lot is giving a class or function too many responsibilities. As much as possible, objects and methods should have a single responsibility, and that responsibility should be obvious (or easily guessed) from their names.</p> <h3>Principle</h3> <p>Functions should do what they say they do&mdash;no more, no less. This means consumers of your APIs (even if that&#39;s just future you) don&#39;t have to delve into the implementation of your functions to figure out what they do, so working with your codebase is more straightforward.</p> <p>Types, classes, and functions shouldn&#39;t be responsible for anything you wouldn&#39;t guess, based on their name (e.g. a <code>NetworkManager</code> shouldn&#39;t be creating models or updating a database&mdash;it should deal with the network and nothing else). This ties in well with our pure functions concept, as a function without side-effects usually only does one thing anyway.</p> <h3>Advantages</h3> <p>When interacting with functions (e.g. an API), I shouldn&#39;t need to understand the internal implementation of those functions in order to use them. If a function says it does <code>x</code>, I can be reassured that it does <code>x</code> and only <code>x</code>. And it should <em>always</em> do <code>x</code>, not only in specific circumstances.</p> <p>(See more explanation and examples here: <a >Reusability and Composition in Swift</a>)</p> <p>As well as being easier to interact with and understand, code with a single responsibility is more easily tested and refactored, whereas multiple responsibilities in a single object or method can easily led to spaghetti code that&#39;s hard to follow and reason about, and nigh on impossible to test.</p> <h2>6. Composition</h2> <p>Swift tends to be more heavily focus on using protocols (otherwise known as interfaces or traits) than Objective-C, where I tended to opt for object-oriented programming and inheritance most of the time. Usually one of these approaches (composition via protocols or inheritance via subclassing objects) is more appropriate to the situation, but since I default to object-oriented ideas, this principle is designed to remind me there&#39;s another option that&#39;s sometimes a better choice.</p> <h3>Principle</h3> <p>Using protocols to set up <code>has-a</code> relationships as opposed to the <code>is-a</code> relationships that come from inheritance enables composition&mdash;combining protocols to compose types that <em>have</em> particular traits. Where possible, protocol extensions can be used to create default implementations like a superclass would offer.</p> <p>With composition, you can build and change your objects like LEGO, adding and removing functionality in a modular way.</p> <p><img alt="rabbit duck graph" class="img-responsive" src="/static/media/public/rabbitduck.png" style="max-height:400px" /> <strong>This object conforms to both rabbit and duck protocols.</strong></p> <p>For example: Imagine a <code>Bird</code> class that has a method <code>fly</code> and subclasses like <code>Finch</code> and <code>Magpie</code>. Now suppose you want to make a <code>Dragon</code> subclass. It needs to have a method <code>breatheFire</code> and it also needs to be able to fly... but it&#39;s not a <code>Bird</code>, so you don&#39;t really want to make it a subclass of <code>Bird</code> just to inherit the <code>fly</code> method.</p> <p>If you make <code>fly</code> and <code>breatheFire</code> part of two different protocols, the <code>Dragon</code> class can conform to both in order to use those methods.</p> <h3>Advantages</h3> <p>Inheritance can lead to a messy tree of classes. It can also lead to bad decisions in order to create objects with the functionality you want (e.g. moving a method further up the tree in order to have it inherited by the classes that need it, which then makes many other subclasses inherit it that <em>don&#39;t</em> need it).</p> <p>Read more details and examples about composition in Swift here, including the bird/dragon example I borrowed: <a >Reusability and Composition in Swift</a> and here: <a >Protocol Oriented Programming Is All About Object Composition</a>.</p> <h2>7. Dependency injection</h2> <p>Until recently I&#39;ve been very reliant on global state, which is fragile and confusing. It causes bugs, makes code hard to reason about, and is rarely the best approach. This principle insists on making use of arguments to pass around objects instead of allowing functions to create side effects that are hard to reason about.</p> <h3>Principle</h3> <p>Pass as arguments every dependency that an object requires when instantiating, rather than accessing global state or creating new objects from within the method. (There are other types of dependency injection, such as passing arguments into functions when they&#39;re called, or setting them as properties on an object or type after creating it, but I prefer to inject arguments during instantiation whenever possible, so that&#39;s what I&#39;ve focused on here.)</p> <h3>Advantages</h3> <p>Requiring dependencies as arguments makes your function definitions more clear, as it&#39;s obvious what objects and values are required for the function to do its work, and where those are coming from.</p> <p>Passing dependencies as arguments also helps a lot with the testability of your code, as you can easily switch out a depencdency with another when testing, passing mock objects and values as needed.</p> <h2>8. Plan new features end-to-end before coding</h2> <p>After programming for a few years, I still struggle with thinking through a new feature. I tend to get a rough idea of how something will work and start coding, only to quickly hit a roadblock I hadn&#39;t thought of and have to undo all my work. This has happened so many times that I&#39;ve designed this principle to force me to spend more time planning my code so I don&#39;t have to keep undoing it.</p> <h3>Principle</h3> <p>Think through as much of the implementation and the use-case of a new feature or a major refactor before coding. Write notes, draw diagrams, use flow charts; whatever works to help you figure out how your code will be implemented and how it will interact with the rest of your codebase.</p> <h3>Advantages</h3> <p>This process helps to save time and effort that comes from constantly backtracking when new features or refactoring don&#39;t work out. It helps you realise more quickly that a particular solution won&#39;t work so you can avoid wasting time implementing it.</p> <p>Better planning can also help you avoid making a mess of your codebase and/or commits by coming up with a solution that will work before coding, rather than constantly refactoring, resetting commits, or adjusting your approach partway through writing the code.</p> <h2>9. DRY / prioritise code reusability</h2> <p>Repeating code has led to both bugs and headaches for me in the past. The worst situation I&#39;ve run into comes from copying code into different places in my app, so that when I want to make a change to how that code works, I have to remember all the places I&#39;ve put it and change it in each one. DRY (Don&#39;t Repeat Yourself) and code reusability help avoid this situation.</p> <h3>Principle</h3> <p>Create reusable functions for any chunks of code you&#39;re using in different places, so the implementation itself isn&#39;t copied into various places in your codebase. Identify code that&#39;s logically the same but with minor changes around values, for example, and refactor these blocks out into a single function that takes the differing value as an argument.</p> <p>You can also use wrapper functions to adjust the behaviour of underlying reusable functions, rather than writing several functions that are very similar. For example, I have a function that calls an API endpoint and takes a timeout argument. In most cases I want to use a default timeout (this code is in Objective-C so I can&#39;t just use a default value for the argument as I would in Swift). I use a wrapper function in most of my code that calls this underlying function, passing in a default timeout argument. In the few cases where I want to change the timeout, I can call the underlying function myself and pass in a different argument.</p> <p>The implementation of the code to call the API endpoint only exists once in my code base, and I have just one extra two-line wrapper function which gives me the ability to change the timeout argument when needed.</p> <p>DRY also works when defining values for things like UI. Develop a consistent UI style throughout the app by creating reusable theme elements (fonts, colours, etc.) and UI elements (pre-styled buttons, labels, etc.), defining these elements once and referencing them as needed. You can do this with a whole theming library or something as simple as a set of constants for your colour names and font sizes.</p> <h3>Advantages</h3> <p>Copy + paste can lead to subtle bugs, as well as code that&#39;s hard to read and reason about.</p> <p>Copy + pasted code also requires the developer to remember all the places the same code has been pasted when making changes in future, and to manually keep that code in-sync, which is an approach that&#39;s extremely fragile and error-prone.</p> <p>DRY makes code easier to test, debug, and keep in your head, because you&#39;re only writing or changing code in one place.</p> <h2>10. Testing</h2> <p>Testing is something I heard about for a long time before I ever managed to understand it enough to try it. I still have a lot to learn about testing, but I&#39;m committed to do so because it makes me write better code (testable code is generally better in other ways too, because it tends to require a lot of the principles above) and it helps me catch bugs before my users do.</p> <h3>Principle</h3> <p>Tests are designed to make sure your code behaves as you expect. They don&#39;t care about implementation, only outcomes.</p> <p><strong>Red, green, refactor</strong> is a TDD (test-driven development) approach that starts with writing tests that fail (because you haven&#39;t written/changed any code yet), then writing code to make the tests pass, then refactoring that code to make it more simple, robust, and/or elegant, while relying on your tests to make sure you don&#39;t break what you just built. This approach ensures new features or changes come with tests, since the tests are written first.</p> <h3>Advantages</h3> <p>Tests can help you catch bugs or breaking changes as soon as you create them, which helps you ship better code. They also help you change your code with more confidence, since tests will catch breaking changes or regressions as you work.</p> <p>Writing tests in advance can also improve the usability and readability of your APIs, since you&#39;re planning with testability in mind.</p> <h2>11. Use assertions to ensure your code is being used correctly</h2> <p>Developers debate whether to use assertions in only debug builds or when the app is live, since they cause your app to crash. While this isn&#39;t a nice experience for the user, assertions are generally used to catch a programmer error that&#39;s caused your app to be in a state you never expected. Either way, this approach is particularly useful during debugging, as you can very quickly and easily catch mistakes you&#39;ve made when using your own APIs.</p> <h3>Principle</h3> <p>Use assertions to define your expectations about arguments or conditions that should have been met, raising exceptions if they fail. Use them to test for things like making sure arguments are what you expect before trying to work with them, or that a particular argument is present in cases where it&#39;s optional but you&#39;re expecting it to be there.</p> <p>Use assertions as extra conditions on your arguments, when the type of object required in your definition doesn&#39;t ensure your code can run as expected. For example, your function takes an integer but you really need one that&#39;s not a negative and not zero.</p> <p>(A more formal approach to this principle is <a >Design by Contract</a>, in which languages like Eiffel require you to list the pre-conditions that must be satisfied before calling a function, and the post-conditions that are met when the function is done. But this works best in a language with first-class support, like Eiffel.)</p> <h3>Advantages</h3> <p>Assertions help to enforce correct use of your APIs by yourself and other developers. You can avoid your users having a bad or broken experience by crashing in debug mode so you can find and fix programming errors before shipping.</p> <hr /> <p>As I said earlier, these principles are designed around my own needs, my own level of experience, and my preferences. They&#39;re also based on what&#39;s relevant to me as an iOS developer. They may or may not be relevant to you, but feel free to take what&#39;s useful and leave the rest&mdash;that&#39;s how I came up with these in the first place.</p> Making it: Indie iOS developer Maree Williams <p><img alt="Maree Williams" class="img-responsive" src="" style="float:left; margin:0 !important; padding:5px 10px; width:180px" /> When I met Maree at a conference earlier this year, I was impressed by her story of finding inspiration for mobile apps in her previous career working in the health industry. Maree&#39;s had some great experience filling real needs that she and her colleagues had, and has now transitioned into indie development.</p> <p><strong>Hi Maree! First up, can you tell us who you are and what you do?</strong></p> <p>Well I am someone with experience in both the health sector and the IT industry. I started out in medical laboratories but before the year 2000 I did a computing degree and worked for a large multinational computing firm in consulting for four years. After this I changed careers again and moved into medical research. This gave me a chance to combine my medical and computer knowledge as I have worked on medical registries as well as clinical trials. These days I write apps&mdash;and I have released four apps on the Apple App Store, with three of them still available now.</p> <p><strong>How long have you been working on iOS apps? What was your journey like from starting out with iOS development to where you are now?</strong></p> <p>So about five years ago I started looking into how to write apps and taught myself Objective C. I released iLab first (a converter for units used in pathology tests), followed by a free app for a medical conference that I was helping to organize as part of my &lsquo;paid&rsquo; employment. My third app is called Date Calculator for Clinical Trials, which as the name suggests helps to plan a schedule based on a given date and day (or week) of the trial. After I released this app I decided to learn Swift and then wrote my next app&mdash;KrazyKringle. This was my first go at writing an app that was not directly applicable to my paid work and I realised that more is needed to have a successful app than just writing code and putting the app onto the App Store.</p> <p>Since then I have branched out and have trialed working in a team environment to produce an app as well as looking into data analysis and machine learning in a datathon. A hackathon and incubator run by Girl Geek Academy followed. This produced a couple of ideas, one of which I am still working on at the moment.</p> <p>The whole startup community is a really big area at the moment and there are a lot of exciting ideas out there and a lot of dedicated people. Participating in this has opened my eyes to the world of marketing and surveying your market to answer a need. This will be very helpful moving forward with my new app that our team is working on but has not been released&mdash;<a >GoTrackHealth</a>.</p> <p><strong>You&#39;ve worked on a few iOS apps now. Where do you usually get ideas for your apps from?</strong></p> <p>Initially my ideas came from what I felt would help me with my job. However I found that the market for this was limited. So I started asking friends and family if they had any ideas for an app. Trying to find an idea that someone else had not already thought of is really quite hard! That is where KrazyKringle came in. A Krazy Kringle is run sort of like a <a >Kris Kringle</a> except everybody brings a generic present. There are all sorts of rules for the game as the presents are chosen but what is needed is a randomised list of names for everybody to select the presents from under the tree. Usually names are drawn from a hat but the app does this part!</p> <p>GoTrackHealth came out of a survey we did of health professionals. We had an a couple of ideas but were not certain which was the bigger issue. It turned out that many of the participants found getting patients to follow through on health requests was a large problem. This first survey was followed up by a survey of what would help people to remember to complete these tasks.</p> <p><strong>Has anything surprised you about going independent as a developer? What are the main differences for you, compared to your previous work?</strong></p> <p>Working as an independent developer is definitely different to my &lsquo;paid&rsquo; work. It is great as the day is my own, no one to tell me what to do and when. However this can be a trap&mdash;it is so easy for the day to escape and I find that I have not spent the time I had planned doing productive work. I might have been distracted by home tasks, or phone calls, or whatever. So yes, I have found it requires discipline. Also as an independent developer it is too easy to work at any time of the day (or night) and every day of the week. This also can be a trap as balance is needed. I do not want to give up paid employment to find that I am my own worst boss!</p> <p><strong>What does a typical day look like for you now? Is there anything you&#39;d like to change about that?</strong></p> <p>The days that I work on my apps usually start later than my &lsquo;paid&rsquo; work days&mdash;as I figure I can take it easier (no commute)! I start off with a coffee then exercise usually while watching a training video about something that I am trying to learn at the moment. Then&nbsp;after breakfast I sit down to work and if I am lucky get 2 to 3&nbsp;hours in then. After that it varies and I try and do something social during the day even if it is shopping. After which I would like to say I sit down in the afternoon and complete another 4 hours of work but it does not always happen!</p> <p>I find it really helpful if I am going around in circles to take a break and to go for a walk. This usually allows me to see the whole picture and often I think of another way to tackle the issue.</p> <p>The work itself can be varied and it took me a while to realise that things other than actual coding are also work in this context.</p> <p>I do miss being able to talk ideas through with other people during the day. Phone calls, emails and chat programs all help but it is not the same as face to face interaction.</p> <p><strong>And when you&#39;re not working, how do you recharge and relax?</strong></p> <p>I am a big book reader&mdash;usually science fiction but also mysteries. I almost always have a pile of books ready to be read and get quite concerned if I am getting towards the end of my book and do not have another one waiting! I tried digital books and while on trips I use them&mdash;at home I just like the feel of a &lsquo;real&rsquo; book.</p> <p><strong>We like to ask everyone what &quot;making it&quot; means to them. What does it mean to you? Do you feel like you&#39;ve made it already? If not, what are your plans to help you move in that direction?</strong></p> <p>&#39;Making it&#39; is such a subjective term! My idea of what constitutes &lsquo;making it&rsquo; varies from day to day, week to week. Really I would like a popular app on the App Store. Something that gets downloaded a lot. This is why I have been looking into what makes a good startup. It seems to be more than just a good idea. Or good marketing. Or a well-written app. I think persistence is required and a lot more. Maybe some of the skills that I have picked up over the years in my former jobs&mdash;project management, planning and networking will come in handy but also I think I have a lot to learn. So watch this space.</p> <p><strong>As an indie dev, how do you stay in touch with the iOS dev community? Do you end up spending a lot of time working alone?</strong></p> <p>I go to Meetups&mdash;<a >Cocoaheads</a> amongst others. Meetups are great for keeping in touch, not just as it is a social environment but it is also good as I feel I am still learning coding. The whole app development community is so varied and technically it can be way over my head.</p> <p>As for working alone&mdash;yes this is the good and the bad of being an indie developer.</p> <hr /> <p><strong>Thanks for joining us, Maree!</strong></p> <p><strong>All the opinions expressed here are Maree&#39;s own. You can find out more about Maree and her work at <a ></a> or get in touch with her on <a >LinkedIn</a> or on Twitter at <a >@mpwil50</a></strong></p> Making It: Indie iOS developer Curtis Herbert <p><img class="img-responsive" src="" alt="Curtis Herbert"></p> <p>Curtis Herbert is the indie developer behind <a >Slopes</a>, an app that gives "skiers and snowboarders detailed stats, and bragging rights, about their days hunting powder". After following <a >his blog</a> for months, I met Curtis earlier this year when I briefly joined the <a >Independence</a> podcast team to chat about life as an indie developer.</p> <p><strong>First up, tell us a bit about yourself, what you're interested in, and what you do all day.</strong></p> <p>I’m an&nbsp;independent&nbsp;developer trying to make a living in the App Store. Building something (be it an app, a project around the house, or LEGOs) is part of my core identity. When I’m not building something you’ll find me outside either enjoying a good 5 mile run, or in the winter carving down the mountains on my snowboard.</p> <p><strong>What does a typical workday look like for you?</strong></p> <p>Usually I’ll live the indie dream and sleep in super late … you know, around 8:30am or so. Brew up a pot of black tea, cook breakfast, and then I’m jumping head-first into whatever I need to get done for the day as I work from my home office. The day itself&nbsp;doesn’t have much structure after that, save for two points: around 1pm I’ll take a break and either go for a run or go to the gym for an hour, and then my wife gets home around 5pm so I try to (and often fail) wrap up by then. Despite being&nbsp;indie for 6 years now I’m still pretty disciplined&nbsp;about not goofing off too&nbsp;much during the day.</p> <p>I’ve&nbsp;been&nbsp;trying to mix things up a bit more as of late,&nbsp;though, as working from home can be pretty isolating at time. I’ve been making it into one of the great coworking offices in&nbsp;Philadelphia (shout out to Indy Hall!) twice a month now. The commute into the city prevents me from doing this too often, but being surrounded by&nbsp;welcoming and creative people even just 2x a month is great.</p> <p>After work hours I’ll usually try my best to&nbsp;“shut down” and stop working, but I only have a 50/50 success rate with that. When you’re working&nbsp;on building something you love it has a way of hooking you back in.</p> <p><strong>And when you're not working, how do you recharge and relax?</strong></p> <p>If I lived somewhere&nbsp;with more winter I’d be snowboarding all the time to relax. There’s just&nbsp;something about throwing on some chill music and hearing the crunch of the snow under my board that always manages to relax me. Alas though,&nbsp;Pennsylvania only&nbsp;gets 3 or 4 months of winter so I’m stuck finding other things to do with my time!</p> <p>Usually you’ll find me playing video games as I try to shut my brain down and relax. I’m a sucker for the unique experiences and worlds I can jump into through a game. I’m a big fan of traditional table-top games with friends, too, so that’s how I’ll spend my non-antisocial time. If I’ve&nbsp;exhausted&nbsp;all those options you’ll find me enjoying some good sci-fi show (so excited Trek is back on TV, and&nbsp;actually good&nbsp;proper&nbsp;Trek!).</p> <p><strong>How long have you been working on iOS apps? What was your very first iOS app?</strong></p> <p>I’ve been working with iOS apps since the SDK was released. I was a web developer at the time, but the idea of shipping software for an Apple platform always appealed to me as I’d been a Mac user since I was a kid. The iPhone seemed like the perfect time to get involved after a few failed attempts to teach myself Objective-C for the Mac.</p> <p>I was constantly playing around with ideas, but I didn’t get my first app into the store for another two years in 2010. The name hasn’t aged well (“Isis") but it was a server monitoring program (with a C# server app backend my friend wrote) allowing me to keep an eye on my web servers’s CPU/RAM/etc. I think I sold all of 5 copies or something, ha. It was a great experience though, and being able to point to something in the store and say “I made that!” was worth it.</p> <p><strong>How did you get started with Slopes?</strong></p> <p>I got started the way many developers do, I think: I was using another app, got annoyed by it, and said “I can do better!” I think I sat on the idea for a good 5 months though before I finally decided to take the plunge. I’m not usually one to half-arse something and I knew that if I was going to take on an app at that point that I’d be trying to make a real go at making it a large part of my life. I worked on it for nights and weekends in the spring / summer, and then took off 2 months from consulting work leading up to the winter to finish it up in time for the season. Fun fact: Slopes 1.0 was launched into the App Store while I was on an Alaskan Cruise using terribly metered and slow wifi on the boat. Quite a way to start an adventure in the App Store.</p> <p><strong>What was your journey like from starting Slopes to jumping into the indie life?</strong></p> <p>When I started Slopes I was already indie, although the mindset is certainly different. At the time I started working on Slopes I had been doing independent consulting (web and iOS) for two years already, so I already had a bit of a groove going. But as I’ve transitioned to spending more and more time on Slopes as it has grown I feel like I’m finally starting to really “get” the indie lifestyle.</p> <p>It is quite the tradeoff — without clients I don’t have anyone I’m responsible to, which means more freedom with my day-to-day and sense of direction, but at the same time now the success / failure of the app rests heavily on my shoulders.</p> <p><strong>How much development time have you put into Slopes, and how much is it making?</strong></p> <p>Oh, geez! I wish I had been running Harvest over these last 4 years as I’d love to know how many hours went into it.</p> <p>The first few years, besides some nights and weekends, I only really took off a month or two per year to focus on the app. I didn’t feel like I could justify any more time; it just wasn’t making a lot of money. But in 2015 I took the summer / fall to re-focus my business model to try to find a way to turn the app around and get to the point where I could justify spending a lot of my time on it. Fortunately, it worked, and I’ve been 2.5x’ing my revenue every year since then. Last winter I saw ~$40k in revenue, so I’m hopeful I can go full-time on it after this winter.</p> <p><strong>Since your business tends to be seasonal, how does that affect the way you work both on the macro and micro scales?</strong></p> <p>Being so seasonal brings an interesting dynamic to the business. On the one hand it is frustrating - most of my revenue comes from the northern hemisphere, so I only see “real” money for ~4 or 5 months of the year. During the rest of the year I’m kinda in the dark in terms of trying to predict how well the next season will go. This also condenses my need to focus on marketing and customer support to that same time period, which is nice.</p> <p>During the summer, since I don’t have a as many active users in the Southern Hemisphere, I’m able to take some time off from “running the business” to focus on my more ambitious goals within the app. This summer I wrote server-side sync, for example. It’s nice to be able to have a longer window of time with fewer customers grabbing at my attention.</p> <p>The ebb and flow of the seasons brings an interesting forced-focus like that through times of the year. In some ways, I’m just along for the ride.</p> <p><strong>In the startup world people often say you can't build a business as a solo founder. Do you personally see advantages or disadvantages to building and marketing Slopes on your own?</strong></p> <p>I certainly feel the disadvantages as I just don’t have enough time to do it all, it is a real struggle to keep up and I know I’m just barely covering everything I need to do! Having a second person focused on marketing would probably really help me take Slopes to a next level. As much as I don’t mind teaching myself how to market better, and I’ve been managing, I’m sure I’m making so many&nbsp;amateur mistakes and having a pro&nbsp;partner would make a huge difference.</p> <p>That said I have to admit if I didn’t also identify as a designer being solo would be a lot&nbsp;harder. I think solo only works if you can at least come close to looking like you know what you’re doing on all fronts (even if you don’t!).</p> <p>But, at the same time, being solo does have its advantages especially when revenue isn’t enough to support two people yet. I’ve been able to make do, growing Slopes into a real business, without much financial stress because I’m not responsible for someone else’s paycheck. Being solo has let me grow Slopes on my terms, and even though it has been a long-game, I don’t feel the rush to get there.</p> <p><strong>Has anything surprised you about going indie? What are the main differences for you, compared to being an employee? What's been harder than you expected?</strong></p> <p>The idea of trading time for money and money for time was a surprising, and alien, thing for me. Having had a “real” job for 6 years before going indie I was so used to working the average ~1,800 hours a year and not even thinking about it. When I went indie, and was focused on consulting, I very much held myself to the same idea of 40hrs / wk, and I was just as bad (if not more so) about taking vacation! It was a great way to make money, but it still felt like I had a JOB-job.</p> <p>Over time I started to realize that tradeoff existed, and started to think of my indie life as goal-based, especially in terms of finances. That’s helped me reach a much better work / life balance and focus on myself and my health. Now I know when I need to take on a project or two to meet my yearly goals, and I know when I can safely take some more time for Slopes or something else. Having a focus on yearly goals like that, instead of just clocking in the hours, has made all the difference.</p> <p>The stress of my decisions being able to make or break my business is harder than I expected, though. When you’re an employee generally you aren’t going to be responsible for your job loss (unless you are a terrible employee). But as an indie, if I mess up Slopes, I can lose that part of my life, which is very intimidating.</p> <p><strong>We like to ask everyone what "making it" means to them. What does it mean to you? Do you feel like you've made it already?</strong></p> <p>I don’t know if I’ll ever “make it”, at least not without being retrospective. My goal is to be able to keep doing what I’m doing: make a living on products I can be proud of. Right now I’m succeeding at that, but if I fail next year I’m back to not making it. So ask me again when I’m 60 ;)</p> <p><strong>As an indie dev, how do you stay in touch with the iOS dev community? Do you end up spending a lot of time working alone?</strong></p> <p>The iOS community is still very Twitter-centric (for better, or more likely, for worse) so I do spend quite a bit of time there. Every month I’ll head into Philadelphia to attend Philly CocoaHeads, which is a great excuse to hang out with 50 or so local iOS developers / designers / hobbyists and talk shop. I’ll also try to make it out for a few iOS conferences throughout the year. I find the mix of those three things keeps me pretty well connected with the iOS community, and keeps me meeting new and interesting people.</p> <p><strong>I'm always on the lookout for more diverse iOS developers to look up to. Do you have any diverse influences in the iOS community that you admire?</strong></p> <p>Just to name a few: <a >@jasdev</a>, <a >@PaolaNotPaolo</a>, <a >@mcgeerosa</a>, <a >@ashleynh</a>, <a >@erynofwales</a></p> <p><strong>What are your future plans for Slopes and beyond?</strong></p> <p>There’s so much I still want to do in Slopes, I haven’t really thought beyond it yet! I feel like it is really just getting started (let's hope I don’t hit that dreaded SaaS revenue&nbsp;plateau soon). The annoying thing is that, aside from some obvious nice-to-have features, I’m getting to the point where what I want to do is reaching the difficult-to-engineer territory. I’ve always liked pushing the bounds of what Slopes can do, and I feel like that’ll be coming to bite me in the butt soon ha.</p> <p>Immediately though I’ve been focused on getting Slopes 3.0 out the door soon. I basically had to write a mini Google Earth for 3.0 (you can replay your runs down the mountain), and server-side sync. Like I said, I like doing the hard things.</p> <p><strong>Thanks for joining us, Curtis!</strong></p> <p><em>You can find Curtis on the web at <a ></a> and on Twitter at <a >@parrots</a></em></p> Making it: Developer and multi-business owner Stef Cola <p><img class="img-responsive" src="" alt ="Stef Cola"></p> <p>Continuing our series of interviews with indie developers on their journey to &quot;making it,&quot; I chatted with <a >Stef Cola</a>, who not only founded a web development company, but also co-runs another small business <em>and</em> works a full-time job.</p> <p><strong>Hi Stef! Tell us a bit about yourself, what you're interested in, and what you do all day.</strong></p> <p>Some quick TL;DR-style facts about me:</p> <ul> <li>I’m a 26 year old female.</li> <li>I live and work in central Victoria.</li> <li>I have a collection of gold, winged shoes.</li> <li>I studied business for two years at an American college on a soccer scholarship.</li> <li>I co-own two small businesses: <a >Ivy and Joe</a> &amp; <a >Doomsday Tuna</a>.</li> </ul> <p>Now for the longer version. By day I work as the head of the digital department at a small educational resource company. By night I work on and in two small businesses. In my downtime I hang out with my intensely playful cat (Moo) and my slightly less playful fiancé (Ivy).</p> <p><strong>What does a typical workday look like for you?</strong></p> <p>As I mentioned earlier, I have the best of both worlds; employment &amp; entrepreneurship.</p> <p>From Monday–Friday I work for an educational resource company (<a >TLRG</a>). I help look after the digital department there, acting as the translator between the developers &amp; management. We are a tight team (my brother is the lead developer there) and really enjoy working on ways that technology can make a difference in education.</p> <p>Outside of the traditional work hours (9–5) I work on the two small businesses that I am a part owner in; a hair studio in Bendigo and a web development company. These are drastically different endeavours but I love the variety that they provide.</p> <p>Generally, I will focus on completing an hour or two of Doomsday Tuna work in the morning before heading off to my 9–5. When I finish up for the day I will wind down and relax before doing a couple of hours work on Ivy and Joe as my final task for the evening. Every day is a little different depending on what crops up in each business (and life).</p> <p><strong>And when you're not working, how do you recharge and relax?</strong></p> <p>I like wine. Red wine of any flavour, assortment or blend. As a rule all wine must be served with delicious food and wonderful company.</p> <p>I have also recently taken up distance running. I am training for my first marathon in May (<a >Great Ocean Road Running Festival</a>) and have been surprised with how much the training has acted as a form of productive meditation. I am spending just over 5 hours a week training at the moment so that is taking up a fair bit of my free time.</p> <p>I also religiously listen to podcasts and audiobooks. A few of my favourite podcasts are <a >The Tim Ferriss Show</a>, <a >99% Invisible</a>, <a >Stuff You Should Know</a> and <a >Myths and Legends</a>. As for audiobooks I will avidly consume anything by <a >Neil Gaiman</a>.</p> <p><strong>You have a lot of ongoing projects. How do you balance all your different responsibilities?</strong></p> <p>I am in a constant battle to be more productive and find the perfect balance between all of the projects that I’m passionate about. I take great joy in experimenting with different tools and methods to maintain some semblance of sanity and lifestyle.</p> <p>Currently I am using an amalgamation of tools, in a cobbled together organisation system that draws on <a >GTD</a> and <a >bullet journalling</a> (although not the Instagram-worthy pages that you produce Belle).</p> <p><em>Note from Belle: I would humbly argue with Stef that my planner pages are not at all Instagram-worthy, and in fact, have stopped sharing much on Instagram recently as a way to avoid thinking about my daily planning as a way to show off, rather than get things done. Having said that, in case you're curious as to what Stef is talking about, you can find <a >my past Instagram posts here.</a></em></p> <p>I couldn't live without Google Calendar, <a >Asana</a> and my notebook. I use Asana to capture all of the incoming, upcoming and random tasks. This forms my giant master to do list. Once a week I will go through the list and schedule tasks into my Google Calendar. Then every evening before bed I will review tomorrow's calendar and handwrite them into my notebook.</p> <p>Throughout the day if any new tasks pop up I will first write them into my notebook. This stops me from jumping into my giant master to do list and getting distracted.</p> <p><strong>In future are you aiming for a different balance between projects and responsibilities than you have now? What would that look like</strong>?</p> <p>Yes, absolutely. End goal: I would love to work part-time and run my businesses for the rest of the ‘work week’.</p> <p>I’m in a weird place, where I thoroughly enjoy my job so there isn’t a huge amount of motivation to move away from being employed. I know that disliking their employment is a massive drive for a lot of people who have a side hustle and are hoping to grow that into their main income. That being said, there is a lot of power in diversifying your income (and your time responsibilities) away from your paycheck.</p> <p>We are growing quite rapidly with Ivy and Joe in terms of revenue and clients. As a result we will be looking to hire another hair stylist to join the team on a part time basis. This is an exciting step as it will take us from owner-operators to employers. This will change my responsibilities in that business quite drastically.</p> <p>Doomsday Tuna has been coasting for the past few months; we haven’t been focusing on marketing or sourcing new clients. For this business I handle all of the sales, customer relations and project management. Whilst I will still be handling all of these responsibilities in the future I am looking to do more developer work.</p> <p>I suppose the higher level spread of my responsibilities within the projects won’t change that drastically but on the lower level, day to day operations there will be some changes.</p> <p><strong>Late last year you took a break from social media on your phone. How did that go, and what did you learn from it?</strong></p> <p>That your mum will consistently ask whether you saw her latest Facebook update. It got to the point that I would have to open the laptop up and check mums feed before heading out to visit her!</p> <p>Additionally, I found that my ability to concentrate on deeper, more meaningful work was directly impacted. By removing the constant pull towards distraction I was able to achieve more.</p> <p>I was driven to remove it when I evaluated the amount of time that I was spending on different areas in my life. I was shocked that a lot of my down time I spend scrolling mindlessly through my Facebook feed instead of doing the things that I said were important to me (connecting with family, writing, producing, etc).</p> <p>I recently installed Facebook back on my phone for a week (I wanted to explore the new ‘Live’ feature) and found that there was a sharp decline in my productivity and mindfulness.</p> <p><strong>You've said before that you're a procrastinator, and that you're trying to focus on getting things done rather than making them perfect. Why do you think that's important?</strong></p> <p>I simply won’t get it done otherwise. One of the great things about running your own business is that there isn’t anyone telling you what to do. This is also one of the worst things.</p> <p>With a focus on getting it done, rather than getting it perfect, I can finish the task and iterate back to improve it.</p> <p>For example, in a project that we are working on for a Doomsday Tuna client we were able to save hundreds of development hours by implementing this. We worked to a minimum viable product model and produced the bare functionality requirements for a webapp. This was coupled with basic sketch ups from <a >Balsamiq</a>. From this initial work we were able to identify some key changes that needed to be made before we lost the time in development.</p> <p>This agile methodology applies so easily to software development and I have been exploring applying it to the rest of my work life. There is almost always a way that this iteration strategy can be implemented into the way I work. This mind set change from making things perfect to getting things done is leveraging my personality to work on the strengths I have; working like crazy to a timeline.</p> <p>It does require constant vigilance and self reflection to ensure that I am maintaining my focus on getting things done and not slipping into the ever seductive procrastinating perfectionist mindset.</p> <p><strong>You mentioned wanting to adjust the balance of time spent in your job and running your own businesses differently in the future. Do you have a definition in mind of what &quot;making it&quot; looks like to you? How will you know when you've made it?</strong></p> <p>I haven't got a concrete vision of what 'Making it' looks like. I don't think that there is ever a moment where you look around and think to yourself &quot;yep, I'm successful now&quot;. That might be the hardest (and most alluring) aspect of running your own business. It's not like in a traditional job role where you have external performance reviews and transition up a corporate ladder. You're building your own ladder and it's certainly not going in a linear fashion.</p> <p>My vague idea of &quot;Successful Future Stef&quot; is that she works part-time, runs the businesses part-time and has more time for other creative endeavours to spike my interest.</p> <p><strong>You also mentioned that you'd like to do more development work in the future. What's your background in development, and how have you balanced that with other types of work so far?</strong></p> <p>I am happy when I'm coding. Working on an intense problem takes me back to the joy and curiosity that I had as a child.?I love it.?However, I suffer from an intense case of?<a >Imposter Syndrome</a>?and have shied away from any level of development work in my day to day job. Going forward I want to change this balance.</p> <p>Last year I completed my Diploma in Website Design and Development. Whilst I had been slowly building up my skills outside of the course I was hoping that getting that certificate would do something to help with my confidence. It didn't.</p> <p>The only way to combat?Imposter Syndrome?is to get in there and do the work. So, I'm changing that balance. In my day job I'm taking on more development responsibilities. In Doomsday Tuna I'm taking an active part in completing our client work; not just finding more clients.</p> <p><strong>It's great that you enjoy your job enough that you don't necessarily want to work for yourself full-time—that seems rare! Are there any downsides to that? For instance, do you find it harder to focus intensely on one project when you're highly committed to both your job and your own businesses?</strong></p> <p>Absolutely.</p> <p>Without the drive of hating my day job I can lack the motivation needed to really double down on the hustle for Doomsday Tuna. I have the cushion of my weekly paycheck to fall back on when business slows down. The mental safety net means that I have to really force myself into finding new clients - because I don't HAVE to do it.</p> <p>We all have a finite amount of resources to spend each week and I'm giving a lot of that to my full-time job. That means I have less mental energy and time for my own businesses. If I have had a big day at work then coming home and working on a big project is one of the last things I want to do.</p> <p><strong>With so many responsibilities, what's it like when you need sick leave or want to have a holiday?</strong></p> <p>That is one of the great benefits to having a full-time role. Even when I'm unable to work or want to get away for a few days, I still have a paycheck coming in.</p> <p>I also have the wonderful support of a business partner in both Ivy and Joe and Doomsday Tuna. This means that even if I'm out of action for a couple of days there is still someone holding down the fort. I have the utmost respect for entrepreneurs who are running a solo ship.</p> <p><strong>As a co-owner of two businesses, what's your biggest struggle in &quot;making it&quot; as a business owner? And how does that differ from your main struggles in your job?</strong></p> <p>&quot;Making it&quot; as a business owner is more of a choose your own adventure story. You set your own hours, goals and motivations. That is my biggest struggle as a business owner lately. It's so easy to get caught in the day-to-day operations of the business without taking a step back to set the overarching goals of the business. That's just not something you need to consider when working for someone else.</p> <p><strong>And finally, you dunk your teabag a lot of times! Why do you like your tea so strong?</strong></p> <p>There is nothing worse than a weak tea!</p> <p>I think Doc Brown can sum it up better than I can:</p> <p><iframe width="560" height="315" src="" frameborder="0" allowfullscreen></iframe></p> <hr /> <p>Thanks for joining us, Stef! You can find more about Stef on <a >her website</a> and chat to her on <a >Twitter</a>.</p> Making it: Developer, designer, podcaster, and illustrator Daniel Farrelly, AKA &quot;Jelly&quot; <p><img class="img-responsive" src="" alt="Daniel Farrelly" /></p> <p>I've been internet friends with <a >Jelly</a> and a fan of his <a >podcasts</a> for a while now. I was lucky enough to meet him in person recently and put a face to the voice I've heard so much of. It was kind of bizarre.</p> <p>Since Jelly's work covers a variety of creative pursuits as well as development, I asked him to tell me a bit about how he got to where he is today and what his future plans are.</p> <p><strong>First up, can you tell us who you are and what you do?</strong></p> <p>Mostly, I’m an iOS and sometimes web developer from Canberra, Australia. I’m also an illustrator, designer, podcaster, writer, musician, husband, reluctant cat owner and tech enthusiast, though not necessarily in that order.</p> <p><strong>What does a typical day look like for you now? Is there anything you'd like to change about that?</strong></p> <p>Many days will involve me rolling out of bed at the crack of 9:13am, grabbing breakfast and a coffee, and diving head-first into code. I find I’m most productive if I can get a flow happening early; as soon as I introduce distractions into my mornings, I find myself fighting them for the remainder of the day. </p> <p>Sometimes distractions are inevitable, so I’ll leave open a secondary task in the hope that when I am distracted, I’ll be distracted by other tasks: responding to support requests, sketching out UI concepts, dealing with emails and the like. That said, some days you just gotta let yourself be free, so I might design an emoji shirt for kicks (just did the other week), or play games for an hour or two.</p> <p>Anything I need to leave the house for—meetings, errands, lunches—I’ll try to schedule for a given day in the week. Working alone requires at least some measure of social interaction, so it’s important, but keeping it all in a single day means I can have 4 days free of distractions, and a day where I don’t mind flitting from thing to thing.</p> <p>I’m a night owl, so I quite often return to my office in the evening to finish off anything left over from the day. This might just mean finishing off a code task and committing it, or it might mean sketching ideas out. Nothing too taxing, the idea is to wind my brain up for the evening, and occasionally give it some things to ponder while I dream of rainbow-flavoured toaster ovens.</p> <strong><p>You've used the username &quot;jellybeansoup&quot; for a long time now. Do you remember how you first came up with it?</strong></p> <p>You only need to look at the names of my apps to realise that I love a good play on words. My first memory of that was when our dog had puppies as a kid, and my sister and I named them. My sister named one “football” and I went with “jelly bean soup” because I guess we were kids?</p> <p>Clearly it continued kicking around my brain long after those puppies went on to other homes (with the exception of Football, who was renamed Sleepy, and I’m really not sure why my sister is allowed to name things), because I created a bunch of cartoon characters, one of whom had that same name (he had a brother named Pete Soup, which is totally normal).</p> <p>From there, I guess it was inevitable that it would become my online handle, and eventually the basis for the nickname used by everyone I know, including my wife.</p> <strong><p>How long have you been working on iOS apps? What was your journey like from starting out as a developer to going indie?</strong></p> <p>I started playing with iOS and Objective-C for the first time in around 2009, just after the 3Gs was released in Australia. <em>Progressions</em>, the first app I ever released, hit the app store in late 2010. So I’ve been doing this thing for a while.</p> <p>The journey from there to where I am today has been turbulent, for sure. I’ve made tonnes of mistakes along the way, and I’ve needed to spend time reflecting on my motivations for decisions I’ve made. I had to learn some basic things, like that I couldn’t take every freelance gig I was offered, and that I shouldn’t take the first full-time job that comes along just because I’m concerned about money. Good decisions can only be made if you allow yourself the space to consider the options you have, and I’ve always been one for jumping in the deep end and improvising.</p> <strong><p>Has anything surprised you about going indie? What are the main differences for you, compared to being an employee?</strong></p> <p>Working on your own stuff is immensely freeing. You’re not bound by other people’s requirements, and you’re free to make decisions as you wish. I love this about my work. My projects are an artwork, an expression of who I am, because I’ve carefully designed them, built them, and shaped what they are.</p> <p>Of course, that comes with its own downsides. I’m left with the reins when things go wrong, and when people critique what I’ve created, it can be difficult to divorce myself from my work, and not treat that criticism as an attack on me.</p> <p>Money is also an important consideration. Leaving traditional employment puts you on a path where your finances can and will fluctuate wildly. I’m blessed to have a wife who puts up with (and helps to smooth out) that aspect of our lives, and I work really hard—on both my own projects as well as client gigs—to make sure that we don’t suffer during the lean seasons.</p> <p>All that said, the hardest thing about being an indie is the independence; it’s very isolating. When you’re part of a team, you have people you can call on for advice and to bounce ideas off of, but when you’re by yourself, you can very quickly find yourself being overwhelmed by simple problems. I try to ensure I get plenty of social time, and reach out to people I respect and admire when I need guidance on something.</p> <strong><p>As an indie dev, how do you stay in touch with the iOS dev community? Do you end up spending a lot of time working alone?</strong></p> <p>The most important thing I ever did was start attending the local CocoaHeads meet up. The local group has never been big, usually only a handful of people, but the discussions, feedback and friends I’ve taken from those have been a hugely important part of my career.</p> <p>We would often meet up for a meal, talk about what we’re working on, toss in a little discussion of the latest Apple news and that would really be it. That may not sound like much, but it allowed me access to other developers’ insights, and that’s really invaluable when you don’t otherwise have it.</p> <p>Having made those connections, I now am able to use Slack and similar tools to ask people questions when I hit a wall, which has made my home office less of an isolation room, and more like working with a team… without having to be around people.</p> <strong><p>I'm always on the lookout for more diverse iOS developers to look up to. Do you have any diverse influences in the iOS community that you admire?</strong></p> <p>I’ve mentioned a few times lately that if <a >Erica Sadun</a> suggests that you should do a particular thing in Swift, you should probably listen to her. She’s incredibly smart, deeply involved in the Swift community, and she knows her biz.</p> <p><a >Rebecca Slatkin</a> is a very funny developer, and though she doesn’t often talk about what she’s working on, she makes for an excellent Twitter follow. She gave an excellent half of <a >a talk at Layers last year</a>, and I’m hoping we see more of her in the future.</p> <p><a >Linda Dong</a> isn’t a developer per-se (she’s a designer), but she was involved in <a >my all-time favourite WWDC talk</a>, and also delivered <a >an incredible talk at Layers last year</a>. She’s a great storyteller.</p> <p><a >Aleen Simms</a> knows much of the marketing side of things, and she’s a genuine champion for diversity amongst the iOS community. She tends to make me question some of my white-dude notions, so I’m terribly thankful for that.</p> <p><a >Yasmine Evjen</a> probably strays the furthest from the question, given that she’s a UX designer, and these days is a design advocate at Google. That in mind, she’s genuinely excited about Android (and burritos), and I like to expose my brain to some outside-the-platform thinking on occasion.</p> <strong><p>You've worked on a few iOS apps now. Where do you usually get ideas for your apps from?</strong></p> <p>I was the sort of kid growing up who spent four hours trying to automate mowing the lawn with ropes and push bikes, even though it would have taken a quarter of that if I just did it in the first place. If something annoys me sufficiently, I’ll try to figure out a way to make it easier for myself. </p> <p>All my apps have a similar story, in that they solved a problem that annoys me enough that I’m “forced” to do something about it. This approach has generally worked for me because other people have had the same struggle, so it presents an opportunity.</p> <p>For example, there was a time when sending GIFs on iOS was really quite a frustrating process. I’d search in Google, then save to Dropbox by saving to Photos first and exporting it, which would allow me to get a link to share. So I created an app called “QuickGIF” which showed me a bunch of images I had in Dropbox already, and that eventually turned into <a >GIFwrapped</a>.</p> <p>The most important factor is honing the idea, though. I toss a lot of them because I’m not going to be able to solve the problem in a better way than existing solutions—ropes and push bikes aren’t exactly going to solve my lawn-mowing woes—so it’s not really worth wasting the time.</p> <strong><p>You do lots of other creative work besides programming—writing fiction, illustration, podcasting, even creating a webcomic. How do you balance all these pursuits? Do they affect each other?</strong></p> <p>I balance them… carefully. Really it just involves learning to say no to certain things (which is harder than it sounds, trust me, I'm the <em>worst</em> at it), and in some cases just giving a passion project ten minutes when you can find it.</p> <p>I can't necessarily accomplish everything I want to do—there just isn't time to do it—so instead I try to inject opportunities into my daily work where I can. I've done a lot of illustrations for my various podcasts over the years, and I try to stick at least one illustration into every app I make (the animated one for <em>Other</em> is especially great). I like to make a big deal of writing my release notes for <em>GIFwrapped</em>, adding some fun and whimsy to make them entertaining as well as informative.</p> <p>Podcasting is a little different, in that it demands a certain amount of time and preparation, I can't record one on the couch while watching TV with my wife like I can with illustration or writing. That said, it's incredibly important to me because it's been part of my attempt to feed back into the community: to learn, to teach, and to interact with people. I'm happy to spend that time because I know it's not wasted.</p> <strong><p>You've done a lot of podcasting in the past. How do you think that's changed your experience of being an indie developer, if at all?</strong></p> <p>Podcasting, and Mobile Couch in particular, affected my development work in a number of ways, some of which aren’t immediately apparent. Obviously, part of that was that it gave me a platform, and made me more visible as a result, but that’s honestly the least interesting thing I took from the experience.</p> <p>The best thing was that it connected me with the greater iOS development community, and allowed me access to people I wouldn’t otherwise have met. Our guests taught me so many new things—from functional reactive programming, to working with fastlane—and my co-hosts taught me a lot too. Ben, Jake and Caleb are all incredibly talented developers.</p> <strong><p>Is there anything else that's surprised you about your career in general, that you didn't expect?</strong></p> <p>Honestly, the very fact I'm doing this at all is the most surprising. When I left school, my intention was to study film production and to become a director and screenwriter. I was doing a media production course here in Canberra, and doing a little web development on the side. It wasn't until after I dropped out of that course that I even considered that I might build software as a career.</p> <p>Even then, it’s surprising to me that I’ve managed to build what I do into any sort of successful venture. It doesn’t always feel that way, but I’m incredibly blessed (and privileged) to be doing what I am today.</p> <strong><p>We like to ask everyone what &quot;making it&quot; means to them. What does it mean to you? Do you feel like you've made it already?</strong></p> <p>I likely don’t fall into most people’s idea of successful when it comes to indie developers. I subsidise my App Store take with freelance work, and while I do have one oddly successful app, it’s by no means world-changing.</p> <p>I get to work on my own stuff, and when I’m not, the work is at least interesting. I get to do it from my own space, (mostly) according to my own schedule. I’ve made a number of amazing friends through the projects I’ve done, and I can blow off some time when I feel like it to have lunch with my wife.</p> <p>As far as I’m concerned, I’ve made it.</p> <hr /> <p><strong>Thanks for joining us, Jelly!</strong> You can learn more about Jelly and get in touch with him on <a >Twitter</a> or on <a >his website</a>.</p>西瓜影院-电影大全 - 高清在线观看 - 海量高清视频免费在线观看