Let's Talk iPhone Event

I always love the last few months and weeks that build up to an iPhone/iPad announcement.  Though some of the rumors have turned into fact, most are just random, fabricated factoids that many MSM and bloggers push out there for the masses.  At the end of the day I can only presume that Apple doesn't pay those any attention except in the case of lost hardware.

However, I am not immune to reading a lot of these misleading articles. Granted I don't treat them as gospel there are a few things that I am very excited about.

First, is the official roll out of iCloud.  Having used the beta version the past few months I have been pleasantly surprised as it's convince and ease of use.  It is a huge win for the average consumer who has, up to this point, been reliant on iTunes and various other backup strategies to manage their content and media.

Second, is iTunes Match.  It has always been somewhat of a let down that users couldn't access all of their music from any of their devices.  The process is extremely easy and now you don't have to carry around a separate iDevice to hold your music catalog.

Third, wireless syncing.  I have a strong feeling that most IT administrators and children/grandchildren who have to provide tech support to their parents/grandparents will jump up and down over this.

Fourth, the API features with the new iOS have once again raised the bar for app developers.  Apple has listen to feedback from developers to make it easier for us to provide better functionality in our apps as well as more detailed customization options.  

*Bye-bye drawRect: category*

Fifth (possibly), Apple Assistant.  Rumor Alert! Could the headline "Let's Talk iPhone" really have a hidden meaning.  
Apple gave the masses the first decent implementation of multi-touch.  The communication mechanism that is inherit to all since birth.  Pointing, dragging, panning, zooming, swiping.  With the acquisition of Siri, there is no doubt that Apple has been putting a lot of effort in creating the near-perfect implementation of voice recognition for the masses.  On device voice processing via natural speech that is a native part of iOS.  If this is the case, then you will see a whole new generation of apps and a paradigm shift in how users, impaired or not, interface with these applications.

Apple...let's talk.

Custom UIActionSheet Using Core Animation

About four months I posted a blog and project that showed how to customize the buttons of a UIActionSheet.  In the disclaimer I stated that because of the use of the private api's if you attempted to submit your app with this technique to the App Store it will get rejected.

This time around a created a simple, yet effective customized, mock UIActionSheet.  Essentially it is just a custom UIView with three buttons that animates and dismisses just let an UIActionSheet.  All you have to do is assign a method to each of the buttons.

If I have time then I'll try and make it even more extensible by creating a custom delegate to make the classes even more reusable.

Upcoming to Universal iOS App on GitHub

In anticipation for the upcoming public release of iOS 4.2, I have updated my Universal iOS App project (iAd Branch).  The project will run on 3.2 and up with iAd support for iPhone and iPad (4.2 only for iPad).

I ran into some interesting hurdles while working on this update.  The first of which is that adding in iAd support for a project using a UISplitViewController SUCKS! #FAIL When iAds where first offered in the 4.0 iOS they came in two different size: 320 x 50 (ADBannerContentSizeIdentifier320x50) and 480 x 32 (ADBannerContentSizeIdentifier480x32) which served their purpose since you could use iAds only on the phone.  When iAd support was added for the iPad Apple was smart and deprecated those properties and added ADBannerContentSizeIdentifierPortrait and ADBannerContentSizeIdentifierLandscape, thus abstracting the dimensions that are available for any current and future devices.  This unification works great on the iPhone and iPad...except for when you implement UISplitViewController on the iPad.  The reason being that even though your root view or "detail" view controller are in landscape or portrait mode their widths aren't in the expected frame width for either choose of iAd. Thus you get an inaccurate display and you will an error in:

- (void)bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error

stating that an ad has displayed but is being obscured. In order to get around this I had to add in some padding to readjust the 'y' coordinate for the tableview's frame (only when the ad appears).  Why the rotation, and only on the iPad, gets screwed up I am not sure at the moment.  I created a simple, iPad only project and got the same results so there might be a bug, but until I am able to verify, my "padding" works".

It is important that if you clone/run this project that you read the debug console for iad display errors.  These are relevant errors passed to the delegate method and don't have to do with my code.  You will notice in the video that ad fails to load the first round.  This is due to an error from Apple serving up the ad because inventory is not available. Second time is the charm.

