MacBook 2015 released with 12″ Retina Display. My Thoughts & Comparison

design_retina_large

On 9th March 2015, Apple announced (among other things…) an all new MacBook, I won’t go into the marketing details as you’ll find those everywhere else. Essentially however its an ultra low power, ultra light, 12″ MacBook with a Retina Display. As a heavy 11″ MacBook Air user I can confidently say I think they’ve really pulled it out the bag this time.

Firstly looking at the overall dimensions of the 12″ MacBook I was very surprised to see its smaller than the 11″ Air (just about) in every dimension, whilst also being lighter and having a 1″ bigger display.

Device Height Width Depth Weight
2014 MacBook Air 11″ 0.11-0.68″ (0.3-1.7 cm) 11.8″ (30 cm) 7.56″ (19.2 cm) 2.38 lb (1.08 kg)
2015 MacBook 12″ Retina 0.14-0.52″ (0.35-1.31 cm) 11.04″ (28.05 cm) 7.74″ (19.65 cm) 2.03 lb (0.92 kg)

To summarise, the thinnest part of the MacBook is thicker than the thinnest part of an Air by 0.05 cm (which perhaps is a good thing if you’ve seen how thin and almost transparent the MacBook Air 11″ display is) and its slightly deeper, apart from that its almost identical in its dimensions, which is great if (like me) you’ve invested in bags/sleeves and the likes, all your non-technical accessories will still work.

Additionally its battery life estimates and tech specs are very comparable if not identical to the battery in the 11″ MacBook Air. Meaning you get your retina display without any compromise… Except one…

The next part of this post is purely speculation until proper benchmarks arrive, however, after some digging into the Intel Core M, i’ve noticed only 5 Broadwell architecture CPU’s exist and one in particular matches the top spec CPU mentioned by Tim Cook in the Apple Keynote almost identically. I’ll take a look at that top spec CPU vs the top spec CPU of the 11″ MacBook Air.

Device CPU Power Cores Benchmark
2014 MacBook Air 11″ Intel Core i7-4650U 15W Max TDP 2 (4 logical) 4156*
2015 MacBook 12″ Retina Intel Core M-5Y71 4.5W Max TDP 2 (4 logical) 2780*

* according to cpubenchmark.net

What this shows is the 2014 MacBook Air 11″ in its top spec config scores 66% higher than the 2015 MacBook 12″ Retina. However what it shows me is that trade off has been made in choosing an ultra low powered CPU to maintain battery life whilst giving the user a Retina Display. Remembering, the benchmark used isn’t a real world scenario, its more of a point scoring benchmark and additionally, I have no idea what CPU the new MacBook 12″ Retina actually uses… This is just an intelligent guess. Interestingly again, both CPU’s support up to 16GB Memory, however the configs at Apple top out at 8GB.

Nevertheless if price wasn’t a factor, it’d be really tough to choose an MacBook Air 11″ over a MacBook 12″ Retina. Having a black bezel, retina display, edge to edge keyboard really sells it here for me. I was happy with the existing size of the MacBook Air 11″, but every little helps. Mondays keynote was the first time I truly agreed with and believed Jonny Ive when he said something along the lines of “we’ve really tried to optimise the efficiency of the MacBook’s design as much as possible”.

 

The next thing that sparked by interest was the inclusion of USB-C for… everything, (for those who don’t know, its a new USB standard that allows power, data + different standards over a single cable). I travel a lot and although my Air rarely runs out of a battery when i’m out of reach of a power outlet, its interesting to think that you could buy a 29$ USB-C to USB cable and potentially charge your MacBook 12″ Retina using the same portable battery pack you use to charge your iPhone / iPad, it is to be confirmed, but i guess it wouldn’t be reaching far to expect this. UPDATE: I can confirm you can charge your MacBook 12″ with a portable battery pack you use for your iPad/iPhone. 🙂

Power pack charging MacBook

 

[follow_me]
Those are my initial thoughts beyond the keynote and various tech blog info out there and i’ll try to update this post once my Space Grey top spec MacBook 12″ with Retina Display has arrived and i’ve (with sentiment) retired my trustworthy and fantastic MacBook Air 11″.

 

SuperRecord an ActiveRecord implementation in Swift

All the media buzz around swift seems to be having some tangible effect. I won’t go into the opinionated slaw of Swift VS Objective-C VS Swift VS XYZ here :). Many of you know I freelance in the iOS space around London and beyond for SuperArmstrong and one of my recent clients asked me to work on a greenfield project to replace a very old wrapped web app they had. When we got down to the nitty gritties, one of their few requirements was that it should be written in Swift. My jaw did drop a little… considering this was about 20 days after Swift had first been publicly announced. After some conversation, we came to the mutual conclusion that they were brave.

