Forward Geocoding in iOS4 and iOS5

Forward Geocoding

It is a common scenario that every developer has run into.

Locate places near me based upon a particular address and/or zip code.

In order to get the correct results the address needs to be converted to a lat/long coordinate. With iOS5 Apple has provided us with CLGeoCoder class which has convience methods for reverse/forward geocoding. Unfortunately, there isn’t really any built-in functionality for iOS4. Most current apps still have to support iOS4 so what are developers doing to fill the gap? Write their implementations for multiple OS support. Below is what I use.

** Note: I did use Sergio Martínez-Losa Del Rincón article as a starting point for the iOS4 support.

Techniques

  • Google’s Map API
  • CLGeoCoder
  • Objective-C blocks for callback
  • Grand Central Dispatch

Implementation

iOS5

I tackled the easiest solution first. Utilizing iOS5’s CLGeoCoding geocodeAddressString:completionHandler: . However, when I first use the method I kept getting back a location of {0.0,0.0} in my log. The reason being that I was neglecting the fact that the method executes asynchronously and doesn’t return its value. Hmmm….

Not too much of a hurdle thanks to the implementation of block handling. By adding a completionHandler to my own method I was able to provide a callback with the appropriate coordinate that I need after the request had finished.

iOS4

Duplicating the ease of the iOS5 functionality was a bit more involved. I created a category method on NSString (see the above referenced article for code origin. I did make updates to it.) for making a call to the Google Maps API and return their forward coding result. The method itself isn’t asynchronous because I wanted to leave the decision of whether or not to call the method async or sync up to the developer. To provide asynchrous support was easy just by utiliizing GCD.

Decision Time

Deciding which code block should the calling method execute was the final task to finish. Once again this was extremely simple.

