Me and some friends use Nike+ gear to compete against each others with the challenge feature. Competing with your friends is a great motivator to get the out to the track. In an effort not to fall behind too much I also have made a private feature that sends an email every night of the challenge positions. This is done with a small script running on my server.
The script made a picture of a small webpage containing widgets from Nike+ using Paparazzi!. The picture is then attached to an email and sent with msmtp. The Nike+ widgets are created in flash and can only show four positions in a challenge at a time.
Personally I have slipped behind a little in these challenges and haven’t reach to the first four positions in a while. Idea, why not make use of some XML parsing classes I created and replace the picture of the widgets with a simple html table of all the positions in the challenges.
Recently I created an iPhone app for me and Tomas to use to enter and view our time reports for our consulting tasks. We have done this since 2004 with a simple webapp and now I updated it to handle input and output through XML. For the iPhone app I created some Cocoa parser classes to parse the XML. They are pretty lightweight and should be easy to use so why not use them for this Nike+ challenge fetcher.
The parser classes I created parse basically two things, straight lists and per-entry-name-values.
A straight list can be like a list of months as below.
<month>January</month> <month>February</month> <month>March</month> <month>April</month>
A per-entry-name-values can be list of employee entries as below.
<entry> <name>Edward Patel</name> <company>Memention AB</company> </entry> <entry> <name>Tomas Stenarson</name> <company>Memention AB</company> </entry>
The Nike+ challenge fetchers was created as a command line tool in Xcode. I use a simple
[NSURLConnection sendSynchronousRequest:...] to pull the XML from
nike.com. There is no event loop and no user to respond to so I am fine with it.
nike.com one need to get two XML files per challenge. One for the challenge name and its description, one for the list of members and their positions.
To get a challenge name and its description I use my ListParser as below.
ListParser *parser = [ListParser parser]; [parser addFieldName:@"name"]; [parser addFieldName:@"greeting"]; // Nike's tag for description [parser parseData:data]; NSLog(@"%@", [parser list]); // Lets see what we got
addFieldName: method adds the tags the parser will actively be looking for. The resulting list returned from the parser is an
To get the list of challenge members and their positions I use the NameValueParser as below.
NameValueParser *parser = [NameValueParser parser]; [parser addFieldName:@"screenName"]; // Name [parser addFieldName:@"rank"]; // Position [parser addFieldName:@"progress"]; // Distance [parser parseData:data]; NSLog(@"%@", [parser list]); // Lets see what we got
The list the parser returns is an
NSDictionary’s for each challenge member. (Note that the
member tag is set in the file
Not too much code and I got to reuse some unrelated stuff, the way it should be. So I put in a little extra time to output a nice html table with some bars showing the distance to the leader. Do you want to checkout the two parser classes and the command tool? Grab my NikePlusTool Xcode project here. Do you need an id for a challenge to try with? Try
1478335687 which is our challenge for october, it’s also last of our James-Bond-movie-named-challenges.
Maybe I should have left the keyboard alone and just put on the gear and gone out to the track…
Update: I received an addition from Ben Sgro so I have moved the source code to github.By Edward Patel, 31 Oct 2009