Stuart Breckenridge

The Cheapest Smartphone in the World

Hitesh Raj Bhagat, ET Bureau (via the Economic Times):

February 18, 2016 will be an important day for the smartphone industry - at 6am, registrations for the Freedom 251 will start. Priced at Rs 251 (less than $4), it’s not just the cheapest smartphone in India - it’s the cheapest smartphone ever.

Just look at the app icons and home button. They look disturbingly familiar.


ASICS to Acquire Runkeeper

Jason Jacobs, founder of Runkeeper, discussing their acquisition by ASICS:

When we look ahead, it seems clear that the fitness brands of the future will not just make physical products, but will be embedded in the consumer journey in ways that will help keep people motivated and maximize their enjoyment of sport. By putting these two pieces together (digital fitness platform and world class physical products), you can build a new kind of fitness brand that has a deeper, more trusted relationship with consumers and can engage with them in a more personalized way.

Partnering with ASICS to fulfil this vision together makes a ton of sense. We both have deep roots in and focus on running as a core component of the fitness experience. There is strong alignment between our brands and core values. And from people using our Shoe Tracker feature in the app, we know that ASICS shoes are by far the ones that Runkeeper users run in the most!

From the end-user standpoint, not much will change. Not only will the Runkeeper product carry on, but we will be able to move even faster. We will be able to pursue the vision we’ve set out to pursue all along, with a partner that can bring many resources to bear that we couldn’t fathom having access to on our own.

My favourite running tracker and my favourite running trainer—I use the ASICS Gel-Kinsei 6—joining forces is good news. I’m hoping for discounts on merchandise in exchange for completing running challenges.

Related: Why I use Runkeeper instead of Apple’s Workout app.


Sparkle Framework Vulnerability

Dan Goodin:

Camtasia, uTorrent, and a large number of other Mac apps are susceptible to man-in-the-middle attacks that install malicious code, thanks to a vulnerability in Sparkle, the third-party software framework the apps use to receive updates.

The vulnerability is the result of apps that use a vulnerable version of Sparkle along with an unencrypted HTTP channel to receive data from update servers. It involves the way Sparkle interacts with functions built into the WebKit rendering engine to allow JavaScript execution. As a result, attackers with the ability to manipulate the traffic passing between the end user and the server—say, an adversary on the same Wi-Fi network—can inject malicious code into the communication.

If you want to find if there are affected apps on your Mac, run this command in Terminal:

find /Applications -name Sparkle.framework

On my Mac, Coda 2, Fabric, GPG Keychain, and Sketch show up as using the Sparkle Framework. However, it’s important to note that the vulnerability only works when updates are served over a non-HTTPS connection. With that in mind:

  • Coda 2 is not affected
  • Fabric is not affected
  • GPG Keychain is not affected
  • Sketch is fixed as of v3.5.2

Say what you want about the state of the Mac App Store, but this stuff hasn’t happened there.


Apple Special Event on March 15th

Matthew Panzarino:

Now, it looks like the date has solidified. March 15th is the date, according to sources, and we should indeed be seeing a rumored 4″ iPhone and a new iPad.

My bet is that we’ll also see the launch of iOS 9.3 with support for Apple Pay in Singapore, Hong Kong, and Spain (via Amex).


Thoughts on Apple Watch from Around the Web

Brent Simmons:

Here’s the thing, though: the Apple Watch contains a hundred miracles of engineering and design, surely, but serious problems with software and services can turn even the most incredible hardware into something you just sit on your desk and ignore.

Nick Heer:

I’ll add one more to the mix: since watchOS 2.0, I haven’t been able to launch native third-party apps on my Watch. Apps from TestFlight work fine, as do WatchKit apps, but native third party apps continue to experience an issue associated with the FairPlay DRM that prevents them from loading — they simply crash at launch.

Marco Arment:

The result is promising, but clunky and slow. It could be so great at its three most useful functions — notifications, activity tracking, and timekeeping with robust complications — if only they were more reliable and better executed. Someday, I hope they are.


