Wednesday, April 22, 2015

Deleted my Instapaper Account, Here are Some Stats, and Why the Service Didn't Work For Me

TL;DR 645 Unread 25 Archived 1 Starred

I've had an Instapaper account since 2008 when Marco Arment launched the service until now. I haven’t been using the account for most of the last 2 years, with my last save in June 2014, the only one the whole year.

So I deleted my account. Finally!

The idea never really worked for me, even though I was very excited about it. I’ve always been a news junkie. My routine is daily RSS reader, hourly Twitter timeline, Facebook News Feed mostly on weekends, and daily manual reading of a number of sites. The idea of a service that could generate a newspaper like thing for me to read later seemed great. But I realized that after I went through my usual news reading routine, my attention was exhausted. 

Instead, I used Instapaper as a bookmarking service for “important stuff”, longer form deeper think pieces I thought I absolutely had to know and would get to later. That also turned out to be untrue. Out of the 671 links I added to Instapaper, how many did I actually read? 26! 3.8%. That’s way lower than even I expected.

I’ve been using the Reading List feature built-in to Safari on iOS and OS X, but it’s where links kind of go to die for the same reasons as Instapaper, I just don’t go there, does’t fit into my routine. Bookmarks are a similar story, only the Bookmarks on my favorites bar see any action.

What I think I might need is something to save links grouped by research topic, not just one big list. Bookmark Folders kind of serve that purpose, but it’s not really an elegant or searchable tool.

I’ve also kind of become one of those people on a desktop browser that just leaves a browser window open per topic with tabs for each site until I’m ready to deal with it. Safari does an excellent job of keeping this state at the ready in my Dock on OS X.

 

Wednesday, April 08, 2015

How To Use the Spock Live Long and Prosper Emoji on iOS 8.3 & OS X 10.10.3

Versions: OS X  10.10.3   iOS 8.3
 
Despite the date, this article by Jason Snell at Six Colors about the Spock Live Long and Prosper hand gesture, referred to as Raised Hand with Part Between Middle and Ring Finger, is not an April Fool’s Joke.
 
iOS 8.3 and OS X 10.10.3 can display the emoji, but it isn’t in the standard Emoji keyboard on either OS yet.
 
To be able to use the emoji on OS X, you can create a text replacement macro to use it now:
  1. Copy the emoji from here: Raised Hand with Part Between Middle and Ring Finger (Blogger keeps double-encoding the emoji and makes it unreadable).
  2. Go to System Preferences -> Keyboard -> Text tab.
  3. Click +.
  4. I used LLAP in the Replace column and the emoji in the With column.
  5. That’s it!
Now when you type LLAP on OS X, you’ll get prompted to use the emoji.
 
Now on iOS:
  1. Copy the emoji from here: Raised Hand with Part Between Middle and Ring Finger
  2. Go to Settings -> General -> Keyboard -> Shortcuts.
  3. Tap +.
  4. Paste the emoji into Phrase.
  5. Type LLAP into Shortcut.
  6. Tap Save.
Now when you type LLAP on iOS, you’ll get prompted to use the emoji.
 
Live Long and Prosper!

Friday, April 03, 2015

With Autocompleted Methods & Functions, I Wish Returned Values Came After the Call In Swift

We’ve been calling functions or methods on objects the same since at least C appeared in 1972. You declare & call a function like this:

int main(void) {
    printf("hello, world\n");
    return 0;
}
int value = main();

To define, the return type is declared before the name of the function. On call, a variable is declared to hold the return value of the function call.

In Swift, you declare a function with a return type like this:

  • func printAndCount(stringToPrint: String) -> Int {

        println(stringToPrint)

        return countElements(stringToPrint)

    }

I loved this change to the C convention. IMHO, the information importance follows the order you declare the function: name, parameter type(s), and return type(s). However, you still call that function like this:

  • let count = printAndCount("Hello, playground")

This feels like a job half done, a little bit like the tail wagging the dog

I nearly always know the name of a function or method I want to call before I know its return types.

Wouldn’t it be great if the language was fully adapted to the pervasiveness of autocomplete?

Imagine the amount of time you’d save if you could start typing the name of the function or method first and let autocomplete show & then fill in the return types?

Proposing Post Call Return Value Assignment

I’m proposing that variables that are assigned the return value of a function should come after the function call using a return arrow. It would look something like this:

