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!

Wednesday, February 11, 2015

2014: The Year Video Games Broke My Heart Part 2 - Game Review Sites Strike Back!

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 the last few days, two game review sites demonstrated real ethics in game journalism (more on Gamergate’s fake kind later). They've changed review practices partly or wholly in response to game quality levels and the previously controlled conditions reviews were conducted under.

Polygon has adopted a system called Provisional Reviews, which I think is fantastic. In the Halo Master Chief Collection case, this would have meant that as soon as launch day and beyond issues became apparent, Halo MCC would not have been issued a high final of 95 vended out to Metacritic (cmd-F/ctrl-F for Polygon):

Screen Shot 2015 02 10 at 6 27 00 PM

 

 

The update on Polygon’s Halo MCC review 5 days after launch from an 8 from 9.5 didn’t affect Metacritic at all. With Provisional Reviews, Metacritic would have most likely got the low quality adjusted review score. This will directly affect game studio and publisher bonus structures since studios are often awarded for 9+ Metacritic scoring game.

Eurogamer.net has dropped review scores entirely and will not submit to Metacritic. Most interestingly, they are taking steps to guarantee they are reviewing paying retail customer experiences as well:

We are also changing (or firming up) other areas of our reviews policy, with the intention of ensuring that we always review the same experience that you get when you buy a game. This means that we will only review from final retail versions and online games will be reviewed after they've launched.

Eurogamer will issue first impressions of games on launch day, but also not use their new system to issue a near immutable final recommendation until they can asses the game under real world conditions. Fantastic!

Hopefully other game review sites follow these two sites lead in:

  • Don’t issue final scores based on debug build games, only retail copies
  • Don’t issue final scores based on controlled network conditions for multiplayer heavy titles, only on 
  • Don’t issue final scores to Metacritic (if at all) until a games total experience can be judged at launch under real work usage
If enough review sites adopt these kinds of policies, then hopefully they will serve as a deterrent to game studios and publishers shipping broken products to retail.

Part 3 Coming Soon: Destiny - Be Mediocre