Running Without Apple Watch Workouts

This week I’ve been running every day: five days on the treadmill and one day pounding the pavement. I could have used the Workout app on my Apple Watch to track these workouts, but it lacks basic functionality that all other fitness trackers have, which make it of little use to me.

#####A Lack of Context After completing any workout which is tracked by the Apple Watch, the resulting data set is shipped into Activity app 1 on your iPhone. From there you can see:

  • Type of Workout
  • Active/Total Calories
  • Total Time
  • Total Distance
  • Average Pace (plus Splits)
  • Average Heart Rate

Things you can’t see, which result in a lack of context:

  • Maps (for outdoor activities)
  • Heart Rate at any given point on a run
  • Elevation (for outdoor activities)

Maps are perhaps my most sought after feature. If I want to know where on a route I am gaining or losing time, they are essential. If I want to recall where my Saturday Morning Run was a year ago, they are essential. It’s something Apple could easily implement, given that they have their own mapping service.

These features are available–and have been for a long time–in competitor apps such as RunKeeper or Strava.

#####Inability to Edit Another bugbear is the inability to edit workouts logged by Apple Watch. For outdoor workouts, this is OK, as I’ve found the GPS to be accurate. For indoor workouts, it’s criminal. For every 5KM run I’ve completed on a treadmill, Apple Watch has logged it as somewhere in between 4.25KM and 4.75KM2. Once it’s logged, that’s it, forever inaccurate.

I’ve been using RunKeeper this week. Workouts has been a huge letdown.

  1. And the Health app. ↩︎

  2. This is after several hours of outdoor calibration runs. ↩︎


Matt LeBlanc to Co-Host New Top Gear

Via the BBC Media Centre:

Iconic American actor Matt LeBlanc has today been revealed as one of the new presenters of the upcoming and eagerly awaited return of Top Gear - the planet’s biggest motoring entertainment show.

LeBlanc’s appointment marks the first time the show has ever had a non-British host in its 39-year history.

In what promises to be an explosive cocktail of car-obsessed entertainers and cultural clashes - the eagerly anticipated return of the revamped show is expected to noisily announce itself on BBC Two and TV screens everywhere this May.

An inspired choice. I genuinely hope that the new Top Gear and the as yet unnamed Clarkson, Hammond, and May show, are good!


Innovation Time. Or Not.

Adrian Kingsley-Hughes for ZDNet:

…Apple is facing a challenge that it’s not previously faced with the iPhone, and that is that sales have plateaued.

Have they? Based on the results of one financial quarter this is quite a statement. I’m sure it takes into consideration the pent up demand that existed for larger screened iPhones that resulted in huge sales for iPhone 6 and 6 Plus. I’m sure it also takes into consideration the 60%1 of users on pre-iPhone 6 devices that haven’t yet upgraded.

On the subject of the innovation needed for the iPhone 7:

Think there’s not much left that Apple could do? Think again! Here are just a few ideas off the top of my head:

  • Waterproof iPhone
  • More durable iPhone
  • VR integration
  • New battery technology
  • Built-in health sensors
  • Gesture control

Waterproofing has been attempted by Samsung and Sony, where it was abandoned by the former and discouraged by the latter2. The iPhone 6s is waterproofed to a degree; making it fully waterproof can’t be classed as innovation.

Is there a durability crisis with iPhones I’m not aware of? Does the use of stronger Gorilla Glass not make iPhones more durable? Or, for that matter, the use of stronger aluminium3?

VR is interesting, but what is the use case for integration in an iPhone and how would it work? VR, to me, makes no sense on an iPhone.

New battery technology: moving from Li-ion to something newer, longer lasting, and faster charging would be innovative. No disagreement here.

Health sensors for a device that’s mostly in your pocket? How would they work?

Gesture control is nothing more than a gimmick. Importantly, gesture control is not innovative as it’s been done before.

It’s a strange set of feature requests, to say the least.