printAndCount("Hello, playground") -> let count

With methods, it would look like this:

someObject.printAndCount("Hello, playground") -> let count

The actual syntax is up for debate, but I’m excited by the idea. I don’t know of another language that does this.

Pros

  • Far fewer trips to documentation to lookup the return types of a function you know the beginning of.
  • Far less typing of return types of any kind
  • Far less (no?) typing the object, autocompleting the method, then fixing up the return types to variables you want.

Cons

  • Return variables harder to “find” when reading code
    • Listing for completeness, I don’t see it being materially wrong, just different from the norm
  • Imagine the style debates because the existing way stays in the language.

I’m betting the pros would outweigh any cons, and this feature would greatly increase the usability of the language and editor together.

Thursday, April 02, 2015

iOS MPMoviePlayerController Crashes when prepareToPlay is Called Without Adding to a View

TL;DR Call something like [self.view addSubView:moviePlayer.view] before [moviePlayer prepareToPlay]
Versions: OS X  10.10.2 Xcode 6.2 iOS SDK 8.2 

I just inherited some code previously compiled against iOS SDK 6.0, ran fine through iOS 7, but crashes on iOS 8.x. Here’s the crasher:

NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"impact_of_needs_goal_planning@1x" ofType:@"mp4"]];
self.moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:url];
self.moviePlayer.shouldAutoplay = NO;
[self.moviePlayer setControlStyle:MPMovieControlStyleNone];
[self.moviePlayer.view setFrame:CGRectMake(0.0, 0.0, 1024.0, 748.0)];
[self.moviePlayer.view setTag:7];

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(movieDidLoad:) name:MPMoviePlayerLoadStateDidChangeNotification object:self.moviePlayer];
[self.moviePlayer prepareToPlay];

App was crashing on the last line, [self.moviePlayer prepareToPlay]; every time it was called.

This is a guess (because installing an iOS 7 simulator is taking forever), but it looks like iOS 7 and below didn't care because the app was working fine. iOS 8 crashes.

The solution is adding the moviePlayerController to a parent view before calling [self.moviePlayer prepareToPlay];, like this:
[self addSubview:self.moviePlayer.view];

Given this is The Right Thing To Do™, I'm actually surprised it ever worked!

Update