*important - always implement delegates to handle failures

In the next few weeks I'll be adding a branch where the Universal app will have Tabbar support.

Customizing UIActionSheet Buttons

One of the great benefits of iOS development is that Apple has provided the ability to customize almost any element thus not limiting a designer or developer with a stock look and feel.  Just take a look at subtle examples in Twitter for iPhone to the extreme of the Outside Weather app or Starbucks.  I am working on a nice size project and one of the requirements is to have the UIActionSheet buttons be a different color than the default gray color.  This turned out the be as straightforward as trying to change the look and feel of a tabbar.

::NOTE TO APPLE:: Customizing Tabbars and UIActionSheet buttons should be a lot easier. ::END NOTE::

It took a few hours, but I finally knocked it out.  At first glance I figured that each one of the buttons would be an instance of UIButton and I could located them in the view hierarchy and just update the background color either in a delegate method or subclass UIActionSheet and override drawRect:.  NEGATIVE.  

My next possible approach was to create my own custom view(s) and slap them on the UIActionSheet's main view and send everything else to the back.  Granted that has worked for some people and is a totally viable option, but I found it to be a very hacky solution for what I was doing.

After looking up a few questions on StackOverflow it turns out that sometime after iOS 3.1 the subviews in the UIActionSheet are an undocumented class instances of UIThreePartButton.

::BIG DISCLAIMER - YOUR APP WILL PROBABLY GET REJECTED IF YOU SUBMIT WITH THIS TECHNIQUE::

After digging up that little nugget about UIThreePartButton I finally had turned a corner.  The next hurdle was trying to find the correct method to use from the UIThreePartButton class to change the background color.  Unfortunately, there isn't a backgroundColor property for that.  Granted since I am dealing with a class that inherits form UIView I could set the subviews backgroundColor property to [UIColor redColor], but when I did that I didn't get the expected result of a button with a red background.  The button became a red tint and the view behind the button was red as well.  Obstacle.  Looking at the methods/properties that I DID have I went on a little intuition that Apple wasn't using a color, but a stretchable background image for the button.  I grabbed the background graphic that I wanted and used - (void) setBackgroundImage:.  SUCCESS!!!!!!!

I wasn't quite finished.  Background button was what I wanted, but I needed to change the font color from black to white.  But wait there isn't a method to set the font. However, UIPushButton inherits from UIThreePartButton so once again going on an educated guess/intution I was able to use setTitleColor:forState: and perfection.  Excatly what I wanted and needed.  UIActionSheet with red buttons and white font.

Even though I can't submit any app to the AppStore because of the undocumented class working through the exercise was very enlightening in the areas of ui customization, design patterns and general problem solving skills which should always be in the top of a developer's skillset.

I posted my example on github.  It was compiled with 4.0 with XCode 4 Preview 3, but XCode 3.x should work.  If you run into any problems then let me know.

Creating a Universal iOS App Tutorial

Just when I thought I had a somewhat decent grasp on developing and deploying iOS apps Apple came out with the iPad and threw a whole new element in the mix when it comes to developing.  Thankfully, the iPad will allow iPhone apps to run on the device, but the user experience is definitely sub-par.  So what is the best approach to providing an native iPhone app and a native iPad app?  The first option is to duplicate your existing iPhone app code base and modify all your views and some of the controllers to take advantage of the features in the 3.2 SDK.  The problem with that is the massive DUPLICATION of code and to be honest it seems quite lazy.  I have seen lots of examples where developers use the idiom check for which device is being used, as well as, runtime checks for selectors in order to leverage the correct methods/classes for the given device.  While this is certainly a better approach then having two separate code bases with 90% of the same code you now have code that is sprinkled/littered with if/else checks.  Unfortunately, you are once again stuck with code that will be maintainable for long.  After reading the chapter on universal apps from the upcoming book from Pragmatic Programmers, iPad Programming, I found a much better design pattern of splitting out the app into Shared, iPhone and iPad resources, classes and delegates.

As a side note, due to the ever exponential growth of iOS device popularity developers are not going to have the bonus of just jumping straight into writing an app like we did when there was just the iPhone.  A lot more thought needs to be given to design patterns (especially regards to the quality of your MVC) and application flow.