Dev Notes - Questions and Answers

As a little side project, I am rebuilding my long forgotten app Amazing Flag Quiz. I don’t have the original source code, so it’s all being done from scratch. My current task is working on the question and answer model. There are few things it needs to do:

  • generate an array of questions (each element a Question) based on the user’s selected continent (e.g. Europe, Africa…)
  • each Question must contain the correct answer and three wrong answers
  • the array of questions and each Question’s answers must be randomised.

Before getting into coding the app properly, I’ve thrown the below together in a playground.

I have an array of all countries:

let allCountries = ["Afghanistan", "Akrotiri", "Albania", "Algeria",...]

My Question class contains a correct answer and three wrong answers, held together in an Array:

final class Question {
    let correctAnswer:String
    var questionOptions = [String]()
    
    init(cAnswer:String, qOptions:[String]) {
        self.correctAnswer = cAnswer
        self.questionOptions = qOptions
    }
}

To track which game option the user picks, I’ve created an enum:

public enum GameOptions
{
    case All, Africa, Americas, Asia, Australasia, Europe, BritishEmpire, USStates
}

Finally, in order to create a list of questions, I’ve created a protocol with a default implementation:

protocol Questionable
{
    func questionsForOption(option:GameOptions) -> [Question]
}
extension Questionable
{
    /*
     Based on option, will generate and return an array of Question objects.
     
     - parameter option: GameOptions selected by user.
     
     - returns: [Question]
     */
    func questionsForOption(option:GameOptions) -> [Question]
    {
        switch option
        {
        case .All:
            var allQuestions = [Question]()
            for q in allCountries
            {
                allQuestions.append(Question(cAnswer: q, qOptions: populateOptions(q)))
            }
            
            // Shuffle 
            return GKRandomSource().arrayByShufflingObjectsInArray(allQuestions) as! [Question]
            
            /* ... */
        default:
            return []
        }
        
    }
    
    /*
     Populate answers for question.
     
     - parameter correctAnswer: String
     
     - returns: [String]
     */
    func populateOptions(correctAnswer:String) -> [String]
    {
        var countrySet = Set<String>()
        countrySet.insert(correctAnswer)
        
        // Get four unique random answers
        repeat {
            let i = GKRandomDistribution(lowestValue: 0, highestValue: allCountries.count - 1).nextIntWithUpperBound(allCountries.count - 1)
            countrySet.insert(allCountries[i])
        } while countrySet.count < 4
        
        // Add answers to an array
        var options = [String]()
        for c in countrySet{
            options.append(c)
        }
        
        // Shuffle answers
        return GKRandomSource().arrayByShufflingObjectsInArray(options) as! [String]
    }
}

In terms of usage, I need to generate questions and answers when my GameViewController appears on screen, as part of viewDidLoad, as shown below:

class GameViewController:UIViewController, Questionable {
    
    var list = [Question]()
    
    /* ... */
    
    override func viewDidLoad() {
        super.viewDidLoad()
        list = questionsForOption(.All)
    }
}

I’m satisfied with this solution: it’s less than 100 lines of code and is easy to follow.

I seem to remember this being much harder when I wrote Amazing Flag Quiz originally and I’m mindful of what Henri Cartier-Bresson once said:

Your first 10,000 photographs are your worst.

That applies to your first 10,000 lines of code as well.

Next up: presentation logic.


Parse to Close

Kevin Lacker:

We have a difficult announcement to make. Beginning today we’re winding down the Parse service, and Parse will be fully retired after a year-long period ending on January 28, 2017. We’re proud that we’ve been able to help so many of you build great mobile apps, but we need to focus our resources elsewhere.

We understand that this won’t be an easy transition, and we’re working hard to make this process as easy as possible. We are committed to maintaining the backend service during the sunset period, and are providing several tools to help migrate applications to other services.

While Parse will be releasing a migration tool to assist with moving existing data to any other MongoDB database, the fact that it is closing will come as a huge blow to developers who make use of the platform.