Tag: Programming

  • iOSNext: Paul Ardeleanu – 10 Reasons You’ll Love Swift

    My notes from Paul‘s talk at iOSNext.

    Swift: A new programming language for iOS and OSX

    TIOBE Index for Nov 2014 – Swift is at #18. A language that is 5 months old – more popular than Scala, Haskell… Fortran!

    Proven to be quite a hit with developers, and there are reasons for that.

    Why do we have a new programming language?

    What is the most important thing for Apple? Most important thing is the stock price, has a legal responsibility.

    Apple passed 120 price, first company valued over $7B, most valuable company in the world.

    Make money with good hardware. Most money made selling products. To have successful product, needs successful software. Need successful app stores.

    In app stores have millions of apps. Who writes them? Apple needs developers?

    How do you make sure you have the best developers in the world

    • Keep existing ones happy.
    • Attract new ones.

    Objective-C:

    • 30 years old. Has evolved (blocks, ARC etc).
    • Drastically different – teaching Objective-C, have to tell people to use square brackets.
    • Not entirely future proof.

    How did this happen?

    • Seemed overnight, but signs for the last 4 years.
    • Go on LLVM, see commits, and swift mentioned, but none knew what it was.
    • GCC -> LLCV-GCC -> LLVM.
      • “What if we had Objective-C without the baggage of C?”
      • “Apple just sherlocked my CV”
      • “We are all of us beginning again”

    What if you get Objective-C without C? You get Objective. Doesn’t make sense.

    10 Reasons You’ll Love Swift

    1. No C. No main() function. No [] or ;
    2. Modern. Tuples. Nil coalescing operator.
    3. Safety. Constants and variables. Don’t specify the type – inferred. No implicit conversion. Switch – must be exhaustive.
    4. Optionals.
    5. Mix and match. Can use Objective-C and Swift together in the same project.
    6. Functions are first class citizens.
    7. Magic.
    8. Emoji. If this evolves, might be a good way to teach kids programming – highly visual.
    9. Playgrounds
    10. Swift REPL

    Like new language. Will be awkward, will feel frustrated. But eventually you’ll get it!

  • Four Reasons Unit Testing Needn’t Be That Time-Consuming

    danbo switches
    Credit: Pixabay / herryway

    On my mind this week because I’m giving a workshop and a talk on unit testing UI code on iOS.

    Tests as Documentation. You think you remember what you did and why… but you don’t.

    Replace debugging. I almost never use the debugger. If something isn’t working as expected, I just start writing tests and figuring out what is going on. When the bug is fixed, and I’m berating myself for being stupid enough to write it in the first place, or not figure it out sooner, I also have a bunch of tests to show for the time I spent.

    Low energy. Seriously there is no 10x engineer, and none of us function at 100% all of the time. I used to rationalise that I should stop work before I start breaking things. But now when I know I’m not going to be effective at creating I test instead. Maybe I’ll write the thing tomorrow morning, but this afternoon I stub the method and write the tests for it.

    No perfection in testing. I’ve mainly seen “we should do it this way it would be better, but that requires us to refactor all the things” argued in places with poor test coverage. I think the point is, do you write a test at all? If a test is stupid, it will take seconds to write and you’ll never need to worry about it again. There is no need to worry about the size of your test binary. Speed, yes, but that is far more determined by integration tests than unit tests.

     

    If you want to improve testing of your iOS apps, I have put together a digital workshop.

  • Cross-Platform Development Decisions

    Screen Shot 2015-02-17 at 5.14.01 pm

    I’ve started to port Show and Hide to Android. There’s still a lot to do, but I hit a milestone of having it working end to end on the emulator last week, which was exciting.

    One of my friends asked if I was using any libraries to make it easier, and the short answer is no. But I think the long answer is potentially interesting so here it is.

     

    1. I want to learn Android

    I don’t think there is a better way to do that than building an app from start to finish on that platform. The more libraries and bits and pieces you work with, the more you learn the intricacies of that system, rather than the platform itself.

    Sometimes that is exactly what you should be doing. There’s often no point doing something that has already been done. But cross-compiling isn’t re-implementing something that exists already, it’s choosing to write something a third way and hope it works well enough on both platforms (more on this later). At this point, if I haven’t written an entire app already, I don’t think I can really have the information to  just decide that cross compiling is the way to go. How could I compare the experience to a problem that I haven’t solved?

     

    2. UI Code

    Fundamentally there are two reasons why I don’t think we will ever have a good cross-platform UI solution. The first is that with major releases every year, it would be a huge amount of work to maintain such a thing. Almost no-one has the resources to run such a project, and of those that do even fewer have the incentive. The second is that the UI patterns on iOS and Android are different enough that what is “right” on one platform won’t feel “right” on the other.

     

    3. Non-UI Code

    Here I think there can be a good argument for a cross platform solution, depending on what you’re doing. Libraries like Parse are interesting, making it easier to abstract persistence and networking out and share it.

    But – the core of Show and Hide on iOS is about 400LOC of optimised C code that is tied to the way that the platform represents images. I don’t even know if that would be possible to share x-platform, and the chances of it being performant enough for my purposes is vanishingly small.

    Because it’s a relatively small amount of code and I deeply understand it, moving it to Android took only 1-2 days. I’ve yet to see whether it is performant enough, but this way I’m also in a much better position to optimise it.

     

    Porting the Architecture

    Instead of using cross-platform compilation what I’ve been doing is:

    • Building the UI according to Android best practises (or trying to).
    • Keeping (initially) the same function definitions for non-UI code.
    • Changing the implementation to make sense on the platform – e.g. the way that iOS and Android represent images are completely different.

    This means that:

    • The two apps have very similar architecture – the same objects, with similar methods on them.
    • The unit tests are near identical: given this input expect this output.

    It’ll be some time before I can declare success on this as a strategy, but I’m cautiously optimistic.

  • Some Things I’ve Learned About Performance on iOS

    Filed under “things I didn’t realise anyone else would find useful”.

    Screen Shot 2015-01-26 at 3.31.36 pm

    The Hybrid App

    The second iOS app I worked on was a hybrid app, and I became a master of the UIWebView. It looked native. But it didn’t quite feel native because… performance.

    We had a bridge that connected the iOS to the Javascript and vice versa. A fairly horrible solution, but this was back when people believed native apps were just a stop gap until the web won, and that this product didn’t really matter on mobile, anyway.

    Eventually we discovered that passing data across when calling Obj-C from Javascript was really slow but that calling a Javascript getter from Obj-C was just fine. Crisis averted.

    The Location Tracker

    This one had a myriad of issues. In theory, the API says you can just register for location updates with accuracy. In practise, if the accuracy is… accurate (<150m, if I recall correctly) the GPS turns on, stays on, and the battery rapidly runs down.

    Even if the phone is sat on your desk, not moving (one would have thought the accelerometer would be useful here, but no).

    So the answer was to operate with the GPS off most of the time, and then after a notification turn it on again for a limited period.

    Then there is the sheer volume of updates you get. If you just send each one with a network call, then… that’s a lot of network calls.

    So instead at each point you have to decide, should I send the update now, or wait for better accuracy. Meanwhile, cache the unsent ones.

    Now you have an app that is running in the background, and being awoken when there’s an update. But if the app gets kicked out of memory, all your unsent locations are lost.

    Fun story – we had it just about working and then I went to Kangaroo island which has terrible cell-phone service, and was taking loads of pictures. So even though I was intermittently on the network, hardly any locations were being sent because the camera was causing the app to be kicked out of memory.

    Basically: we had to implement persistent storage for location tracking to work.

    The Image Processor

    This app was handling a quantity of data (pixels) and had time and space problems.

    To reduce the memory usage, I got rid of as many Objective-C objects as I could, and replaced them with C. So the NSArray of NSNumbers became a CGFloat[]. Stopped using UIColor and started working with raw RGB values.

    Memory footprint reduced by around 66%, and the app became much, much faster.

    (I wrote all the tests on slower and easier to read code, which helped a lot with this process).

    Major problem here was how little information there was on the internet. I’m not an expert C coder, and I would look for how to do something in C within Objective-C and the answer was typically “there is almost certainly no need for you to do this“.

    The other performance improvement I made was to break up the processing work and do some pre-processing in the background thread, so that the wait is split into two very short waits, as opposed to one, slightly longer, wait.

    Things I’ve Learned

    Find the One Thing

    There’s not, in my experience (assuming you’ve been sensible around the basics of ARC, table views etc) any need to go through your code looking for “things to optimise”. iOS is mostly pretty good. The problems I described above all occurred in the most non-standard places of the app. Getting a deep understanding of how that thing worked was how it was fixed (aside from the first one, which I still think is just weird).

    The Profiler is Not That Scary

    Memory allocations is the one I’ve been working with most recently, but there is also a way to profile which parts of your code most time is spent in. I can see this being really useful. I used to be really intimidated by the profiler, but having spent more time with it, it’s OK [helpful tutorial].

    Performance Tests are Easy, but Slow

    I started adding performance tests, typically at stress sizes (10x the data I expect to process), using the (void)measureBlock:(void (^)(void))block function in XCTestCase [more info]. Each performance test runs 10x to give variance, and you can save a per-device baseline. Because these are my most time consuming tests I don’t want to run them when I’m developing against my tests so I moved them out into a separate target (that takes a few minutes to run) so that my core test target runs faster (<30 seconds).

  • Getting KIF Set Up

    Kif tests running

    Continuing my obsessive testing strategy, I had to set up KIF for UI Automation Tests. Honestly it’s surprising I didn’t do it earlier, but since the UI is very simple I was getting better ROI doing unit tests – I see KIF as a sanity check, not as a way to debug anything.

    Step 1: I went through the app with the Accessibility Inspector on and made sure everything had an accessibility label.

    Step 2: I made a new test target for KIF tests, and made sure it ran OK. I made a mistake at first and created a Mac testing bundle rather than Cocoa touch (I don’t know why it was even on that screen, I have never made a Mac anything).

    Step 3: Added KIF as a submodule.

    Step 4: Followed these instructions (which are very good).

    Step 5: Trying to debug baffling error messages about pulling in SenTestCase which shouldn’t be required because I’m using XCTest (the default). Adding it as a dependency out of desperation, getting duplicate symbol errors. Some time figuring out what an #ifndef does (basically – if defined). Feeling very discouraged.

    Step 6: Pair programming (or, pair-debugging). In desperation, as we have no other ideas, I delete the (theoretically unused) OCUnit targets. Everything works. I am enraged. We are both confused.

    Step 7: Check in time! Oh wait, it’s not, because I have edited a submodule.

    Step 8: Fork KIF. Delete the two OCUnit targets again (here’s the repo if anyone else needs such a thing).

    Step 9: Replace the official submodule with my submodule. Realize I now need to keep these in sync. Forever. Why do we programming.

    Step 10: Sync. Everything works again.

    Step 11: Write some KIF tests. This takes approximately 5% of the time I spent on getting everything set up.

    Step 12: Go to the gym for several hours. Forget what happened.

    Step 13: Next thing on the TODO list.

     

  • #iOSDevUK: Hamish Allan – The Pareto Principle

    80/20 modular framing
    Credit: Flickr / Alexander Pfeiffenberger

    App store offered a way for people who were interested in writing software to make money from writing software.

    Have recently found need to do more advertising. Even more recently, take on more and more contract work.

    Identify as devs, but need to learn more sides of running a business. Pareto principle is thing that can help here.

    What is it?

    • 80:20 rule of thumb.
    • Doesn’t have to be 80 and 20.
    • Doesn’t even have to add up to 100.
    • 80% of effects come from 20% of causes.
    • Cause and effect are not necessarily linearly related

    Vilfredo Pareto

    • 80% of the land is owned by 20% of the people.
    • Economics based on observation, transformed into scientific discipline.
    • Adam Smith was more of a philosopher.
    • 80% of peas come from 20% of pods.
    • In 1980 countries with richest 20% of world population had 82.7% of GDP.
    • Up from 70.2% in 1960.

    If you have an 80:20 rule, alpha param has a value of about 1.16.

    Project Management

    • 80% of value is achieved with the first 20% of effort.
    • The last 20% of an app takes 80% of the time to write.
      • If writing a mail app, got table view done, might think 40% done, but only 1/600 of the way there.

    Your own apps

    • Five 80% coplete apps versus one 100% complete.
    • Ask, should I be writing more apps?
      • Do you write one app and make it the best you can, or diversify.

    Contract Work

    • If possible, avoid estimating for completed projects.
    • Easier to estimate 80% of what they want.
    • Bid for a phase 1. 80% of what they want, in 20% of time.

    In Engineering

    • 80% of bugs in 20% of code.
    • A large number of bugs come from a small number of classes of bugs.
      • E.g. memory management. Arc destroyed a large class of bugs that took up so much time.
      • Multithreaded programming. Dispatch queues address this.
      • Asynchronous programming.
      • Type safety (swift).
    • 80% of processing time is spent in 20% of code.

    Design

    • 80% of your app’s usage is 20% of it’s features.
    • Optimize for the common case.
    • Especially at resume time.
    • Be opinionated
    • Especially if you change rather than just adding.
    • They will ask you to add a switch in settings. Try not to do that.
    • Paradox of choice – if you present a lot of choices, it stresses them. Makes the app less usable for them.
      • Developers might be OK with it but a lot of people find it stressful to be presented with so many choices.

    Support

    • 80% of your support is for 20% of your customers.
    • Check if they haven’t paid and ask for support.
    • Like getting blood from a stone. Try and engage in a conversation just don’t.
    • Answer terse emails briefly.

    Sales

    • Not quite as applicable on the app store because leads don’t work the same way.
      • 80% of sales come from 20% of your products.
    • 80% of your clients come from 20% of your leads.
    • Don’t do too much work for free.

    Productivity

    • 80% of work is copleted by 20% of individuals.
    • 80% of work is completed in 20% of an individual’s work hours.
      • Hard to optimise for that, downtime is important for perspective.
    • Best teams have people who can code quickly, and people who are always trying to put the breaks on and take a wider perspective.
      • Need both of those types of people and everyone else in between. Or individuals taking both of those approaches.

    Bunch of places where you can apply. Helpful for people who want to make a business coding.

    You must measure. It’s a discipline. You can make assumptions about where the low hanging fruit are, but until you measure you don’t know.

  • Getting Started with Adobe Air (or, trying to)

    birefringence stress plastic
    Credit: Wikipedia

    Recently I had cause to play with Adobe Air, which I missed when it was popular and it’s been pretty hard to find out what is actually going on with it as much of the information is out of date, other than Adobe’s corporate PR engine.

    It’s supposed to make it really easy to create apps that work on the web, desktop, iOS and Android. Which is a cool story I’m sure I’ve heard before.

    The first step was installing it, but after much confusion I discovered I had just installed the runtime, and not any way of actually creating apps. So in spotlight I find the installed, and the uninstaller, but not the actual thing.

    OK great, so now I just need a development environment. The first recommended one I found was AptanaStudio. Except Air is not supported in Aptana 3, the latest one (I discover this, of course, after I have downloaded, installed Aptana and it is refusing to close on my machine – good feelings).

    New way: install the Aptana Plugin for Eclipse and then separately the Air Plugin. This might be the Flash Builder plugin, but given the last mention of this is from 2008, maybe not. More research uncovers that Flash Builder plug in doesn’t work with versions of Eclipse above 3.6. Eventually I find that the Aptana Plugin has it’s own set of plugins, once of which is the Air plugin. But Aptana again barely works.

    I end up downloading a trial of Adobe Flash builder. I’ve realised that the bit on the Adobe site that says you don’t need to buy tools from them to develop Air is a lie. Because Air is out of favour, only Adobe is updating their dev tools. Unless you are on Windows, where you can use FlashDevelop apparently.

    Luckily they have a one month free trial.

    In all, my instructions for getting started with Air:

    1. Don’t.
  • #iOSDevUK: Steve Scott: Sherlocked! Deprecated! Changed! AKA “Do Apple Hate Developers?”

    rose tinted glasses
    Credit: Flickr / derekgavey

    Helpful to take a step back and see where we are.

    We all tend to view the world through rose tinted glasses. Depend to look through a lens that colours what we are seeing. Unless take them off, hard to see what the situation is.

    Glasses worn by iOS is “we are indie devs”. Sense in community, the little guy, hacking away on the porch or in the evening. Stood for a long time, back when it was actually true. Now maintained even though probably one of the biggest communities of devs in the world.

    Not unreasonable. Vast majority of companies producing apps are very small. Even “big” less than 30-40 people.

    Is a sense of being small, see things through the lenses of being small.

    When we look at Apple, relate to the apple that was Steve and Steve in their garage hacking. All about innovation, friendliness, camaraderie.

    We see Apple, we like to see Apple. The Apple we want is the Apple of this 70s breakthrough, this small indie thing. However reality is, Apple is (depending on day of week and season of year) is one of the biggest companies in the world. No longer based in a garage somewhere in California. The thing that is most important to them is the stock price. This is true, because the law says it has to be. Has an obligation that every decision you make is in the best interest of your shareholders. If can be shown not, you can be imprisoned.

    “How does this effect us as a public company” – reality, shareholders come first.

    Not everyone. But Apple as a company, this has to be what it is about.

    Have to ask, how can we make the best investment for investors. If you go to their website, clear they have done that by deciding to be a hardware manufacturer. Click around for a long time before any mention of software.

    Chosen to make money through hardware. Strategy – build fanatical customers, who love the hardware. Carefully decided. Look at the presentations, the words they use.

    “The every day man’s designer brand” – slightly more than most people than they can afford, but within reach.

    Would never do a low end laptop, because it would destroy that brand. Target people with aspirations. Hence the margins on their laptops.

    Strategic decisions are around these things. And nothing else. Desirable to customers. Maintain brand. Bottom line.

    Apple are not the friendly garage of indie devs. They are a moneymaking machine.

    Faster accept that, the easier it is to deal with reality.

    Not going “developers developers developers”

    Don’t hate developers. Just not their priority.

    Do Developers Hate Developers?

    Open source projects:

    • How many have considered users in code open sourced.
    • How many have sent money?
    • How many have contributed a significant fix or amount of code?

    Argument hear again and again is “Apple should look after us as developers because we make significant contribution to their business”

    Financially: tiny. So small they wouldn’t notice if it disappeared.

    App ecosystem does enhance Apple’s attractiveness to customers. Will place some value for that reason. Because it creates value for customers who they want to be fanatical about their products.

    As developers, the very people making that complaint, we don’t stop to think about people who are producing code that makes a significant contribution to the things that we make. Bit of a hypocrisy. If want that to be true, need to value people who make a contribution to people who help their code.

    Don’t hate devs. Just value customers more than you.

    Love

    Love is not about what you feel, it’s about what you do. It’s in your actions and your deeds.

    Sherlocked. Apple have Sherlocked a number of apps. (Replacing a dominant player in the market as an independent – Watson replaced by Sherlock).

    Not mean, evil, but because they want to give something to their customers. Just a business decision. Just an attitude about them making better products.

    Deprecated. Deprecation is a curtoursy to devs, could just remove the API altogether. Good for customers, because forces things to do things in a better, more efficient way.

    Microsoft for many years refused to deprecate anything. People are still running things on XP because they thought they must never get rid of anything that breaks anything. So we all had to live with an OS that is full of crap. So much was there for legacy purposes. But it didn’t make a good product. Better for people who were no longer giving MSFT money than for people who were (buying).

    Not about devs. About building a better product for customers.

    Changed. That is exactly why things change.

    How do Apple Love Developers?

    Apple, iOS dev centre membership. $99. Charge again to do the Mac. How much does it cost Apple to provide with what they provide? $99 doesn’t cover it. Nowhere near.

    Apple known for small teams, people often shocked by how few people work on something. Doesn’t matter. Have very clever, very expensive California devs working on things for your benefit. Subsidising your career. That is how much they love you.

    Windows, you pay 1200GBP every year for Visual studio and MSDN subscription. And that is still a subsidised price.

    Next time you complain about the App store pricing. Remember if going to do that, going to start charging a realistic price for tools.

    Short while with Mac app store. Xcode was $4. Was like the world had ended. “How could they charge me $5 for the thing that I make my living from?”

    Apple understand value of devs, charge very little for tools that allow you to do your job.

    Not because love you, but because you create value.

    WWDC videos. 2006 would wait months for vids, be delivered on DVD. Apple gained nothing by investing millions of dollars in ensuring you can get the videos on the same day. Investing in you, because it helps them. If you have the latest information, can upgrade your apps faster.

    Whichever title. Reality is. They understand your value, and provide reasonable practical support without taking their focus off of their main business and their customers.

    Hopefully just like you do.

  • In Defence of Static

    Picture of my app working after I fixed a bug... using extensive unit tests.
    Picture of my app working after I fixed a bug… using extensive unit tests.

    Maybe it’s my functional programming background, but I love static methods. Not everyone gets this, some people parrot the phrase “static methods are bad for testing” but don’t seem to understand what that means.

    Static methods are great for testing. Inputs in, outputs out, side effects – what side effects? What’s not to love?

    What they are bad for, is mocking. This is an entirely different problem.

    Note: here I’m using static to mean methods without side effects, which technically includes Objective-C methods that are denoted with a + (class methods). Turns out, these methods are not technically static, they take place on another object [detailed explanation]. Static methods in Objective-C should properly be C methods.

    Also, you can mock class methods, in OCMock by using: 

    id classMock = OCMClassMock([SomeClass class]);

    When and Where

    I’ve been doing a bunch of image processing work lately, and it looks like this:

    • Break image down into pieces.
    • Do stuff to it.
    • Put it back together.

    Each of those things individually are great for static methods. Take an image, break it down – do I have the requisite pieces? Put some pieces through this process, is the result right? Given some pieces, do we get an image with the right properties? Wonderful.

    I’ve spent hours (OK, days) writing tests for these things, because I was not an expert on image manipulation and in my opinion there is no better way to deeply understand code. I found and fixed a horrible bug. Next, I need to optimise, but my thorough test suite gives me confidence that I can do this refactoring without breaking things, and that I have a good API.

    But – I don’t want to deal with this elsewhere in my app. So I absolutely want this stuff to be mockable. So I use a very simple pattern:

    • Expose a class method that updates the object.
    • Have a static method that takes whatever information is necessary, and returns whatever needs to be updated.
    • Class method calls the static method with the requisite information, and updates itself accordingly.

    This becomes easy to test. My static method has tests that cover a full range of inputs and outputs. My class method just needs a single test to ascertain that stuff gets updated.

    When I’m mocking this object, I just mock the class method. The static one never gets called.

    Some people’s irrational loathing for static methods can cause problems in code review. If you don’t want to argue, two options:

    • Split the static methods out into a “MyClassHelper” object. For larger things I do this to be tidy.
    • Just don’t declare the methods as static, but use them as such following this pattern – I really don’t like having to do this. But I have done it.

    Other People’s Static Methods

    The main issue I run into with static methods, is that other people have used them – I find it is common in API design when classes shouldn’t be subclassed.

    In this case, I group things together logically in a wrapper. For example, in my current project I have a class that wraps various static things I need for handling images.

    Coverage vs Confidence

    I am a proponent of code coverage, and regularly use it to guide me to the places in my code base that need a bit more love and understanding. But it’s important to note that coverage doesn’t necessarily mean confidence.

    If you have a (say, static!) method that takes a test image and returns an array of length 9, and you verify at the end of it that the array is indeed of length 9, voila you have coverage. What you don’t have, however, is confidence. What are the 9 things?

    In part for this reason, I start small and work up incrementally. If I start writing a large test and get confused, I break it down and write a small one first. So in this case I might write 3 tests:

    1. The result has 9 things in it.
    2. The 9 things are correct.
    3. The completion block gets called.

    So if I break the test and 9 things are no longer produced, tests 1 and 2 will both fail. If I break it and 9 wrong things are produced, just test 2 will fail. If I accidentally delete the line that calls the completion block, just test 3 will fail.

    So when I break something, multiple tests will fail, and the simplest one that is failing will be where I go first to determine what I’ve done.

    The other thing about confidence, is that tests should break when you change stuff. The other thing I use to improve my code confidence is when I make a change that doesn’t result in failing tests and I think it should, I go and write some.

    TDD Wut?

    I don’t often do pure TDD, when testing UI code I expect it would be difficult to the point of not being worthwhile, or in some cases not even possible. Occasionally I TDD, if I’m trying to figure out how something should behave I will start with test cases. More commonly what I do is:

    1. Write the simplest thing.
    2. Write tests for it.
    3. Refine my code, optimise it etc.

    I used to employ this strategy a lot when I was writing lots of Guava. I adore functional programming, but a nested for loop is easier to read, understand and debug with print statements if necessary! Because at least initially, it’s nearly as likely that I have made a mistake in my test as in my code.

    TL;DR

    Static methods are great. Hide them away and they make testing easier, not harder.

     

    Thanks go to Martin, for reviewing a draft of this post.