Twitter Tabbar Indicator Added to Universal iOS Template

Today I pushed a nice little update to the Tabbar Support branch of my iOS-Universal App Template project on Github.  I added in the "Twitter tabbar slider" indicator.  Though it isn't that flashy it was the attention to detail that made Tweetie so popular and usable when it first came.  While it has since been duplicated I found it interesting that most examples don't have support for landscape orientation nor for iPads.  After looking through @boctor's code on idevrecipes.com I figured I would be able to drop the code in for my template within a few hours.

If it seems too good to be true then it usually is.  I realized why I didn't see a whole lot of support for the indicators in other orientations or for the iPad.  The first obstacle was orientation support.  In @boctor's code the indicator is added as a subview to the main window.  This is not a bad practice because it ensures that the indicator is always on top of any subviews within the app. Unfortunately UIWindow doesn't support orientation, so when the device rotates the image looks crooked.  The solution is to add the indicator to the tabBarController's view.  Now that the image is repositioning itself with the orientation, unfortunately the new position is not centered.  To ensure that you will position the indicator in the center of each tabbar item ,regardless of orientation, you have to use the following calculation:

The last piece to the puzzle was to be able to force the indicator to recalculate it's position based upon the orientation.  This wouldn't be an issue with UIViewController, but I don't want to add in boilerplate code for each VC that I have.  (I already have boilerplate that I am going to abstract out with the next update).  Using NSNotification or a custom protocol seemed like overkill…and it was.  I ended up creating a category for the UITabBarController that overrides:

- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration

and calls the delegate method for the tabbar that is selected.

The rotation animation on the splitviewcontroller seems a little sluggish so I need to track that down and I am hoping to take out the dependency for an image and draw it programmatically.

A BIG SHOUT OUT to Peter Boctor (http://idevrecipes.com/) and Loren Brichter for being innovative and providing the code that was the basis for my little addition.

Thoughts on Why Event Driven Design is Not Very Mobile

Last week I was rereading Matt Gemmell's post "Finger Tools" and it really got me thinking more about the direction that app design should be headed for mobile devices.  Most apps up to this point implement what I would classify as Event Driven Design (EDD).  A user clicks/taps a button and is event/action is fired off and then you are presented with more navigation/action choices. Repeat/rinse.  Inherently, there is nothing wrong with this.  People are used to pressing buttons to get what they want.  However, this design implementation is counterintuitive to mobile platforms and where they, especially the iOS devices, shine. Using gestures, multitouch, taps, swipes, etc. Matt Gemmell sums this up pretty well:

"One annoying thing about desktop UIs that has also appeared on touchscreen devices is the “verb then object” style of interaction, or what I call “ink dipping”. You pick a tool from some globally-positioned area (like a toolbar or palette), then move to where you actually want to use that tool – like having to periodically re-dip your pen in an inkwell. It requires a lot of unnecessary hand-movement, and breaks the idea of “direct interaction” to a certain degree."

The reason that most apps, up to this point, have followed EDD, is the lack of screen "real estate" on the phone to really exploit gestures.  However, one of the early examples of breaking this mold was Tweetie creator Loren Brichter by adding in the ability to quickly get to tweet actions, by 1) swiping the uitableviewcell for a given tweet and 2) the now ever popular "pull to refresh".  With the release of the iPad all bets where off.  What was an acceptable practice on the phone for ui design is now flat out boring on the iPad.  I now expect iPad apps to get away from standard hierarchy navigation and app flow. Using gestures and "direct interaction" feels more natural.  I try as best I can to not be a hypocrite and spent quite a bit of time re-evaluating my own app designs moving forward.  As a consequence I came up with three different "direct interaction" mechanisms which I am currently looking to have patented so I can't go into details yet, but if all goes well then it will show further examples of how people interact with their device that goes beyond buttons and clickable menus…what I would refer to as 2 dimensional navigation and moves in a realm of a "Gyroscope" navigation and interaction.

Examples of "Direct Interaction"

These are apps that I use and or am inspired by for different types of navigation in an app.

iPadReeder.png

twitter_pane1.png

ipad_touches.jpg

Benefits to Proxying APIs Using with Your Own Servers

Last night I was hacking away at some new features in EraseUrX and I ran into, what I still don't know is, a coding error on my part or incomplete api with Facebook. At this point it really could be either one. I am using their graph api and have no problem authorizing a user, requesting extended permissions and getting a list of friends from that user.  However, when I try to post a message to someone else's wall I get an OAuthException message that Facebook couldn't authorize the application.  WTF?! I thought possibly that my access token was invalid or that my url that I was posting with was incorrect. Nope they are fine. I tested it using curl and the post went through just fine with the same access token. After a few more code changes to no avail I decided to approach it from a different angle.

Though most big services take a lot of pride and care in their API's that they produce they still inevitably change method names, authentication schemes, parameters, validation, etc. This type of uncertainty isn't easily managed when you have compiled code on a device.  If/when a service provide decides to change/delete something from their API, your app could possibly break leaving the users pissed and blaming you.  Even though it TECHNICALLY isn't your fault, developers should take ownership and responsibility to do whatever they can to provide applications with the best user experience.