Turns out this was not the cause of the crash, which I have yet to nail down. This change did seem to temporarily solve the crash, but alas it is something to do with NSNotifications :’(

Thursday, March 12, 2015

Reminder: iOS's UICollectionView Added an Item Property to NSIndexPath

TL;DR Use the item property on NSIndexPath for UICollectionView instead of row from UITableView 

Just realized I littered a UICollectionViewController with calls to indexPath.row when I should have been using indexPath.item. I didn’t see any bad behavior, but should use the right property for the job!

Reference:

NSIndexPath UIKit Additions (Web)

Thursday, March 05, 2015

Workaround for iOS Simulator Not Sending Current Location to Your App

TL;DR Click the Debug -> Location -> Apple menu.
Versions: OS X 10.10.2 Xcode 6.1.1 iOS SDK 8.0 iOS Simulator 8.1 (550.3)
iOS Simulator Debug Location MenuI often reset the iOS Simulator to quickly wipe out installed apps, settings, keychain items, etc. After a reset maneuver, the simulator often refuses to deliver the the users current location. I usually have a Custom Location (as pictured in the screenshot to the right) configured to get back to the same place every run.
When the simulator gets stuck, a quick workaround is to change the location to a pre-defined one, e.g. Apple. It kind of feels like Han Solo smacking the Millennium Falcon to get it to power on in Empire Strikes Back!
Just click the Debug -> Location -> Apple menu.

Wednesday, March 04, 2015

Reason Why Your Storyboard Defined UICollectionViewCells Are Blank on Run

TL;DR Remove the / do not add a call to... self.collectionView.registerClass in viewDidLoad
Versions: OS X 10.10.2 Xcode 6.1.1 iOS SDK 8.0
Blank Collection ViewWhen you run your app to see your collection view, does it look like this? 
This isn’t your first rodeo, you’ve implemented UICollectionView before, but maybe it’s been a while.
You want to do it The Right Way™, using all the modern stuff like Storyboards, and then this happens!
What's gone wrong?
You have what seems like a reasonable line of code in viewDidLoad that UICollectionView is choking on!

How You Could Have Got Here...

Let’s say you created a UICollectionViewController in a Storyboard or a UICollectionView in a plain old UIViewController. You’re confident, not cocky, but you know Apple’s pattern on this pretty well, so you go ahead and customize the first cell, nothing that requires code, and then add a second cell that you expect to set properties on, so it might look like this:
Screen Shot 2015 02 27 at 7 44 19 AM

Best Way To Add Code for Storyboard?
Back in the day when Interface Builder was a separate app (pre Xcode 4), there was an option to auto generate class files right from within the UI. If memory serves, this would create the class file as mostly what you wanted and connected to IBActions and IBOutlets.
Since Xcode 4, you can drag actions and outlet into your source code, but the source files have to already exist. If you want to create source, the only way I can find is from the process on the left. There's some typing & option choosing which are needless because you already made those choices in your Storyboard. Worse, the source is not customized in any way from the changes you already made in the Storyboard.
Anyone have a less manual way? Let me know, I can't seem to find one.
Now you think it’s time to add code for the view controller you created in the storyboard, so you go through the File -> New -> File (or ⌘N if you do this a lot) dialogs like in the screenshots below: (your mileage may vary with different Xcode versions)
 Screen Shot 2015 02 27 at 8 00 03 AM Screen Shot 2015 02 27 at 7 56 17 AM

 

The code template that's used for a UICollectionViewController seems like a reasonable starting point. It adds the following line to viewDidLoad:
Obj-C [self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:reuseIdentifier];
Swift self.collectionView!.registerClass(UICollectionViewCell.self, forCellWithReuseIdentifier: reuseIdentifier)


If you've customized the stock UICollectionViewCell in your Storyboard, the cell with the matching reuse identifier in code will cause UICollectionView to load an empty UICollectionViewCell! If you went full steam ahead and added a bunch of custom cells with matching reuse identifiers and registerCell calls in viewDidLoad, you, ah, might not figure this one out for a while.

Tuesday, March 03, 2015

A JS Framework On Every Table

No article or blog post has ever captured how I feel about Javascript like a JS framework on every table.

It’s not like I hate Javascript, but with limited time to invest in learning stuff outside the Apple stack, the constant turnover in JS frameworks means nothing ever really rises above the level of noise for me.

Except Angular.js! Looked like that had some heat, some staying power. Too bad Angular is breaking compatibility between 1.3 and 2.0. I’d heard many good things and even dabbled with it on a project, and thought it might be time to dive deeper, but now…*sigh*

Thursday, February 19, 2015

2014: The Year Video Games Broke My Heart Part 2 - Destiny

Destiny: Be Mediocore

In 2014: The Year Video Games Broke My Heart Part 1 I detailed how the quality deficit in Halo: The Master Chief Collection needs to lead to a change in behavior: no more pre-orders and no more day 1 purchases.

In 2014: The Year Video Games Broke My Heart Part 2 - Game Review Sites Strike Back! shows how a couple game review sites hopefully lead the charge to reviewing the product and experience retail game buyers have before rating a game, which should act as a deterrent to shipping shoddy products to retail.

But flat out broken games weren’t the only huge disappointment in 2014. The most anticipated & hyped game of 2014, Bungie’s Destiny, wasn’t even close to living up to expectations.

What went wrong with Destiny? Destiny is like the best C+ shooter you’ve ever seen. First, here’s what went right:

Before I unload the complaints, I have to tell you dear reader that at the time of this writing I’ve played Destiny for 3 days, 11 hours, 35 minutes! That’s just the shipping game, I also poured a bunch of undocumented hours into the beta. I’m not even a hardcore player, there are tons of people with hundreds of hours played in this game!

What could be so wrong with a game that millions of gamers and I around the world have spent so much time in? A game profitable on day 1? It’s complicated, but even Destiny’s most ardent fans (largely) agree on this:

  • A story that barely makes any sense in game
  • A ton of story shunted off into something called a Grimoire, which is a collection of "cards” to read on a website or app.
  • Laughably bad dialog from a lot of the in-game voice acting (e.g. "I don’t have time to explain what I don’t have time to explain")
  • A bewildering number of currencies and materials (glimmer, vanguard marks, crucible marks, motes of light, strange coins, black wax idols, ascendent shards, ascendent energy, exotic shards, I might have missed something) 
  • A bewildering number of factions to grind reputation for (Vanguard, Crucible, Dead Orbit, New Monarchy, Future War Cult, Iron Banner, Queen, Eris Morn, Cryptarch)
  • Factions (New Monarchy, Dead Orbit, Future War Cult) with hardly any back story or purpose, they’re just vendors of slightly different versions of weapons and armor
  • No Looking For Group tools in game for the toughest challenges, it’s all manual.
  • Notice I didn’t say Matchmaking, which is in the game, but not for the hardest content, and Bungie has “no plans” to do so. (Thankfully , Weekly Strikes Will Soon Be Matchmade).

And this is just for starters. I mean there are so many things wrong, incomprehensibly nonsensical, it truly boggles the mind. Players have spent tons of time on the Bungie community forums documenting this and much, much more…the threads live for a while, then disappear either intentionally or they lose all heat and get auto-scrubbed.

This is a great look at why the game was such a letdown at launch and largely still to this day:

 

Yet Million Keep Playing…or Are We?

For all the complaints, a lot of people are hooked, digging deep to rationalize their addiction. For me the continued playtime is twofold. I’ve already paid for more content then I’ve received and I remain hopeful Bungie can pull this thing out. What do I mean? I bought the $90 Digital Guardian Edition, which included The Dark Below and House of Wolves expansions. The Dark Below was not an improvement, but more of the same. Still I enjoyed some of the changes, and the missions, while still not making a ton of sense, were decent.

The big hook though is winning that sweet loot. Chasing the carrot (even while there aren’t enough), pulling the slot machine handle one more time, or this time getting the winning lottery ticket. What do I mean? Every reward in the game is handed out at random. Materials, armor, and weapons. There are few guaranteed paths to acquiring everything, and the ones that do exist (Exotic Weapon Bounties) are extremely time consuming. The tantalizing possibility of winning by chance (not earning) loot is the hook that keeps people doing the same repetitive tasks over and over again. Playing the same mission, strike or raid (in ascending order of time & difficulty and thus possible payout) is no different from going to a casino for hours and hunkering down with a bucket of coins and pulling the slot machine handle or tapping spin over and over again.

This is perhaps the biggest disappointment of all. It feels like Bungie went full dark side, embracing every dark pattern used first by the gambling industry and increasingly the video game industry to keep us playing, and playing, and playing to get the loot, to beat the monsters, to get the loot, to beat the monster, ad nauseam.

Yet with all those tricks in full use, hardcore players are hitting a wall while waiting for the The House of Wolves expansion, which is coming out later than many expected. I’m not hardcore enough, I haven’t had enough time, to exhaust the raid content because without matchmatching or in game looking for group (good for you if you like DestinyLFG.net), it’s often too much work for me to put a raid group together. Even with the great DadsOfDestiny clan on my friends list, the game doesn’t help people on your friends list figure out which activities you’d like to do, it’s all website forums or Xbox One (for me) messages.

Yes the addiction is strong, abetted by the promise I can play my characters for a long time, so how could I have avoided this love/hate relationship? Don’t believe the hype.

Call to Action

It happens to all of us from time to time, the hype gets to us, we believe, and spend money before a product is shipped. But with games increasingly the prescription is don’t fork over your money ahead of the game actually shipping (Kickstarter included). Don’t buy expansions before you’ve played the game, you’ll save yourself money, and this stuff is often on sale if the game is good. Wait for reviews of even the most hyped games before plunking down your own sweet loot.

I would not be playing Destiny if I hadn’t already paid $90 for the full game. 

Tuesday, February 17, 2015

How To Delete Conversations in Messages OS X Without a Confirmation Prompt

I get a lot of iMessages and SMSes that are informational, like transit alerts, that I just want to delete after reading them.

With the Continuity features of OS X 10.10 Yosemite and iOS 8, I end up deleting these conversations on all the devices I can get them, which is not really what you want. 

In Messages on OS X, you delete conversations by clicking the little x next to the conversation or typing ⌘⌫ (command-delete). Then you get this prompt:

OS X Messages Delete Prompt

While it would be great if Apple automatically deleted them on all devices when deleted on one device, we’re not there yet, but you can eliminate the prompt!

Just option-click the x next to the conversation or type ⌘⌥⌫ (command-option-delete)

I’m still surprised and delighted when something I want to be able to do is tucked behind an ⌥ option key press. ⌥ option click all the things!