In order to make life a little easier on myself since a few universal apps are coming in my near future I decided to create a basic "template" for a universal app.

Features
  • Compiled for 3.2 and 4.0
  • Utilizes navigation controller based app for iPhone device and SplitViewController for iPad
  • Shared "model" class and controller classes
  • Separate resources (classes/xibs) for the different devices

Comments and improvements are ALWAYS welcome.  One improvement that I know I want to make is having the "detail" controller from the SplitViewController to be a UINavigationController.

JandB Photo App Officially Launched

The past three months I have been working on an iPhone app for a local photographer John Childress.  Like most great iPhone apps, the idea that John had dealt with a concept that would:
  1. Get him iPhone app market for his business
  2. Provide a new value-added service to his customers
  3. Providing a new form of media to promote his business to potential new customers
In doing research for the app he and looked at a lot of other photo gallery viewing apps in the App Store to see what features dominated and most importantly what could he offer that others didn't.  Currently, after you have a photo shoot John will send you a gallery code and you can then view the flash slideshow on his site.  There are few issues  with the "mobile" market that we all live in now.  The first is you can't view flash on the iPhone so trying to view your photos on the phone and show them off to friends and family is not possible.  Rewriting his gallery website to be non-flash would be a good idea, but the system is currently in place and is integrated with his core business aspects.  The other roadblock that he runs into is that most people want to view slides shows with a soundtrack. 

*I think I just heard the RIAA scramble to call their lawyers for a lawsuit just for a business thinking of doing that*

With the JandB Photo app, which is a free download, users can add a gallery to their phone and enjoy the slideshow of images with an optional custom soundtrack from tracks on your phone.  Want to share a picture on Facebook?  Not a problem that feature in there as well.  Want to view current specials that John is offering, there is a place for that.

What I really love about the app from a consumer point-of-view is that it is simple and straightforward.  There is not guessing about what to do.  A specific task is performed in the least amount of steps.  You don't have to think.  From a developer's point of view this app was one of the more challenging apps I have done and learned a lot.  The app uses two complex frameworks.  Three20 and Google's objective-c framework.  Though integrating these components took sometime and I went through a few glasses of wine for support, both saved me COUNTLESS hours of custom development.

Three20 Modifications
Apple should really be THANKING @joehewitt for this work his creation of the Three20 framework.  Especially the photo gallery/viewer components.  If it wasn't for Three20 then I am sure that developers would be rioting outside of 1 Infinite Looper Cupertino, CA for the lack of such important piece of built-in functionality.  With all it's glory though I did have to make some modifications which include integration of posting an image to Facebook and adding in the ability to play an playlist that is associated with the gallery.  Unfortunately, and I plan on working on this soon, I had to modify the core source which to be frank felt dirty.  I just didn't have time to write classes extensions and categories for the gallery controller and viewer controller.

Google Objective-C Library
Man there really is a lot going with this library.  Everything and the kitchen sink.  When scouring through the wiki page for this I didn't see a lot of really good iPhone examples, but I was able to piece together what I couldn't figure out from their Mac example to modify a document and worked without a problem.  My only real disappointment with this library is that there, IMHO, waaaaaay too many delegate methods and callbacks.  With that being said I do understand why. Google gives you granular control of the content, metadata, revisions, ALC, etc. and objective-c is verbose so the end result is a lot of code to accomplish what I need which was: lookup a document by a given name, grab the latest revision, insert text at the end, close/save the document.

All in all I am very happy with the app.  The first few future releases will mainly deal with performance.  I still feel that I could squeeze some more performance on parsing through the images on the server side and optimize the network calls on the phone.  After that some UI tweaks. To me the gallery listing could be a little prettier.  Most importantly any enhancements that users want to see.  Feedback is always welcome.

Head over to the App Store and check it out.  If you want a check another gallery besides the default, then use "McKinna", without quotes.  Shameless plug for my daughter.

How to Create SMS Ballon iPhone Table View