Like many of the apps I work on, this project relied heavily on CoreData, as a convenience I decided i’d try out a library that I have a lot of respect for (even though its had its challenging moments) “MagicalRecord”, having only done organic CoreData for the past few years. As you probably know, Objective-C and Swift can sit alongside in a project and work in unison… however, not all the interoperability is 100% sound. I soon started to endure strange bugs and thanks to the incompleteness of Swift lldb support at the time (especially when mixing with Objective-C) these bugs soon became quite difficult to track down.

The most annoying was this:

let entityDescription = NSEntityDescription.entityForName("Pokemon", inManagedObjectContext: context)

Although harmless… this would actually fail when trying to insert an entity of that description into your managed object context. The culprit here? the NSString to String bridging (or vice versa).

To get around this bug (which I won’t go into too much detail) I began using:

let entityName = "Pokemon" as NSString
let entityDescription = NSEntityDescription.entityForName(entityName, inManagedObjectContext: context)

Performing a forced downcast to NSString. So great, now it works… However, many of the MagicalRecord finders and helpers I was using, would not have these forced downcasts as they came from the Objective-C world. I first forked MagicalRecord, after delving into the source-code, making many changes for better Swift support, fixing some threading irregularities I then realised I was putting a lot of work into making something work that had more functionality than I required at the time. So I embarked on making a Swift ActiveRecord style “companion” to CoreData.

The reason I say “companion” and not “wrapper” is that I didn’t want to abstract away CoreData too much or remove the power from the hands of the developer. I wanted to make the developer’s life easier, whilst maintaining their flexibility.

I’d much rather do something like this:

let pokemon = Pokemon.createNewEntity() as Pokemon

and avoid the above lines + more.

Thereby SuperRecord was born. The original goals for SuperRecord were simple.

  1. Give me the ActiveRecord style finders I crave, optimise them, keep my application level code tidy, but still performant.
  2. Rather than me typing out the same code in each project to handle batch updates on my UITableView and UICollectionView classes, have a special “one size fits all” class that will act as your NSFetchedResultsControllerDelegate, providing “safe” batch updated to your reusable views.
  3. Additionally, I didn’t wanna have to spend too much time creating NSFetchedResultsControllers all the time either, so I added some helpers for this too.
  4. Be written in Swift, keeping the public API’s simple and stable, but changing the implementation as Swift changed and moved with updates.

In late October 2014 whilst still very much a work in progress, I released the first public version and it was featured in the great iOS Dev Weekly newsletter. I decided to release it early as I saw a lot of discussion around CoreData and Swift and thought there’d be a lot of people interested in this OSS effort, so we could build up a good toolset as a community. I’m still the only maintainer… (not by choice) but its early days :).

Below is some extract from the README.md but I suggest you head over to the project on github for more information and feel free to checkout the demo project also on github which shows how to use the safe batched updates along with some other common tasks.

 

Core Files

  • NSManagedObjectExtension.swift This extension is responsible for most of the “finder” functionality and has operations such as deleteAll()findOrCreateWithAttribute()createEntity() and allows you to specify your own NSManagedObjectContext or use the default one (running on the main thread).
  • NSFetchedResultsControllerExtension.swift In constant development, this Extension allows the easy creation of FetchedResultsControllers for use with UICollectionView and UITableView that utilise the SuperFetchedResultsControllerDelegate for safe batch updates.
  • SuperFetchedResultsControllerDelegate.swift heavily inspired by past-projects i’ve worked on along with other popular open source projects. This handles safe batch updatesto UICollectionView and UITableView across iOS 7 and iOS 8. It can be used on its own with your NSFetchedResultsController or alternatively, its automatically used by the NSFetchedResultsControllerExtension methods included in SuperRecord.
  • SuperCoreDataStack.swift a boilerplate experimental main thread CoreData stack. Can be used either as a sqlite store or in memory store. Simply by calling SuperCoreDataStack.defaultStack() for SQLite or SuperCoreDataStack.inMemoryStack() for an in memory store. Of course you have access to your context .context / .saveContext()

Usage

Create a new Entity

Assuming you have an NSManagedObject of type “Pokemon” you could do the following

let pokemon = Pokemon.createNewEntity() as Pokemon

Please add @objc(className) above the class name of all your NSManagedObject subclasses (as shown in the demo project) for now. Better support will be coming in the future.

Creating an NSFetchedResultsController

This feature is currently in progress with basic support so far, in future versions, sorting and sectionNameKeyPath’s will be supported. Until then you can create your own NSFetchedResultsController, however, if you have no need for the above missing functionality then simply use

lazy var fetchedResultsController: NSFetchedResultsController = self.superFetchedResultsController()

func superFetchedResultsController() -> NSFetchedResultsController {
return NSFetchedResultsController.superFetchedResultsController("Pokemon", tableView: tableView)
}

With Pokemon being the entity name of your NSManagedObject.

Delete Entities

I’m planning on adding much more powerful functionality around Delete soon, such as deleteAllWithPredicate() or deleteEntity(), right now all that is available is

Pokemon.deleteAll()

Method Listing

This isn’t an exhaustive list of all methods and classes, however it includes some of the most useful ones.

  • NSManagedObjectExtension
  • findAllWithPredicate(predicate: NSPredicate!, context: NSManagedObjectContext) -> NSArray
  • findAllWithPredicate(predicate: NSPredicate!) -> NSArray
  • deleteAll(context: NSManagedObjectContext) -> Void
  • deleteAll() -> Void
  • findAll(context: NSManagedObjectContext) -> NSArray
  • findAll() -> NSArray
  • findFirstOrCreateWithPredicate(predicate: NSPredicate!) -> NSManagedObject
  • findFirstOrCreateWithPredicate(predicate: NSPredicate!, context: NSManagedObjectContext) -> NSManagedObject
  • createNewEntity() -> NSManagedObject
  • findFirstOrCreateWithAttribute(attribute: NSString!, value: NSString!, context: NSManagedObjectContext) -> NSManagedObject
  • findFirstOrCreateWithAttribute(attribute: NSString!, value: NSString!) -> NSManagedObject
  • NSFetchedResultsControllerExtension
  • superFetchedResultsController(entityName: NSString!, collectionView: UICollectionView) -> NSFetchedResultsController
  • superFetchedResultsController(entityName: NSString!, tableView: UITableView) -> NSFetchedResultsController

NSFetchedResultsControllers created using this method will automatically handle safe batch updates.

Developer Notes

This whole project is a work in progress, a learning exercise and has been released “early” so that it can be built and collaborated on with feedback from the community. I’m using it in a project I work on everyday, so hopefully it’ll improve and gain more functionality, thread-safety and error handling over time.

The next key things to be worked on are Optionality (as this has changed in every Swift BETA), the CoreDataStack, adding more finders with more functionality and improving the NSFetchedResultsControllerExtension.

 

 

iPhone 6 and 6 Plus side by side Paper Comparison

So on September 9th (as of time of writing thats last night) Apple announced (among other things) the new iPhone 6 and iPhone 6 Plus… Both are which are larger than the any predecessor. I won’t go into details of what each phone does / has… as i’m sure you can find that information anywhere on the Internet :). The biggest question on everyones minds is….

Which should I buy?

So, I was curious about the sizing of the new devices, therefor I made a really quick and dirty paper prototype with the precise dimensions. What it shows… the 6 Plus is a beast, larger, but somewhat smaller than a Samsung Galaxy Note II, but probably a commuters powerhouse, a halfway house between the traditional sized iPhone and iPad. Whereas the iPhone 6 is a welcomed and comfortable size increase on the iPhone 5/5S/5C generation.

Samsung devices in the Apple Spaces

Now next to the original devices

IMG_1330 iPhone sizing

 

Despite the iPhone 6 Plus being ginormous… I think thats the one i’ll be getting… Having to commute 1 hour a day on a train and being an overall geek… it suits me well 🙂

For more info on the specs and sizing of the new iPhones I suggest visiting the apple specs webpage.

 

Mockacino a lightweight ruby/sinatra API Mocking script

Hi Guys, so i’ve been working on a new app recently for a client of mine, currently there is no API… so in the meantime I decided to knock up a quick few lines of ruby to get a mocking api up and running… to explain this better, I need not do more than paste my README.md here.. Enjoy 🙂

Mockacino

A very simple and easy to use MOCK API server that serves static JSON written in ruby/sinatra.


NOTE: This is a super simple, super fragile MOCKING SERVER Intended so you can test routes and mock an API with static jso whilst you’re still building the real production API. DO NOT EVER use this in production… Seriously. It breaks a lot and will if you try… DONT. Absolutely 0 effort went into it, therefor 0 Warranty. Use if you dare.

DOCS:

Folder structure defines API calls…. return.json is what gets served.

site_root ->;
    [ http method ] ->; [ api call route ] ->; [ json response contents of call return.json ] 

e.g.

site_root ->;
    GET ->; users ->; return.json
    POST ->; users ->; create ->; return.json

If you have static assets you wanna reference in the json, plonk them in the ASSETS folder

e.g.

site_root ->; file.jpg

You can call http://yourhost:port/ASSETS/file.jpg

Here’s the directory structure of the sample project included here

mockacino.rb  
./site_root/ASSETS
./site_root/GET
./site_root/POST
./site_root/GET/sheep
./site_root/GET/sheep/create
./site_root/GET/sheep/return.json
./site_root/GET/sheep/create/return.json

Which supports calls like…

http://localhost:4567/sheep
http://localhost:4567/sheep/create

And gives responses from the static result.json file like…

{
    "sheep": [
        {
            "id": "1234",
            "name": "Dolly Two",
            "url": "http://mike.kz/sheep1234",
            "assets": {
                "small_image": "http://cloned.sheep.com/ASSETS/small.jpg",
                "large_image": "http://cloned.sheep.com/ASSETS/large.jpg"
            }
        }
    ]
}

Usage:

gem install sinatra
ruby mockacino.rb
 

Brisk a simple lightweight Networking Framework written in Swift


This is gonna be a short and sweet blog post… I’ve been working on a little pet project to practise and learn some Swift, so I thought, what do I use the most in projects these days… its networking. I’ve published on github.com my first attempt Brisk, its no where near complete and only has basic functionality right now, but if it becomes interesting i’ll pick up the effort and add more, until then, its a great educational exercise, you can check it out here and be sure to contribute back 🙂 it should work on both OS X and iOS and is MIT Licensed.

 

Swift the new Language for writing Cocoa and Cocoa Touch Apps

swift programming language

Introducing Swift

I’ve been at WWDC 2014 all week and one of the major announcements from Apple was a new programming language they’ve been working on named “Swift”, immediately it flashed me back to a really old WWDC where they announced an experimental language they were playing with named “Dylan” but I could be wrong.

Swift attempts to deliver a fast modernised language that looks and behaves as an interpreted language such as Ruby or Python but has all the power of a compiled language such as C++/Objective-C. From what i’ve seen on the interweb and twitter, there seems to have been a mixed reception from developers, but overall its looking more positive than not… My stance is… i’m gonna read more than 60 pages and wait more than 48 hours before declaring either my love or hate for Swift :)… If you’ve seen the blogosphere lately, you’ll understand what I mean.

Apple have released a publicly available (so i’m guessing not under NDA) Swift book on the iBook Store thats lengthy, doesn’t assume you’re an 8 year old and gives a decent overview of the Swift programming language, in what seems is from a “answer all of your questions and thoughts” approach, with some examples and exercises along the way.

I’ve attended the Swift labs almost everyday this week armed with questions, thoughts, suggestions and generally the engineers have been great at responding to everything. As a result i’ve filed radars, been convinced i’m not crazy and had some insight into the future of the language.

My main bone of contentions so far are:

  • No sensible/pretty way to selectively expose method A vs method B.
  • The threading model is still a little undefined and incomplete.
  • Autocomplete and LLDB seem to still be a very much work in progress.
  • Downcasting syntax is overly verbose.
  • Did I do it wrong? or did Xcode just shit itself?

However having said that, Swift was released early to us the developers, in order to get feedback/suggestions and help Apple build it to how we want… lets not forget, i’ve had (at the time of writing) 96 hours experience in Swift and its only been public for around the same amount of time… so a lot is likely to change.

What I like so far:

  • Generally a nicer more modern syntax
  • Less “falling back” to C for common things
  • Less unnecessary verbosity *(most the time)
  • Pretty seamless “bridging”/”interoperability” (or whatever the term should be) to existing Objective-C code
  • Namespacing, Modules & Frameworks
  • Explicit typing support with some intelligence from the compiler too
  • An emphasis on “tell the compiler as much as possible”

As soon as I figure out whether or not we’re allowed to talk about more, i’ll go into more detail on some of these points and post some sample code. I’m currently working on an iOS Framework written in pure swift that I’m sure people will enjoy, i’ll be posting it on GitHub in the near future here it is now, but its probably far away from prime time and perhaps a little useless 🙂 but a great way to learn Swift!

As always, thoughts and criticisms should be constructive and not defamatory and furthermore, have your own opinion, no one you follow on twitter is an expert on this yet 🙂 so don’t be afraid to voice your opinions and join in the healthy discussion.

If you wanna chat about it more, i’m @ArmstrongAtWork on twitter.

 

 

 

Reading Linux extfs (ext2/3/4) in Mac OS X

I have a collection of both Mac OS X and Linux servers dotted around the place… Sometimes I need to read ext4 formatted drives on my Mac’s… this always proves an annoying problem where I have to mount them inside a Virtual Machine and copy things across…. Pain and Slow!

I searched the interweb for a solution to this… and most  guides are about 3 years out of date, so here’s one from 2013 that works on Lion / Mountain Lion and even Mavericks DP1/2.

Download and Install : OSXFUSE-2.5.4.dmg (this took off where MacFuse left off and even has compatibility for old MacFuse plugins).

Download and Install : fuse-ext2-0.0.7.dmg

Plug in your ext fs formatted drive… Voila! I wouldn’t rely on this in a production environment mind you… but its decent if you just need to grab some files from a USB drive quickly for example.

 

Ubuntu 13.04 on a Late 2012 Mac Mini

EDIT: Tonight i’ll be picking up one of my Mac Mini’s from the Datacenter to get Ubuntu 13.04 up and running! expect a full guide with drivers here shortly 🙂

So Ubuntu 13.04 LTS recently was released, It comes with the new 3.8.0-19 upstream of the Linux Kernel so I thought I’d check it out!

Although our patched 12.04 and 12.10 Ubuntu’s use version 3.124c of the tg3 NeXtreme drivers from Broadcom which have Mac Mini support… The version in Ubuntu 13.04 (3.128c) seems to have had this removed!

A simple run of modinfo tg3 | grep 1686 reveals sadly that support for detection of the Mac Mini Ethernet hardware seems to have been removed during 3.124 and 3.128 of the Broadcom tg3 drivers.

I’m likely to install 13.04 on a Mac Mini sometime soon so will update this post with a proper howto and any good news I encounter but I don’t think its good news…

lsmod | grep Ethernet returns
01:00.0 Ethernet controller: Broadcom Corporation Device 1686 (rev 01)

whilst modinfo tg3 | grep 1686 on our modified 12.04/12.10 machines using the NeXtreme driver from this blog returns:

alias:          pci:v000014E4d00001686sv*sd*bc*sc*i*

however on 13.04 returns nothing.

 

The __block specifier in Objective-C and Why its so mis-understood

I’ve seen a lot of source code recently where people are mis-using the __block “specifier” that ships with modern Objective-C runtimes. I’ve always had the opinion that if you are to use __block for an Object then you should design around it and avoid, reserving its use for primitives. Regardless of that, here is a summary of my understanding of __block to share with any other keen readers who may be interested.

__block is used as variables outside the scope of a block become readonly once inside a block. For example

 int num=1;
void (^someBlock)(void) = ^{
num = 2;
};
someBlock();

Would cause a compiler error asking for the __block specifier to be used. so in this case you can try:

 __block int num=1;
void (^someBlock)(void) = ^{
num = 2;
};
someBlock();

and num will contain the correct value after block execution.

Straight forward right? So what about the following example:

 __block NSMutableArray *someArray = @[@"Hello",@"World"];
void (^someBlock)(void) = ^{
[someArray addObject:@"Goodbye"];
};
someBlock();

It’s wrong… you don’t need __block in this case… why? because you’re not assigning a value to the captured “variable” someArray, rather you’re just sending a message. I often see this and wonder why.

The __block specifier is actually a storage-class specifier, to give you an idea of what this means, the following are also storage-class specifiers in C. extern, typedef, static and so on.

Why don’t I like __block a great deal then? Read on for more…

… 

 

Installing Linux on a Late 2012 Mac Mini

So in the last post I discussed why the Mac Mini is the perfect machine for Linux and for Datacenters in general! One frustration some readers may be finding is that the networking chipset used by Ivy Bridge platform in Late 2012 Mac Mini’s doesn’t have native support in the Linux Kernel (as of now anyway). So its required to install a kernel module from the manufacturer/vendor (broadcom).

On their website they provide the “tg3” drivers for Linux kernels, however these are only good if you are running a Linux kernel < 3.5.x. If you take Ubuntu for example, 12.04 uses the 3.2.x stream, whereas 12.10 uses the 3.5.x stream and isn’t immediately compatible with the drivers on the broadcom page. This is due to the deprecation in 3.x and removal in 3.5.x of the asm/system.h header.

Read on for the fix, more and downloads. …