if (NSClassFromString(@“CLGeocoder”)) { // ios5 } else { // everything else. in this case we are assuming there isn’t support for iOS3.x }

Code

Efficient String Manipulation With Objective-C

One of the best interview questions that I have ever been asked, and now ask myself to potential candidates, is create a function that will transform any set of words into an acronym.  The reason why I like this question is that it shows how well the candidate understands basic string manipulation, problem solving and how efficient their technique is for the string manipulation.  Regardless of the language that is chosen the two techniques use by most are to either use some sort of regular expression or split.

Regex techniques with PHP, Javascript, Python and Ruby are the most popular (I did it using PHP), but I was curious as what an implementation would look like using Objective-C.  It was my theory that using regular expressions would incur more overhead and than using a “string split” technique.  Apple does a fantastic job with making their framework api’s pretty darn efficient, but I had a feeling that with this type of simple manipulation using a regular expression would be like lighting a grill with an atom bomb.  The results weren’t so dramatic, but none the less it does turn out that using componentsSeparatedByString is a better use of resources....for a single manipulation. When iterating and manipulating multiple strings I prefer to use regex.

When I iterated over the string 1000x the time to execute was almost the exact same.

I even tested two different regular expressions to make sure I wasn’t being to liberal with my pattern.  The difference was negligible.

Test String: "hEll0 WoRLD please hElP me"
Standard Regular Expression: "(\\w)+\\s?"
Boundary Regular Expression: "(\\b\\w)"

Single (regular regex)
Time to parse using regex: 0.003947
Time to parse using componentsSeparatedByString: 0.001246

Single (boundary regex)
Time to parse using regex: 0.003747
Time to parse using componentsSeparatedByString: 0.000668

1000x (Regular)
Time to parse using regex: 0.511170
Time to parse using componentsSeparatedByString: 0.538784

1000x (Boundary)
Time to parse using regex: 0.555807
Time to parse using componentsSeparatedByString: 0.485708

Here is the test project

Fast String Concatenation

Besides collection/list iterations, string concatenation is probably the most common developer task. Doesn’t matter the language.  Unfortunately, this is done incorrectly, especially with large strings.  I myself am guilty of taking for granted what goes on under the hood when performing this operation. After reading this article I found myself wondering about the mutability of strings in Ruby. Strings are natively mutable so you don’t have as much performance hit when doing basic concatenation, unlike Python which treats strings as immutable, thus “+=” performs a copy-on-write. No efficient at all. For small string concats doing the standard: “+=” or “+” is still the shortest distance between two points, however manipulating a string of any significant size, what seems to be the most efficient across Python and Ruby is to add each separate string into an array and then join.

Examples:
Ruby: ** Thanks to Travis Dunn for codev

Python

Do to the fact that I am doing more and more large scale projects performance is more important than ever and paying close attention to these little details allow for performance boots very quickly.

UITabBarController Subview Gotcha

By far the most view blog article that I have, and subsequent Github project, is my Universal iOS App Template.  Unfortunately, it has been a tad bit neglected. There were some memory leaks, still supported 3.2 and not iOS5 compatible.  Now that I am working from home I have dedicated part of my day to personal projects and the first order of business is to get the app template up-to-date.  Most of the work was just cleanup and minor tweaks.  One of the branches however required a little bit more work. The template that comes with TabBarController support. A few months ago I added in the feature of having a “Tweetie” style indicator slider.  In 3.2 - 4.x iOS everything worked fine.  In iOS5 the indicator was not initially centered in relation to the first TabBarItem, but the entire TabBar.  When you selected another TabBarItem the indicator would move, but not in the correct position either.

The number of subviews are different between the iOS4 and iOS5.

--- iOS5
2011-11-17 09:14:54.290 UniversalExample[8989:f803] view frame: {{0, 0}, {768, 1024}}
2011-11-17 09:14:54.293 UniversalExample[8989:f803] view frame: {{181, 1}, {76, 48}}
2011-11-17 09:14:54.294 UniversalExample[8989:f803] view frame: {{291, 1}, {76, 48}}
2011-11-17 09:14:54.296 UniversalExample[8989:f803] view frame: {{401, 1}, {76, 48}}
2011-11-17 09:14:54.297 UniversalExample[8989:f803] view frame: {{511, 1}, {76, 48}}

--- iOS4
2011-11-17 09:16:06.751 UniversalExample[9033:b303] view frame: {{181, 1}, {76, 48}}
2011-11-17 09:16:06.754 UniversalExample[9033:b303] view frame: {{291, 1}, {76, 48}}
2011-11-17 09:16:06.754 UniversalExample[9033:b303] view frame: {{401, 1}, {76, 48}}
2011-11-17 09:16:06.755 UniversalExample[9033:b303] view frame: {{511, 1}, {76, 48}}

I now confirmed that there indeed was a difference in how the center position was being calculated. In iOS5 the first subview is the entire frame of the view.  However, I didn’t know which view(sub or super) that it might be referring to.

The best uiview debugging tool for situations like this is the recursiveDescription method.  If you haven’t heard or used it before I suggest/encourage you read Oliver Drobnik’s blog on it. In summary it is a private method to iterate over a views hierarchy.

After calling this method on the subviews in both iOS versions I saw the culprit. The first subview of a UITabBarController is an UITabBarBackgroundView, which obviously is going to extended the entire length of the tab bar.

iOS4


iOS5


Why did Apple add this subview you might ask? They added it because of welcome changes to UIKit.  Since iOS 2.0 developers have needed the ability to customize many of the UI elements, but unfortunately there wasn’t a straight forward way to accomplish this. The categories and hacks that people came up with are pretty cool, but not maintainable. With iOS5, and updates to UIKit, you can customize background images, tint color, selected images, etc. to your heart’s desire.


In order to fix the iOS5 bug in my template I just had to add a quick runtime check on the OS version and increment the index by 1.

All is right with the world.

UIWebViews Are Horrible

After spending the last few days trying to improve performance with a local html document I am convinced that UIWebView is a horrible component that should be limited to only showing remote web page documents.  What brought upon this rant, and proposed solution for it, had to do with the half a second flicker between clicking on a TabBarItem in a TabBarController and the rendering of the local html file itself. If a user navigates away from the TabBarItem and then back again it will load instantly since the contents are now cached in memory.  However, I just couldn’t get past that initial flicker.

There are three different methods of loading an html document into.
  1. - (void)loadRequest:(NSURLRequest *)request
  2. - (void)loadData:(NSData *)data MIMEType:(NSString *)MIMEType textEncodingName:(NSString *)encodingName baseURL:(NSURL *)baseURL
  3. - (void)loadHTMLString:(NSString *)string baseURL:(NSURL *)baseURL
Source: http://cwil.es/uJznzA

The first thing I tried was timing each method to see which was faster.



The difference is negligible.  The second route that I attempted was to use Grand Central Dispatch (GCD).  Using GCD to manage process intensive logic that would normally block the main thread makes EVERYTHING so much better.  

Unfortunately, this is not the case with loading the local html file.  In fact, the speeds were essentially the same as using the single threaded paradigm.  I am assuming this to be the case because of the slight overhead of managing the threads. At the end of the day I am not gaining any performance.

Due to this frustration I am going to look into using @Cocoanetics NSAttributedString-Additions-for-HTML and save UIWebViews for remote display only.

Test Results (iOS5 Simulator. Ran code 4 separate times in - (void)viewDidLoad)

Main Thread Only

loadRequest
  1. 0.024776 seconds
  2. 0.025888 seconds
  3. 0.023575 seconds
  4. 0.026948 seconds
loadHTMLString
  1. 0.020844 seconds
  2. 0.063485 seconds
  3. 0.026386 seconds
  4. 0.057899 seconds
loadHTMLData
  1. 0.027755 seconds
  2. 0.036826 seconds
  3. 0.026125 seconds
  4. 0.025203 seconds
Grand Central Dispatch

loadRequest
  1. 0.029463 seconds
  2. 0.025321 seconds
  3. 0.026808 seconds
  4. 0.033857 seconds
loadHTMLString
  1. 0.025549 seconds
  2. 0.030053 seconds
  3. 0.027117 seconds
  4. 0.022959 seconds
loadHTMLData
  1. 0.035207 seconds
  2. 0.034666 seconds
  3. 0.029324 seconds
  4. 0.023069 seconds

Fun Times with Objective-C Runtime

Good reusable solutions to problems usually come out of necessity rather than luck or leisure.  Over the past 18 months I was always faced with problems of how to simplify the data integrity, security, and aggregation of multiple datasources, usually in big organizations that would then be fed in an iOS app.

The first solution to this issue is to create the "man in the middle".  Essentially a proxy/web services layer that acts as the gateway to all the necessary model objects.  Utilizing tools such as Gearman, CouchDB, MySQL, PHP, Python, Memcache and a little bit of Apache to make everything complete I was able to deploy a lightweight standard response to the iOS app.  As requests from various business groups would come in I found myself taking more and more out of the app and putting that logic into the services layer. Instead of having to rely on the app to handle security, data integrity, computational analysis, image manipulation, etc. I pushed that onto a light weight stack server side that could be scaled easily and mainainted without having to revision the app for basic model object changes.  The added benefits that I saw later on were that I could adapt the response based upon the request…(Android, iOS, mobile web, desktop browser, etc.)

Now that I was concentrating more on feature sets, bug fixes and UI enhancements I was still stuck with having to manage various model classes within the app.  This was a serious pain point to me. I wanted to be able to consolidate the various list and detail controllers that I had down to one instance of each.

Objective-C runtime to the rescue.

Let me be very clear that objective-c runtime is VERY powerful and not for the faint of heart, but when used effectively can be quite useful.  The approach that I took was as follow. 

Use the existing "standard" json format from a web services layer and restructure the "responseObject" so that it gave meta information about the model name, properties for class, which properties should be displayed on the list page and detail page.  By structuring the json  (xml, plist, etc) play load this way I now can push changes to model object and display anytime I want.

In the github project I use an "Employee" object as the example. The app should be able to show a list of employees (title and subtitle) and then a detail page for each employee that would display up to 3 properties.

I have included another json file for "Events" just so that I can show the flexibility. The same list/detail view controllers are now reused for two different objects.

The (current) limitations.
  1. There is an assumption that your list view will use the subtitle uitableviewcell enum type.
  2. Parsing and creation of classes doesn't take into account types other than nsstrings. I have an idea to remedy this, just haven't implemented yet.
  3. What about images?  Most list views have an image associated with it.  What I am thinking about it having a flag set in the properties specifically for images so that they can be loaded asynchronously.
I will be adding in these features.  I am still getting my head wrapped around some of the advanced features of runtime. Below are the links to resources that I used in my research.

Posted on slideshare is the presentation that I gave. It details the philosophical and practical importance of having an SOA that is similar to what I described.  It was heavily inspired by the presentation written on the subject of NPR's SOA.

Presentation References:

Fixing Blurry Text in iOS

Quick Pro Tip:

It never fails that no matter what project, simple or complex, I always run into a unique scenario that makes me scratch my head.  With the latest project I am working on the UI is almost 100% custom.  The views have custom CAGradientLayers, the views are positioned dynamically, special touch events, custom UI date pickers, etc.  Like most developers after staring at the screen for long periods of time text starts to look blurry.  After I looked closer I noticed that all my label text was actually blurry.  As far as I can tell it only occurs when the UILabels were added as a subview for a subclass for a UIView.  Though I am not 100% sure why this is occurring I am pretty confident that the blurriness is caused by frame calculation from the superview has a non-zero fractional component.

In order to remedy this situation, and future proof the app, I round the label's frame and center.

Everything is now all crisp and clear.

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.

Please Enter Your Password Gesture

The more and more that I develop apps the more I try to challenge myself to come with creative ways for users to use the apps. Really trying exploit the power of multi-touch. As mentioned in a previous post, this trend is becoming more and more mainstream. Unfortunately, when it comes to authentication, we are still stuck using the old attage of a PIN and/or using biometrics, which never really caught on with the masses. I personally think that has to do with implementation of it not the mechanism.

In order to try and contribute, to a hopefully better way to authenticate, I started working on a password gesture framework. Though password gestures aren't new what I think differentiates mine, at least conceptually, is how it deals with resetting it. My first thought was to just stick with the same old "email me my password", however email isn't always relaible and the "gesture" password isn't stored on a server, but on the device. In addition, I didn't want to have to rely on a separate server or component. Lastly, by doing that I am relying on an outdated "desktop" thought process of handling lost/forgotten passwords. So how do I give a user a usable and easy way to reset their password without having a server dependency or leaving the app?

My solution is that during the password setting process is to present the user a list of pictures and have them choose N out of X. If they need to reset their password they will be presented with the "reset" picture screen and select the correct ones. If the correct set of pictures are choosen then reset occurs. If not then fail. Due to my extremely busy schedule I haven't had the opportunity to really dedicate the time I want to. I am hoping that posting this to github that the iOS community will take it and make suggestions or fork and implement it with ideas and features that I haven't thought of.

I have started the project as a sample app, but once it reaches a stable point I will make it a static library that can be dropped into any project.

It goes without saying that I am really looking for feedback on this. All comments and suggestions are welcome.

Password Gestures on Github

Using CAAnimationGroup for View Animations

Lately I have been pushing myself to increase my knowledge and understanding of more advanced animation techniques. The more that I
dig into the lower level
core graphics framework and core animation the more impressed I become with their power. I also have a greater 
respect for those developers who can leverage their power in creative ways.

For most use cases leveraging
uiview basic animations with blocks will do exactly what you need. However, in my particular case I wanted to
accomplish the following. Scale, rotate and change center point of subview "A" to subview "B" all at the same time.

Taking my own advise I first started down the path of using basic uiview animations. I want to make sure that each different piece of
the animation would perform the way I wanted them to. Separately, they did exactly what I wanted. Unfortunately, grouping these together was
not going to happen with uiview animations.

When I ran the process all the animations executed, but the transition to subview b's center point was very jerky. To make sure that I didn't
miscalculate any of the individual animations I went back and tested each one separately. Each animation ran smoothly. When I ran the group within the block
I had the jerkiness problem of animation the center point.

After going back and reviewing Apple documentation I found what my problem was.
Imagine that. To do the rotation I apply a transform on
the view's layer. However, the transform performs it's animation based upon the views center point. Since I was trying to apply an
animation on the center point as well the group animation had to reposition subview A's center point first before it could apply any of
the other animations. Hence the jerkiness.

I pushed all my animations to a
CAAnimationGroup and all the transitions were performed.


-- 
Cory D. Wiles
kwylez@gmail.com
www.corywiles.com | twitter.com/kwylez