I was working on incorporating an "sms ballon" type view for a client and while doing some research on the best, and different, ways to implement the functionality I came across a great tutorial, but thought it could be cleaned up just a little bit which should make your FPS increase and I fixed some memory leaks.  I wasn't able to run any performance tests on it so I would welcome ANY feedback how to improve the code.

The key to making the "ballon" background grow and shrink based upon the amount of text is using:

UIImage *balloon = [[UIImage imageNamed:self.imgName] stretchableImageWithLeftCapWidth:24 topCapHeight:15];

If someone has any advice on how to make the font look better please let me know.

UILocalNotification Example Project Using iOS4

One of the greatest new features that is included in iOS4 is the power that developers have to deliver local notifications.  At the time that the first beta was released in April I was writing specs/requirements and project timeline for a potential app which would have ended up taking me about 5 months to develop.  A large part of the project schedule dealt with having to setup/maintain user reminder preferences...the number of reminders, frequency of each one, time zones, etc.  I tried to think of ever solution that I could that didn't involve the server component, but there really wasn't any other way.

UILocationNotification to the rescue.  After looking over the API docs, Apple had provided exactly what I needed and I was able to cut out 2.5 months from the project schedule because of it.

I was able to create an POC app using UILocationNotifications in literally 5 minutes.  It involved two easy steps:

 

  1. In the app delegate class I added the following method to verify that the event was fired off if the app was running. -(void)application:(UIApplication *)application didReceiveLocationNotification:(UILocationNotification *)notification;
  2. In the -(void) viewDidLoad method of my controller you alloc/init a new UILocationNotification object, set the fireDate which is an NSDate object, what time zone you want, what the notification message(body) should be and then add the UILocationNotification object to the UIApplication scheduleLocalNotification method

 

There are two possible end results.  The first being that the event is fired off while the app is running in which case you will not see anything. Hence, why I added the NSLog to the didReceiveLocationNotification method.  The second is if you close the app before the notification has fired and in that case you will receive the alert box with your message.

Download XCode Project

Note: This was compiled with iOS4 GM and tested on iPhone 3G/3GS

Facebook Graph API with a Native iPhone Application

One of the biggest gripes that I have with working with the FBConnect iPhone SDK, and really the Facebook API, in general was having to deal with a very inefficient REST implementation.  Callback after callback, protocol after protocol, major bugs (that have yet to be fixed as far as I know), and my biggest issue is the nasty user experience having to login a user.  I was very excited to hear when last month Facebook announced they had came out with a new API that would allow great security, ease and flexibility.  The pains of having to go through currently working functionality and refactor the code to accommodate the new features wasn't too much of a problem for me because it would mean a reduced code set on my part and I would be able to get rid of the Facebook Connect SDK.  I set out to test my theories and functionality via a quick web app.  No problems.  Then I proceeded over to my native iPhone app.  EraseUrX v2.0.  The new authentication mechanism utilized in Open Graph is OAuth2.0.  While many of the headaches and complexities of using OAuth are addressed and the documentation for using it in a mobile web app are well documented with Facebook they TOTALLY dropped the ball on providing any direction on using it with a native iPhone app and they don't provide an updated SDK.

I could one of three things: 1. Use the old Facebook Connect which should still work for the forseeable future, but as stated above has too many issues that I don't want to deal with and they could drop support at any moment. 2. Wait for Facebook to publish a new SDK, but how long would it take them 3. Just figure it out myself and have a flexible solution that didn't relay any third party framework.  I went with option 3.
The first thing you need to do is setup your app with Facebook.  Second, you will need to create a "callback" page that Facebook will send the request back to once the appropriate code and token has been given to your original request.  Third, once you have gotten the access_token from Facebook then you need to put it in a DOM object. This is important so that you can retrieve it via the UIWebview's javascript string evaluation and then finally save the access_token in NSUserDefaults for any subsequent requests.  In my case I wanted to get a list of the currently logged in friends.  Instead of having to go through the callbacks and delegate methods associated with the FBConnect SDK I now have user's login via OAuth and I make a call to, https://graph.facebook.com/me/friends, and get a JSON response of what I need.  Simple. Beautiful.
Callback Example (PHP):

Custom ViewController (I am not including setting up the uiwebview. I assume you already know how to do that):