I decided that I would create a small webapp/script on my server that would act as a proxy or broker between api calls from my app and Facebook. On the surface it looks like it is overkill, but the benefits definitely outweigh the overhead.

A standardized output
Depending on if my request is successful or not to Facebook I will get a different JSON response which is fine, but the JSON structure is also different.  If I were do to all response checking on the phone, not only is it EXTREMELY verbose, but I don't want to have to parse through two different object graphs.  Instead my webapp will get the respone(s) and create a standard response structure of my choice. Something like this:

// Success
{
  'status': 'success',
  "data": [
      {
         "name": "John Doe",
         "id": "55555"
      },
{
         "name": "Jane Doe",
         "id": "6666666"
      }
  ]
}

//Error
{
  'status': 'error',
  "data": [
      {
         "message": "Bad error message",
   "title" : "Bad error message  title",
         "type": "666"
      }
  ]
}

Having a standardized response my app code looks for an exact value in the json string, 'status', and transverse the rest of the json response and process everything accordingly.  Efficiency.

APIs Change
As stated above service providers (Facebook, Twitter, Google, etc.) can/will change their api at any given time.  It is by far easier to change code in a webapp, test and deploy then it is to modify code, no matter how well written it is, in a native device app.

Better Monitoring and Logging
Having your native apps hit your script will allow for better monitoring of a) how many user's are actually using your app b) if there are errors you can track down them down easier and faster c) more accurate analytics that are based on your use cases.  In addition, being able to integrate those stats into other business initatives and integration points.

Result Caching
I would bet that companies like Facebook are caching result sets for a better/faster response, but we will never know and to the full extent they are caching.  You can setup your own caching architecture that will best serve you and your apps needs supplementary to whatever may or may not be provided by the service.

Disaster Recovery
We have all seen the Twitter "fail whale" which means that ANY app trying to utilize that API is housed for x amount of time, which is not a good thing.  Having your own server side script would allow you to handle those unfortunate instances when the service is unavailable by using a cached copy of the result set if one is available or send back a message in your standard response that allows your app to present to the user that that piece of functionality isn't working at the moment.

By handling the majority of the requests/response on my server I reduce the amount of boilerplate code/frameworks that are in my iPhone/Android/Blackberry app, able to standarize the message format for more efficient parsing on the device and provide a better user experience.

To Kill A Mocking Bird Called "Your Twitter App"

Over the past week there has been quite a bit of news coming out of the Twitter HQ. First it was announced that Twitter has acquired Tweetie and subsequently hired it's author Loren Brichter.  They also have launched the promoted tweet service and for you real bird watchers out there the ability to add meta data to tweets using the API.  Finally, it was confirmed that Twitter is going to launch their own URL shortener and stop using bit.ly.  A recently published article on Mashable summaries one tech startup's frustration with the announcement of Twitter now coming out with it's own "official" Twitter client. Why is there so much frustration? Because developers, at times, feel they have been sabotaged by the very companies they are using.  Just to be clear, they are upset because a service that Twitter owns, that they allow developers to use for free, is now being used by the very company that created it in the first place to promote their own brand!

I'm just saying...

I am developer and know what it is like to have that great idea or great app and to have some MUCH bigger/better company come along and launch their own version which inevitably kills mine before it got off the ground.  However, those are the ropes.  Don't put all your "1"'s and "0"'s into one app or service.  That goes for everything in life.  This animosity towards Twitter, and any other information service, is quite misdirected.  As mentioned earlier, Twitter didn't go out and build their own app, they chose, quite possible the best Twitter client in the AppStore today.  Did developers really expect Twitter to NOT have an official app.  I am surprised it has taken them this long.  That is like Apple releasing the iPod, but not iTunes.

What does that really mean? If you create something that is TRULY great then there is a good possibility that it will get picked up.  Just look at all the startups and other mashups that have been acquired by big companies lately. Twitter has just released a site for developers that will aid the creation of new mashups and services to use with the information they provide not hinder innovation.

It is an unfortunate price that one has to pay when the service you rely on for your mashup comes out with their own official app that does the same thing and my sympathies are definitely with you, but if all you do is rely on that ONE great idea then you weren't going to last that long anyway.

Automate Adding Twitter Followers with Zend Framework

Adding followers to a user one at a time is sometimes a VERY lengthy process.  Last night the question was posed to me if there was a way to automate adding followers from users who follow someone else.

Example scenario:
John Doe follows Jane Doe
John Doe wants to follow at 600 followers of Jane Doe

Unfortunately, the Zend_Service_Twitter class doesn't offer any functionality to retrieve a list of followers from another user, but I was able to extend the class and add the functionality.

The particular user that I chose to test has roughly 6,000 users.  My client didn't want all 6,000, but the first 200.  Within 10 minutes the new custom class was written,  the script ran, and now my client was now following 200 new people of like mind. :)

I plan on submitting the feature request to the Zend Framework gurus to have the ability to find followers from other users so that it can be apart of the main service.

Until then here is the class and script: