Facebook API, I don’t like you

During the development of Reader for Facebook I ran into all kinds of issues with the Facebook API. I started with the goal of building a relatively simple application that would allow users to login to Facebook, retrieve their newsfeed, and have it read back to them using a Text to Speech engine.

At the time I started the app AVSpeeachSynthesizer wasn’t available within the iOS SDK so I ran into the wall trying to get Flite and OpenEars to work. It didn’t help that I was trying to do so in MonoTouch (it wasn’t yet Xamarin). I eventually got it working only to swap it all out when the new iOS APIs were released to do so natively. Little did I know the pain was just starting.

As I developed Reader, I worked my way through the Facebook API and identified that the combination of a Graph API call to me/home and the API’s for posting comments and likes would be all I’d need. With the API documentation in hand I set on my way to build the core Reader Facebook interactions.

Along the way I ran into lots of unexpected twists and turns that resulted in me spending way more time then I wanted combing through Stack Overflow posts trying to make sense of the Facebook API and the results I was seeing (which often didn’t line up with my expectations).

Low Res Images

For some reason the Facebook API often returns really low resolution images for photo posts. The resolution is so low that showing anything more then a tiny thumbnail isn’t possible. In order to work around the low resolution images returned from the main me/home graph API call, I’m making a second batch request for all the “photo” posts to retrieve all the available images and choosing an appropriate sized image for display. Unfortunately, for a subset of photo posts the graph API request to retrieve the images fails without any meaningful error message. My best guess is that there is some sort of permission on these posts that prevent the list of images available to be retrieved through the API. Regardless, the result is an occasional low resolution photo being displayed in Reader.

Newsfeed Filters Don’t Work

Somewhat recently I wanted to allow users of Reader to choose what filter to use when retrieving posts from Facebook. Although the default “newsfeed” filter is likely to be the most popular, it would be nice to allow folks to filter who they hear in Reader for Facebook by selecting from available filters (Friend Lists, Apps, etc.). Unfortunately, the Facebook API in many cases doesn’t pay any attention to the filter being passed in the me/home?filter=XXXX graph API request.

Random API Errors with Unexpected Side Effects

On the day Reader for Facebook was approved my wife rushed to the app store to download a “real” copy (she had a beta build on her phone). An hour or two later she called asking for a refund. It turns out that she was posting comments through the app that were returning errors, so she tried several times each time getting the same error. Despite the error, her comment was posted to Facebook multiple times. For some reason the Facebook API will return an error for certain calls but the action requested via the request will go through which makes it difficult for an app developer to appropriately handle. An API call that returns an error shouldn’t have any side effects.

Newsfeed is different via the API

In addition to the above “errors” API developers also have to deal with the fact that the results from the Facebook API don’t match up with what users see on Facebook. In Reader, I’m requesting the users home newsfeed, however, the items returned often times don’t match up with what is available in the newsfeed from within the Facebook app (or website). I’m still not sure what causes this, but it definitely leads to unexpected inconsistencies that users notice.

That’s a small sample of the Facebook API issues I ran into while developing Reader for Facebook. Based on my experiences I’m not sure I’d build anything substantial via the Facebook API. The API is too inconsistent and unreliable. I still believe leveraging the Facebook SDK and API to create social “hooks” for your app is worth considering but for more substantial integrations the pain isn’t worth the “payoff”.

Reader for Facebook

Today Reader for Facebook was approved by Apple and made available in the App Store. You should totally download it!

Background

I started working on the app that would eventually become Reader for Facebook over two years ago.  I started the project hoping to learn a bit about iOS development and figured I’d start with a small simple app that I could code and release in relatively short order.  Here I am two years later 🙂

Reader connects to your Facebook timeline and reads your timeline to you using Text to Speech.  Its a nice way to catch up on what’s happening on Facebook when you’re busy driving, walking, running, or just relaxing and can’t physically look at your phone.  On my drive to and from work I’ll start up Reader and catch up on what my friends and family have been up to during the day.

While the intention was never to create a full fledged Facebook client the app evolved a bit to support basic functionality for liking posts, adding comments, and had to be improved to support displaying various types of content that people post (images, videos, links).

While the development was relatively straight forward I ended up taking several extended breaks from development of the app due to frustrations with the Facebook API.  While the API is very rich and provides a lot of functionality it doesn’t always behave as you would expect and has a tendency to stop working or return random errors that are difficult to track down.  In fact, the version of the app released today has a bug when comments are posted related to one of these API bugs.  Despite the Facebook API returning an error messaging saying the request to create the comment failed it does indeed get posted.  After downloading the app my wife successfully posted 4 of the exact same comments due to this bug and called me asking for a refund! (not really but it sucks for your wife to find bugs in your app, after all I try to pretend like I know what I’m doing around these parts).

In addition to various breaks due to frustrations with the Facebook API and just general unavailability the project lost some steam early on when one of the Facebook hackathons was aired on TV and one of the projects was more or less to create Reader for Facebook.  With any development project, but especially side projects, its important to have motivation to continue to push forward and I lost the motivation to finish Reader shortly after.

Luckily my wife was there to encourage me and ask me if I had released the app.  I had to keep explaining it was nowwhere near complete and I had about 100 other features I thought it needed.  Eventually I decided I needed to simplify and focus on the core functionality of reading a users timeline to get the app shipped.  After all, the motivation for the project was to learn a bit about iOS development, learn the process of submitting an app, and getting it available in the App Store.  While the app still lacks many features I had planned it does achieve the primary purpose and is available in the store (YAY!).  If all the users (my mom, wife, and other family) like the app perhaps some of the other features I had thought about will make it into an updated release.

Technical Notes

The app was built with Xamarin (which was called MonoTouch and was part of Novell at the time I started the app!). Over time the tooling and overall experience of working with Xamarin improved by leaps and bounds. Xamarin Studio is a formidable, feature rich IDE, that makes developing iOS (and Android) apps a pleasant experience. I found the biggest hurdle to be finding compatible bindings for existing Objective C libraries that I wanted to leverage in the app. Over time, and with the introduction of the component store this improved dramatically…but early on it was a bit rough.

At the time I started the project C# was the only supported language and given my familiarity with the language it was a natural choice for my first app. It allowed me to focus on learning the core concepts and paradigms of iOS development rather then the language itself. I still have a bit of an aversion to Objective C and am glad that I’ll have the option of forgoing learning it in depth now that Swift and RubyMotion are options for projects I decide to attack with a non-Xamarin tool belt.

One of the big headaches early on was finding a text to speech API that worked reliably, and supported the MonoTouch toolchain. I started with Flite, moved to OpenEars, and thankfully with the final version was able to use the built in Speech Synthesizer classes available in the iOS SDK. Voice recognition is still a pain point and has prevented me from adding the ability to interact with the app via voice commands, so hopefully that API will be opened up soon as well. In the meantime I’m banging my head against the OpenEars SDK trying to get “like”, “comment”, “next”, “refresh”, and etc to be supported in Reader. Not to mention the ability to record full fledged comments or posts which is near impossible without shelling out $ for commercial speech recognition libraries.

The only other notable SDK that Reader makes use of is the Facebook SDK. Again, early in the process there were headaches with trying to get a MonoTouch compatible version of the iOS SDK but more recently the Xamarin Component Store has made the process silky smooth. The SDK and API itself is still buggy as all get out but I’m sure that will all be ironed out with Facebook’s recent commitment to API reliability (yeah right!).

Design Notes

At the very early stages of development I engaged with a designer on what at the time was called “TalkingFaces”(seriously, how terrible is that name!). I worked with him on a few iterations of a design but never ended up with anything I liked. Rather then stress too much on the design I pressed on with development hoping that as I made more progress I’d find some design inspiration and simply skin the final app and make it look super perty. As you can tell by the final version, it never did get super perty, but I hope its also not terrible.

I designed the app, icons, and screenshots myself. I had many fights with Photoshop and other tools which was another reason this project took me two years to complete. Somewhat recently I downloaded Sketch and got comfortable enough with it to complete the design items necessary to submit an app (icon, etc.). I’m still no designer but I’m looking forward to learning more about Sketch and trying to improve my design skills. The current app needs a design refresh to add some depth and separation to the UI but I’ll tackle that in an update, shipping was my goal and the current UI was “good enough” to ship.

Conclusions

It’s a relief to FINALLY move this project into the shipped category. I have a lot of ideas for improving the app but in the short term I’m going to take a little break and think about other side projects I want to move along and get closer to shipping.

If you have any feedback, comments, or suggestions for the app itself hit me up on twitter at @steveeichert, or head over to the Facebook page for Reader and give it a “Like”.

Oh, and don’t forget to download the app and recommend it to all your friends!  Download Reader