Apple People, This is Why Others Hate You

Have you, Apple Fan, ever wondered why some people on the Internet seem to have an irrational hatred of you? Don’t worry, Rusty swings both ways, allow him to mediate and explain.

Let’s start with well known Apple Developer, Wil Shipley

Yes…except no. The IFA Trade Show was scheduled long before Apple announced anything, and is where manufacturers announce things like this. Let’s not even get into how ridiculous it is to actually assume that the wearables category was started by an Apple rumour. People actually think that. You probably do too. Please stop for a second and think that one through.

Next up is my favourite Apple PR Representative Blogger, John Gruber:

Screen Shot 2014-09-06 at 10.05.40 am

John thinks Motorola is so ashamed of an issue that he created, and won’t stop talking about, that they tried to photoshop it out. Except they didn’t. I’ve also lost count of the amount of times he’s called it a ‘flat tire’ on his blog. Anyone would think he’d been handed this as some kind of talking point. His circle maths is also way off, but I’m not even going to bother trying to correct it here.

Finally, I have one more person to call out. You dear reader, you. You see if the rumours are true Apple will be launching a 4.7″ and 5.5″ set of phones next week. They will also demo some new software. My Twitter stream will fill up with people telling me how this is revolutionary, and how only Apple could do this. A few parts of it no doubt will be, but in most respects someone, somewhere will have done all of these things before Apple. The fans of said platform will only hate you more for being ignorant of this fact. So by all means get excited, but remember that other companies also do great things. Sometimes even first. Sometimes even better.

Security By Deflection

Not sure if you read the news, but some celebrities had their nudie photos stolen. Apple posted their response today, you can read it here.

It contains choice phrases such as :

“a practice that has become all too common on the Internet”

I could write entire blog posts about how that level of blame deflection is beyond patronising. I’m not going to though, because they end with this:

“To protect against this type of attack, we advise all users to always use a strong password and enable two-step verification.”

Strong passwords and two-step verification. Makes perfect sense right? Except Apple forgets to mention that there’s no such thing as two-step authentication for your iCloud photos, or even access to your iCloud account. Here’s what’s actually protected:

Then, any time you sign in to manage your Apple ID at My Apple ID or make an iTunes, App Store, or iBooks Store purchase from a new device, you’ll need to verify your identity by entering both your password and a 4-digit verification code, as shown below.

http://support.apple.com/kb/HT5570

In other words, enabling two-step authentication would do nothing to ‘protect against this type of attack’. I store a lot of things in my iCloud account, and it’s also able to wipe most of the devices I use. I expect more from Apple, we all should. Here’s a specific example of why that is:

That’s right, someone can wipe an entire iPad, on an account I enabled two-step authentication on. They can also track all my devices. They can read my email. Peruse my calendar. Get all my photos. In my case as a developer they can remove all my apps from sale, or change their descriptions. I care about all those things far more than someone stealing money from my credit card. That’s the whole reason I enable two-step authentication for all my important online accounts.

I hope Apple takes this opportunity to lift their game security wise. Blaming hackers is one thing, doing more to protect us all is entirely another.

The Rumoured iOS Screen Fragmentation

In a previous post I covered the widely held myth that is Android screen size fragmentation from a developer perspective. Consider it required reading before you proceed.

Today famed Apple blogger John Gruber, posted his thoughts on what the iPhone 6 could look like when it launches. He suggests that both the rumoured 4.7″ and 5.5″ models might exist, and takes a guess at their screen resolutions:

- 4.7-inch display: 1334 × 750, 326 PPI @2x

- 5.5-inch display: 2208 × 1242, 461 PPI @3x

John Gruber, Daring Fireball, Conjecture Regarding Larger iPhone Displays

The whole post is worth a read, so off you go. I was interested in taking the same 1x (or 1pt/1dp as it’s also known) diagram we drew for Android, and redrawing that for iOS in light of this post. It would look like this:

ios

Remember our Android one looked like this:

screen_resThis comes from these 4 screen sizes:

  • 320×480 @1x iPhone 4
  • 320×536 @1x iPhone 5
  • 375×667 @1x iPhone 6, 4.7″
  • 414×736 @1x iPhone 6, 5.5″

What does this mean in practice? It means iOS developers will now have to do more work than their Android counterparts in order to support the increased variation in iOS screens. The best tools for that exist in iOS 8, which also makes it likely a lot of apps will go iOS 8 only to avoid the manual layout pain. It’s not all bad news though, this might actually result in better large screen iOS apps vs their Android counterparts. This is because on the 5.5″ iPhone there would be more content being shown, rather than everything just being bigger.

All of the above is based on rumours though, so we all have to wait until September to see what actually happens.

 

The Church of GTFO

“That’s good to know, but what did Rusty think of them?”
“Rusty?”
“Yeah”
“He said he’d happily hire them”
“Well that’s all I need to know, that guy really doesn’t abide fools”

Do you ever hear something about yourself, that makes you realise there’s a part of you, that you didn’t even know existed? The above is a conversation I overheard almost a decade ago now when two people were discussing whether or not to hire a recent applicant. The Rusty was me, but I don’t abide fools? What does that even mean? That one overheard conversation made me aware of just how many things in my life I hold up to a critical light, and discard when they don’t hold up to careful examination.

I was raised as a fundamentalist Christian by my mother from a young age. As I grew up I became really involved in the Church. Eventually I became a youth leader, organising events for hundreds of young people, giving regular sermons from the platform, I became everything expected of a young man in that organisation. Then came the day they asked me to take on the role of ‘Area Leader’. That day made me stop, and examine everything I believed in. I know it sounds funny in hindsight, but I hadn’t ever taken the time to think it through before that. What I believed was true, because it was true. Everything I heard in the Church was true, because everyone else affirmed it to be true. Well it was, until I spent time critically examining everything I believed in. Like a house made of cards, it all collapsed, unceremoniously and silently to the floor. This, as far as I was concerned, left me with only one thing I could do. I explained to everyone that I no longer believed, and wished them well with their endeavours. Being a fundamentalist church 99% of them immediately stopped talking to me, but that is a story for another day.

I’m not here to keep telling you my life story, and in truth I have no regrets. I met some great people and to this day I have no fear whatsoever of public speaking, since I did that from a young age. I share the above story because as much as I hate to admit it, a lot of people treat Apple and Google like their own personal churches. They think their company is better than all others, that whatever they do should be viewed in a different light to everything else. They have common wisdoms and sayings that they repeat over, and over, and over again. They surround themselves in a virtual echo-chamber of like minded attendees and repeat the sayings of Gruber, Nickinson et al. And should you dare to challenge them on those beliefs? You get the same reaction I did when I explained to my former church friends why I’d become an atheist. I’m not going to stretch this analogy to breaking point, it is just an analogy after all. I don’t recall hearing of anyone praying to Marco to watch over them while they sleep. My point is simply that from time to time, it helps to stand back and consider things a bit more objectively. Perhaps we all view life through various lenses and being aware of at least some of them, could be a good thing.

I recently went to Google I/O, I switched to using an Android phone and I’m wearing an Android Wear watch. I talk about all of those things not because I’ve had some miraculous conversion to the church of Google, but simply because I find them interesting. When I write about my experience, it’s not to convert you. I honestly don’t give a damn what phone you have in your pocket or which laptop you use. Actually, that’s not entirely true. I, like most geeks, am one of those people that try to steal glances at people’s phones when they pull them out in public. What’s on her home screen? Does he have a weird case? Is that a crack? OMG not a screen protector, WHY would you do that to a screen?!

Honestly I’m just tired of people who identify with one and only one company. While you’re talking to them, they are too busy figuring out how to counter what you’re saying to listen. Please stop. Companies aren’t churches, they aren’t sports teams. If I use a Google phone and an Apple laptop there’s no contradiction there. Technology is absolutely amazing. Sometimes I feel like most people I meet are so busy taking sides that they aren’t stopping to appreciate the innovation and wonder being delivered by so many companies today. Taking snarky pot shots at products is so easy, heck even I do it occasionally. Stopping to actually marvel and enjoy them, well that’s much harder.

I tried to convey some of this on the latest episode of Pragmatic. I mostly failed, but if you’re out of podcasts, go listen: http://pca.st/Zwvi.

House of Cards, Gruber Edition

I just read the most interesting post I’ve read all year. It was two sentences long. Allow me to share it with you:

It looks like Motorola’s designers tried to draw as much attention as they could to the 360’s stupid flat-tire display shape.

The only way this could get funnier would be if it doesn’t even ship until after Apple announces their wrist wearable thing next month.

- John Gruber, Daring Fireball, 8th August 2014

Now most people think this is interesting because it reveals ‘secretly’ or ‘accidentally’ that Apple’s wearable is coming next month. That’s not the interesting part at all, it’s stated blatantly and purposefully in the post. And that kids, is the interesting part. Ponder that last sentence for a few minutes, if you will. Consider how and why it got posted to Daring Fireball.

Thoughts on Swift, From an Idiot

Swift (-taylor) is the exciting new language Apple debuted at WWDC in 2014. It took pretty much all of us in the developer community by surprise. We’re now in August, 5 beta builds into Xcode and I feel like I’ve started to form an opinion about the language itself.

First the good parts:

  • It looks a million times cleaner than Objective-C code
  • I won’t miss the [square brackets]
  • It’s much nicer to read
  • It has a lot of modern ideas and influences that make it a joy to write
  • It’s apparently fast, and only getting faster

And that’s where, for me, it ends. You see Apple sold me on the promise that this would solve my number one gripe about Objective-C: memory management issues. I had assumed my number two gripe, proper stack traces on crashes, was joining us for the ride. If you want to feel some of the pain that comes with Objective-C development, feel free to peruse this crash, from an older version of Pocket Casts:

Thread 0 Crashed:
0   libsystem_kernel.dylib               0x000000019a38e58c __pthread_kill + 8
1   libsystem_pthread.dylib              0x000000019a41116c pthread_kill + 100
2   libsystem_c.dylib                    0x000000019a322808 abort + 108
3   libsystem_malloc.dylib               0x000000019a3c85c4 nanozone_error + 292
4   libsystem_malloc.dylib               0x000000019a3c8778 _nano_malloc_check_clear + 432
5   libsystem_malloc.dylib               0x000000019a3c725c nano_malloc + 40
6   libsystem_malloc.dylib               0x000000019a3b8368 malloc_zone_malloc + 92
7   CoreFoundation                       0x000000018d68fd70 _CFRuntimeCreateInstance + 268
8   CoreGraphics                         0x000000018d81c9dc CGTypeCreateInstance + 56
9   CoreGraphics                         0x000000018d8262ec create_provider + 52
10  CoreGraphics                         0x000000018d826284 CGDataProviderCreateDirect + 52
11  CoreGraphics                         0x000000018d826228 CGDataProviderCreateWithCFData + 88
12  CoreGraphics                         0x000000018d8261a4 CGDataProviderCreateWithCopyOfData + 364
13  CoreGraphics                         0x000000018d825ee8 CGBitmapContextCreateImage + 84
14  UIKit                                0x000000019076d038 _UIGraphicsGetImageFromCurrentImageContext + 196
15  UIKit                                0x000000019076f830 -[UIImageView _setImageViewContents:] + 1244
16  UIKit                                0x000000019076ede0 +[UIView(Animation) performWithoutAnimation:] + 84
17  UIKit                                0x000000019076e748 -[UIImageView setImage:] + 836
18  UIKit                                0x0000000190b128b8 -[UIButton _updateImageView] + 128
19  UIKit                                0x00000001907b7e2c -[UIButton layoutSubviews] + 100
20  UIKit                                0x000000019075afe0 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 344
21  QuartzCore                           0x000000019034c258 -[CALayer layoutSublayers] + 180
22  QuartzCore                           0x0000000190346e20 CA::Layer::layout_if_needed(CA::Transaction*) + 296
23  QuartzCore                           0x0000000190346cd8 CA::Layer::layout_and_display_if_needed(CA::Transaction*) + 28
24  QuartzCore                           0x0000000190346560 CA::Context::commit_transaction(CA::Transaction*) + 276
25  QuartzCore                           0x0000000190346304 CA::Transaction::commit() + 420
26  QuartzCore                           0x000000019033fc38 CA::Transaction::observer_callback(__CFRunLoopObserver*, unsigned long, void*) + 76
27  CoreFoundation                       0x000000018d757858 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 28
28  CoreFoundation                       0x000000018d754ae0 __CFRunLoopDoObservers + 368
29  CoreFoundation                       0x000000018d754e6c __CFRunLoopRun + 760
30  CoreFoundation                       0x000000018d695dd0 CFRunLoopRunSpecific + 448
31  GraphicsServices                     0x000000019337dc0c GSEventRunModal + 164
32  UIKit                                0x00000001907c6fc4 UIApplicationMain + 1152
33  podcasts                             0x000000010004e9b4 _mh_execute_header (main.m:14)
34  libdyld.dylib                        0x000000019a293aa0 start + 0

Looks very detailed right? So as an app developer you get that back, and now it’s your job to figure out why. The first thing you look for is your app’s line numbers, so you can follow the execution path. Our app executable is called ‘podcasts’ and we can see it’s in main.m, line 14. Now most Objective-C developers have already skipped ahead and know where this is going, but indulge me. Here’s line 14:

return UIApplicationMain(argc, argv, nil, NSStringFromClass([SJAppDelegate class]));

Oh…it’s the line our app was launched from, and doesn’t really bare any resemblance to where the crash actually started from. What button did the user press? Which screen where they on? There’s no way to know. Now before you email me, I know exactly why it’s like that. I’ve put up with it for many years. Currently in Swift, those stack traces are even worse. I won’t post one until they actually release it to be fair to Apple…but why oh why when they were making a ‘modern’ programming language could they not solve this? I know, the Objective-C runtime is hailed by many the world over as being fast, and awesome. But it’s 2014, the things I actually care about are the problems Microsoft and Sun Microsystems solved, memory management and reliability. If it comes at the expense of a tiny amount of speed, I’ll happily take it. I can count the amount of times on no hands that my code was running slow, and it was the languages fault. That goes for Java, Objective-C, C#, C++, Ruby and so many other languages. Don’t get me wrong, I love more speed, but give me more reliability first.

Update: Someone on Twitter wanted to be clever and pick apart the actual stack trace I posted. It was an example kids. But here’s a more specific one:

Thread 0 Crashed:
0   libobjc.A.dylib                      0x3a6f7626 objc_msgSend + 6
1   CoreFoundation                       0x2ff14f01 __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ + 10
2   CoreFoundation                       0x2fe88d69 _CFXNotificationPost + 1718
3   Foundation                           0x30874cc5 -[NSNotificationCenter postNotificationName:object:userInfo:] + 70
4   UIKit                                0x329e545f -[UIApplication _sendWillEnterForegroundCallbacks] + 152
5   UIKit                                0x3298a949 -[UIApplication _handleApplicationResumeEvent:] + 1146
6   UIKit                                0x327895f3 -[UIApplication handleEvent:withNewEvent:] + 1880
7   UIKit                                0x32788dd9 -[UIApplication sendEvent:] + 70
8   UIKit                                0x327ed3e5 _UIApplicationHandleEvent + 614
9   GraphicsServices                     0x34df6b55 _PurpleEventCallback + 606
10  GraphicsServices                     0x34df673f PurpleEventCallback + 32
11  CoreFoundation                       0x2ff1d807 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 32
12  CoreFoundation                       0x2ff1d7a3 __CFRunLoopDoSource1 + 344
13  CoreFoundation                       0x2ff1bf6f __CFRunLoopRun + 1404
14  CoreFoundation                       0x2fe86729 CFRunLoopRunSpecific + 522
15  CoreFoundation                       0x2fe8650b CFRunLoopRunInMode + 104
16  GraphicsServices                     0x34df56d3 GSEventRunModal + 136
17  UIKit                                0x327e7871 UIApplicationMain + 1134
18  podcasts                             0x000851cf main (main.m:14)
19  libdyld.dylib                        0x3abebab7 start + 0

I know the cause of this. I forgot to call removeObserver somewhere. But where? Damned if I know unless I give every single one of my methods unique names. Pointers are fun. My point is, a language/framework/runtime combination that is modern, should remove that guesswork.

As much as people hate Java, and to some extent I’m in that camp too, here’s an equivalent crash from our Android app:

java.lang.NullPointerException
	at au.com.shiftyjelly.pocketcasts.PodcastDialog.addToPodcastLibrary(PodcastDialog.java:465)
	at au.com.shiftyjelly.pocketcasts.PodcastDialog.subscribeToPodcast(PodcastDialog.java:257)
	at au.com.shiftyjelly.pocketcasts.PodcastDialog.access$400(PodcastDialog.java:48)
	at au.com.shiftyjelly.pocketcasts.PodcastDialog$2.onClick(PodcastDialog.java:201)
	at android.view.View.performClick(View.java:4438)
	at android.view.View$PerformClick.run(View.java:18422)
	at android.os.Handler.handleCallback(Handler.java:733)
	at android.os.Handler.dispatchMessage(Handler.java:95)
	at android.os.Looper.loop(Looper.java:136)
	at android.app.ActivityThread.main(ActivityThread.java:5001)
	at java.lang.reflect.Method.invokeNative(Native Method)
	at java.lang.reflect.Method.invoke(Method.java:515)
	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
	at dalvik.system.NativeStart.main(Native Method)

Yes I know, ha ha Null Pointer, Java, LOL. But that’s an exact line number friends. What did the user do? They tapped the subscribe button. Which page where they on? The Podcast Dialog. Zero ambiguity. Guess how many of our Android crashes we get that for? 100%. In iOS we’d be lucky if even 30% of our crashes had stack traces we can line up to actual things we can then reproduce. So most iOS crashes today involve me becoming House MD and poking the code for hours, only to figure out that like always, it’s never Lupus.

I haven’t even covered the crashes I’ve seen where Objective-C was sending a message to the wrong object, a classic sign that the object you thought you had has been released and you’re now talking to something completely different. I’m assuming that Swift, running on the same runtime, with the same compiler, is going to have that exact same issue. I also haven’t gone into how the entire Cocoa/Cocoa Touch API is built for Objective-C and is still at times awkward to interact with in Swift. That one at least feels like mostly a transitional issue. So count me disappointed until the day Apple announce a new runtime that actually gets rid of memory related crashes, and gives us accurate stack traces. Until that day, old man Rusty is just going to keep yelling “get off my lawn, kiddo’s”.