Adventures in Appleland

by Derek Clarkson (d4rkf1br3 [at] gmail dot com)

Fixing Nslog Output

In my dUsefulStuff static library project I have a define which defines a logging macro depending on whether a preprocessor debug flag is set. It looks something like this

#ifdef DC_DEBUG
    #define DC_LOG(s, ...) \
        NSLog(@"%s(%d) %@", __PRETTY_FUNCTION__, \
        __LINE__, \
        [NSString stringWithFormat:(s), ## __VA_ARGS__])
#else
    // Effectively remove the logging.
    #define DC_LOG(s, ...)
#endif

This makes things really simple when writing code because I can effectively include a pile of logging when developing and it all just disappears when I compile a release version. The output from NSLog is controlled by NSLog and looks like this:

2012-05-02 14:08:49.452 dUsefulStuff simulator unit tests[21353:f803] -[UIColor(dUsefulStuff) isEqualToColor:](15) My message!

As you can see it prints out these items of information:

The problem I have is that this takes up a lot of space and some of it I’m just not interested in. This has been bugging me for a while now and I’ve finally found a solution – swap out NSLog for CFShow like this:

#ifdef DC_DEBUG
    #define DC_LOG(s, ...) \
        { \
            NSDate *now = [NSDate date]; \
            NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; \
            [formatter setDateFormat:@"mm:ss.SSS"]; \
            NSString *dateString = [formatter stringFromDate:now]; \
            CFShow([NSString stringWithFormat:@"%@ %x %s(%d) " s, dateString, pthread_mach_thread_np(pthread_self()), __PRETTY_FUNCTION__, __LINE__, ## __VA_ARGS__]); \
            [formatter release]; \
        }
#else
    // Effectively remove the logging.
    #define DC_LOG(s, ...)
#endif

which prints out a line like this:

08:49.452 f803 -[UIColor(dUsefulStuff) isEqualToColor:](15) My message!

Here all I’m printing is the current minutes:seconds:milliseconds, thread-id, location and then my text. It may seem like this is not much different but it can make quite a difference when there looking through a log.

Posted on 02 May 2012, View comments

New Version Of Simon V0.1.8

I’m pleased to release Simon build v0.1.8 The emphasis for this release is a re-worked UI. It’s been cleaned up and new functionality added. Now you can re-run all tests, some test or an individual test. This is particularly useful when debugging.

Posted on 08 April 2012, View comments

Fixing Xcode Permissions

Running XCode from a non-Admin user works reasonably well. However there are a few little quirks. One is that when you attempt to run your application in the Simulator, XCode will prompt for permission to modify system settings so that it can go into debug mode. This is rather annoying because it does this every time.

The root of the problem is that non-admin users are not in the “Developer Tools” security group. Even more annoying is that if you look in “users and groups” in settings, there is no such group present. The group exists, but it’s a unix group so you have to add the user at the command line. Googling around I found two commands that will do this for you:

# Option 1
sudo dscl . append /Groups/_developer GroupMembership <user>

# Option 2
dseditgroup -o edit -u <admin_user> -t user -a <user> _developer

Notice that the name of the group is _developer. I have not looked up these commands in detail to see exactly how they work, but they do the job. I went with option 2 which I found worked very well. It prompted me for the admins password and everything was fixed. I can now run my app without having to enter the admins userid and password every time.

Posted on 02 April 2012, View comments

New Version Of Simon V0.1.7

It’s been a while since I’ve announced a new version of Simon so I thought I’d drop a note to say that I’ve just uploaded the DMG file for version 0.1.7. This release contains a lot of new stuff and fixes, including the ability to enter text and wait for animations to finish. Enjoy!

Posted on 24 March 2012, View comments

Accessing Yellow Page Data Using Sapi

(Disclaimer – yes I work for Sensis :-)

Recently I was asked to do an upgrade a web site at work to replace an ageing search function with Sensis’s new SAPI search engine so I thought I’d put up a small discussion of how I went about it.

SAPI is a restful JSON based service which external developers can use to search both Yellow and White Pages listings combined. Providing a web based API allows developers to get creative and come up with new ways to utilise the information. In my case it was a fairly simple replacement of an established search with the SAPI search so it’s a good example of the basics of using this API.

To achieve this result I decided to make use of 3 core technologies apart from SAPI itself:

So lets get started

The first thing I had to do was to was to setup a HttpClient object ready to access the SAPI website and build a url to query the data. I’ll use some hard coded data here, but it’s easy to figure out where you would replace it with data from your input form. Note also that to be able to query the SAPI search engines you also need a SAPI Search API Key which is free for both development and production use.

// Get a client
DefaultHttpClient httpclient = new DefaultHttpClient();

// If you are behind a firewall and proxy you will probably need to enable this code.
// HttpHost proxy = new HttpHost("my.proxy.host.com.au", 8080);
// httpclient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);

// Build the parameters we are going to add to the url. 
// Note: There are many more than this you can use to refine this.
List<NameValuePair> parms = new ArrayList<NameValuePair>();
parms.add(new BasicNameValuePair("query", "Plumbers"));
parms.add(new BasicNameValuePair("rows", "20"));
parms.add(new BasicNameValuePair("page", "1"));
parms.add(new BasicNameValuePair("key", "xxxxxxxxxxxxxxxxxxxxx")); // This is your API key.
parms.add(new BasicNameValuePair("location", "Richmond"));
parms.add(new BasicNameValuePair("state", "VIC"));

// Use the developer connection URL.
URI uri = URIUtils.createURI("http", "api.sensis.com.au", "-1", "/ob-20110511/test/search", URLEncodedUtils.format(parms, "UTF-8"), null);

It’s pretty much what you are looking for, where and paging controls. SAPI has a lot of options you can add to refine your queries even further. For example, you can specify to include listings within a radius around a central location, or filter out potentially unsafe links for minors. Now lets execute the query and map the results into some java beans:

try {
	// Send the search Request to SAPI.
	HttpUriRequest request = new HttpGet(uri);
	HttpResponse response = httpclient.execute(request);
	
	// Get the Jackson object mapper which can read the results.
	ObjectMapper objMapper = new ObjectMapper();
	
	// Tell the object mapper to ignore JSON values we do not have a bean property for.
	// Otherwise it will throw an exception.
	objMapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
	
	// Tell the object mapper to use Mr Bean to create the bean classes.
	objMapper.registerModule(new MrBeanModule());
	
	// Unmarshal the JSON response into beans.
	SapiSearchResult sapiResult = objMapper.readValue(response.getEntity().getContent(), SapiSearchResult.class);
		
} finally {
	httpclient.getConnectionManager().shutdown();
}

So that’s the SAPI, Httpclient and Jackson parts done and we now have java beans all ready for using in our UI. But wait … Where did those beans come from?

Mr Bean

The reason I have not started by defining beans is because Mr Bean makes it so easy as to be trivial. Prior to this you would have had to define your java beans as fully realised classes. For example, here’s a simple version of SapiSearchResult (there are a lot more properties you can add! ):

public class SapiSearchResult {

	private int totalResults;
	
	private int code;
	
	private String message;
	
	private List<SapiListing> results;

	int getTotalResults() {
		return totalResults;
	}

	void setTotalResults(int totalResults) {
		this.totalResults = totalResults;
	}

	int getCode() {
		return code;
	}

	void setCode(int code) {
		this.code = code;
	}

	String getMessage() {
		return message;
	}

	void setMessage(String message) {
		this.message = message;
	}

	List<SapiListing> getResults() {
		return results;
	}

	void setResults(List<SapiListing> results) {
		this.results = results;
	}

}

Phew! image what you would have to write for the full API if your JSON processing API (unlike Jackson) cannot handle un-mapped properties and you have to boiler plate everything – SAPI can return a lot of data! Luckily I’m using Jackson so I can use two different tricks to avoid all this work:

With Mr Bean we can simply define a Java interface for the properties we want from the JSON response and let Mr Bean dynamically create the Java implementation of the bean class on the fly. So SapiSearchResult now becomes:

public interface SapiSearchResult {

	int getTotalResults();

	int getCode();

	String getMessage();

	List<SapiListing> getResults();
}

That is a huge difference. Mr Bean will handle creating the setters, constructors and implementations. It handles arrays, maps, lists, Enums, and everything else. The only thing it needs is the getter definition to tell it what to create. You can even add custom code simply by defining an abstract class instead of an interface and adding in the custom methods you want. Wicked.

Summary

I would have to say that between the ease of use of the SAPI search engine, HttpClient and the Jackson/Mr Bean combination, it has taken a surprisingly small amount of time to get a working result. Even when factoring in other stuff such as exception handling and UI.

I would also have to say that the SAPI web site is excellant. As a developer, it’s exactly what I want to see when it comes to documentation and support. The site also contains plenty of examples of using their API in Java, PHP and Ruby. Well done guys.

Posted on 08 March 2012, View comments

Eating Your Own Dogfood

Over some time I’ve come to realise that the difference between a good piece of software and a crap one has nothing to do with methodologies, practices, patterns, principles or any of the other things so many people like to bandy about. It simply comes down to one thing that has not changed since we first start writing code – The best software comes from those who use it themselves.

When you design an application you making a best guess at what is needed, but when you use an application you know what is needed. This doesn’t sound like much, but it makes a massive difference. I often find that when I first visualise a piece of software I can come up with all sorts of UIs, features etc as part of working out what I want to do. Some of those I drop and some I code up in the application. But it’s only when I take the developer hat off and try to use the software that I find out that my groovy button is in fact, not that groovy. Or that the input fields that made sense when thinking about a particular function makes no sense when I actually want to do it. So I I tend to write a piece of software as a V1, or more to the point, a v0.1, and then usually find myself making some quite significant changes in V0.2 or even v0.3. After each stage I to take the software out for a run and try it in the real world, expanding my understanding of the problem space. Something the application doesn’t work as well as I hoped and go back in to re-engineer in light of the new experience I now have. At some point the software goes from being a potential solution to being something that I can actually use.

I think one reason why 90% of the enterprise software I have been around basically sucks is that this does not happen. There are thousands of enterprise developers out there, spending huge amounts of time writing applications to specifications drawn up by Business Analysts and Enterprise Architects, none of whom are ever going to actually use that software. And frankly some don’t even know what it does! So the result is a pipeline of people’s best guesses based on other peoples best guesses of what the actual need is, usually defined by someone else who is also not going to use the software. It’s even worse when dealing with software which just talks to other software. And of course, the developers usually only get one shot at writing the software which means there is no real chance for building an understanding through experience. So it it really that surprising that the results are pretty poor and often over-engineered?

But isn’t Agile, Patterns, Practices and Principles going to fix this. Or at least that’s what the evangelists would have us think. After all, all we have to do is following these things religiously and we will be writing better software. Hang around in the Java enterprise world long enough and you will come across everything from hard bitten practicality to zealous idealised evangelism. This is where I think we have to split the myth from the reality. Talking to some people it all sounds very reasonable – all you have to do is follow <insert acronym here> and you will be creating amazing software is no time … Simply not true.

Writing good software that actually helps rather than hinders has nothing to do with these things, it comes down to a clear vision of what has to be done coming from a clear understanding of the need it has to fulfil. You cannot get this from a one shot project and you will definitely not get it from writing software you will not use. Sure, experienced developers have the experience and skills to know the questions to ask and can better separate the practical needs from the dreams and distractions. So experience counts in getting closer to a worthwhile application – faster, but it’s still no substitute for going through successive iterations of writing code and using it.

But what about all the APPP? (Yes I had to throw in an acronym, you figure it out) Those things are very worthwhile and I’m not dissing them. They sum up years of hard won experience, distilled down into something we can all use by some very smart people. Learning them and understanding where they can be used will help you to write cleaner, simpler, easier to understand code.

But they are not a magic pill, or silver bullet or whatever you want to call it and you cannot automatically write great applications just by religiously following them. What they really are is a great set of tools to help you get the job done better, in the same way that a workshop full of the best quality tools can help a craftsman make a great chair. Usually with less effort and time than if all you gave him was an axe. Either way you will still get a chair that you can safely sit on and will probably treasure. Send in someone who knows nothing about chairs and doesn’t like sitting down and all you will get is a pile of fire wood, regardless of the tools. Send in an Agile evangelist and you will get a joinery demonstration, book and TV show. The chair will be extra. You get what you pay for after all.

Finally remember this, great software was being written long before we had TDD, FDD, LSP, Facades, OCP, BDD, DRY, CI servers, YAGNI, KISS, Interfaces, Unit Testing, SRP, Decorators, ISP, DIP, etc etc. So just because someone does not know these things, or has chosen not to use them in a project, doesn’t mean they don’t know how to write great code.

Posted on 06 March 2012, View comments

Simon V1.3 Is Out

I’ve now released Simon V0.1.3 which is a large update. New and included things are:

Simon is now (I’m rapt to say) at the point where it feels like a usable product. So I’m now planning to use it as part of updating Crema, which I’ve left a bit by the way side whilst doing other things. This will help me firm up what Simon needs next. Although I already have some ideas for new macros and enhancements to the core and UI reporting functions.

Posted on 03 March 2012, View comments

Whats On Tv

Was looking up the expected arrival date of one of my favourite TV shows today. TV I like to watch falls loosely into two categories. The first is the shows that I’ll watch to be entertained. In that sense I like interesting humour, puzzles and good writing. Shows in this category include Big Pang Theory, Bones, NCIS, CSI, Castle, Black Books, Coupling, etc.

Then there is the second category. These are the series that get you hook line and sinker, the ones that you would give up a date with Tom Cruise for, the ones that time after time leaving you hanging wondering how the characters could possibly get out of this and knowing that the writers have no compuncture about killing off lead roles to tell a good story and confront issues head on.

It this category there are only 3 TV series worthy enough to mention and I heartily recommend that if you have not seen them, then you stop watching reality crap and start watching these, from the very first episodes. You will not regret it.

Deadwood – set in the the town of Deadwood during the Californian gold rush in the 1800’s. You will meet all sorts – rich, poor, gamblers, thieves, women of the night, and day, hero’s and anti-heros. And above all, more 4 letter words of all types than I have heard in any TV show ever. This show is not for the feint hearted and will drag you through the mud wanting more all the time.

BattleStar Galactica – (Reimaged) The story of the remains of humanity after near annilation by the robots they created, treaking through space for a home they have only heard of in legend. Earth. Forget the campy BSG of the 1970s. This version is violent, vicious, and addresses every evil human kind has inflicted on itself and others. It screws with your concept of good and evil from the moment you reralise that the robots have not only revolted, but are now exact replicas of human beings right down to the DNA. Everything is up for question by the writers, including the nature of God and religion which play a surprisingly big role in this science fiction show.

Game of Thrones – Set in a medieval alternative world, this shows follows the lives, loves and wars of the feuding lords of a mythical realm. Again strong characters pull you into the series as the line between good and evil blurs. Mad kings, magic and mayhem all ensue. Season 1 aired in 2011 and season 2 is due this April so we are eagerly awaiting to see just what happens next.

Posted on 21 February 2012, View comments

Massive Update To Simon's Documentation

I’ve been doing a massive update to the documentation for Simon. I’ve broken it up into seperate pages and enhanced much of it with examples. This is much better than one massive ReadMe file. Check out the Quick Start guide to get started.

Now I’m working on getting swipes working so that Simon can perform those on a UI and improving the class scanning to be more reliable.

Posted on 16 February 2012, View comments

Hello Im Back

Well it has been a while since my last post. I’ve been really busy on some projects for work and at home and have simply not been updating. That no way to run a blog. Anyways, lots of things have been happening so I thought I’d do a quick update.

Firstly, it’s great to see that what compiling iOS apps, -all_load is no longer needed when linking to frameworks that contain categories.

Next, I’ve been doing alot of work on Simon and learning alot. Some parts of it have simplified and some are better defined. It now sports an on screen report of the stories which have been run.

It’s also been good to see Apple solve the bug where thrown NSExceptions from without an NSInvocation where not being caught. I was able to remove a lot of code from Simon thanks to that being fixed.

I’ve also had a look at some other BDD frameworks, mainly Zucchini which I think is very slick. But like others, it is external to the app and does require knowledge I don’t have to use. So for the moment I’m forging ahead with Simon

Posted on 07 February 2012, View comments

Older posts