A short note on CLLocation / CLLocationManager
**** DEPRECATED **** Use http://liip.to/ilocator
Well.. I’ve been testing this Locator quite a while now. Today I had my final attempt, to find out, why I always got either a cached location or an extremely inaccurate location.
Today, I went out with my notebook (yes, there where the sun is..) to debug.
The example of apple says, to check the timestamp of the newLocation. (It should be less than 5..). Yeah well, guess what – it is sometimes 0 in a cached location. And somehow it’s sometimes just a bit over 5 and you’ll have to wait forever to get a new location.
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
NSDate* eventDate = newLocation.timestamp;
NSTimeInterval howRecent = [eventDate timeIntervalSinceNow];
if (howRecent < -0.0 && howRecent > -10.0) {
[manager stopUpdatingLocation];
// USE THE FORCE OF THE LOCATION!
}
}
This one should work. Maybe that location stuff is working in the U.S. but it wasn’t in Switzerland..
P.S.: I had another issue with a pwned iPhone today. NSXMLParser throw me errors back and I didn’t know why.. I still don’t know why, I guess it had to do with the libxml2 update I did. Workaround? Restore, works fine now.
Make NSXMLParser your friend..
As promised, here is a little How-I-did-it / How-To.
First off: I am not an experienced SAX-User.. So this approach might be packing the problem at it’s tail, but this is how DOM-Users feel comfortable with ;)
Let’s assume we want to parse the following XML:
tranist.xml
<root>
<schedules>
<schedule id="0">
<from>SourceA</from>
<to>DestinationA</to>
<links>
<link id="0">
<departure>2008-01-01 01:01</departure>
<arrival>2008-01-01 01:02</arrival>
<info>With food</info>
<parts>
<part id="0">
<departure>2008-01-01 01:01</departure>
<arrival>2008-01-01 01:02</arrival>
<vehicle>Walk</vehicle>
</part>
<part id="1">
<departure>2008-01-01 01:01</departure>
<arrival>2008-01-01 01:02</arrival>
<trackfrom>1</trackfrom>
<trackto>2</trackto>
<vehicle>Train</vehicle>
</part>
</parts>
</link>
<link id="1">
...
</link>
<link id="2">
...
</link>
</links>
</schedule>
<schedule id="1">
...
</schedule>
<schedule id="2">
...
</schedule>
</schedules>
</root>
In human readable format, this means: We have multiple schedules with from/to etc. These schedules consist of multiple links (different connections for the same route) with departure/arrival etc. These links consist then of multiple parts/sections with various elements which are not sure to be there..
With the let’s find the element called ‘part’ – approach, you won’t get anywhere..
The Basics
So what do we want to achieve? We want a list/array of Schedules, which have the given members. On member is a list/array of Links, also consisting of the given members and a list/array of parts with the respective members.
This is also the basic idea behind my approach: for every new node-container, use a new class/object (an array will also work, but it’s kinda crap..)
Now we have a Schedule class, a Link class and a Part class.
This is an example of the Link class interface:
Link.h
#import "Part.h"
@interface Link : NSObject {
NSString *departure;
NSString *arrival;
NSString *info;
NSMutableArray *parts;
}
@property (nonatomic, retain) NSString *departure;
@property (nonatomic, retain) NSString *arrival;
@property (nonatomic, retain) NSString *info;
@property (readonly, retain) NSMutableArray *parts;
- (void)addPart:(Part *)part;
@end
We use an accessor method for the parts, because it just feels better when dealing with arrays. (Instead of later using [foo.myArray addObject:..] we have [foo addMe:..])
Also we make it easier for us, using retain properties..
The Parser setup
A short introduction into SAX:
The parsing goes node by node and is not nesting-sensitive. That means that first we get root, then schedules, then schedule, then from, then to, then links, then link, then departure etc. As soon as the parser returns you the node for example, you don’t know anymore in what schedule you were. As long as you have a clearly defined structure where always every element must be present, you could do this using a counter, but as soon as you have multiple nodes with no defined count, you have a problem.
What we do is known as recursive parsing. What does this mean? We implement some kind of memory.
In our parser, we have 4 members and 1 method (to make actual use of the parser..):
@property (nonatomic, retain) NSMutableString *currentProperty;
@property (nonatomic, retain) Schedule *currentSchedule;
@property (nonatomic, retain) Link *currentLink;
@property (nonatomic, retain) Part *currentPart;
@property (nonatomic, readonly) NSMutableArray *schedules;
- (void)parseScheduleData:(NSData *)data parseError:(NSError **)error;
(Yes, this needs to be a NSMutableString..)
Your parseScheduleData method should look similar to the following:
parseJourneyData
- (void)parseJourneyData:(NSData *)data parseError:(NSError **)err {
NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
self.schedules = [[NSMutableArray alloc] init]; // Create our scheduler list
[parser setDelegate:self]; // The parser calls methods in this class
[parser setShouldProcessNamespaces:NO]; // We don't care about namespaces
[parser setShouldReportNamespacePrefixes:NO]; //
[parser setShouldResolveExternalEntities:NO]; // We just want data, no other stuff
[parser parse]; // Parse that data..
if (err && [parser parserError]) {
*err = [parser parserError];
}
[parser release];
}
Now we need those delegate methods.
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
This function is called by the parser, when it reads something between nodes. (Text that is..) Like with blah it would read “blah”. It is possible, that this method is called multiple times in one node. As you will see later, we define the property “currentProperty” only if we find a node, we care about. That’s why we test it against this property to make sure, that we need this property. This will then look something like this:
Parser
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
if (self.currentProperty) {
[currentProperty appendString:string];
}
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
This is called, when the parser finds an opening element. In this case, we have a few cases, we need to distinguish. These are:
It’s standard property in the schedule (like <form> etc.) or it’s a deeper nested node (like <links>), the same for all the other nodes.
How to? We define, that we only set a member, if we are in that node. That means, only when we have entered a <part>, then currentPart is set, otherwise it’s nil. The same with the others.
We do then need to check them in reverse order of their nesting level.. Why? Because if we would check for currentLink before currentPart, currentLink would also evaluate to YES/True and hence we will have a problem if their are elements with the same name. If we aren’t in any node, then there is probably a new main node comming -> in the else..
When we hit a nested node, we need to allocate the respective member of our class, so we can use it when the parser gets deeper into it.
This will look like this:
Parser
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
if (qName) {
elementName = qName;
}
if (self.currentPart) { // Are we in a
// Check for standard nodes
if ([elementName isEqualToString:@"departure"] || [elementName isEqualToString:@"arrival"] || [elementName isEqualToString:@"vehicle"] || [elementName isEqualToString:@"trackfrom"] || [elementName isEqualToString:@"trackto"] ) {
self.currentProperty = [NSMutableString string];
}
} else if (self.currentLink) { // Are we in a
// Check for standard nodes
if ([elementName isEqualToString:@"departure"] || [elementName isEqualToString:@"arrival"] || [elementName isEqualToString:@"info"]) {
self.currentProperty = [NSMutableString string];
// Check for deeper nested node
} else if ([elementName isEqualToString:@"part"]) {
self.currentPart = [[Part alloc] init]; // Create the element
}
} else if (self.currentSchedule) { // Are we in a ?
// Check for standard nodes
if ([elementName isEqualToString:@"from"] || [elementName isEqualToString:@"to"]) {
self.currentProperty = [NSMutableString string];
// Check for deeper nested node
} else if ([elementName isEqualToString:@"link"]) {
self.currentLink = [[Link alloc] init]; // Create the element
}
} else { // We are outside of everything, so we need a
// Check for deeper nested node
if ([elementName isEqualToString:@"schedule"]) {
self.currentSchedule = [[Schedule alloc] init];
}
}
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
Basically, the same things apply as for didStartElement above. This time, we need to clean things up and assign them if they are set :) This is a bit a pitty, since it’s a lot of code.. *(for not so much)
It’s the same checker-structure..
If we are in a deeper nested node (like <Link>) and we hit an ending element of that nested node (like </Link>), Then we need to add this element to the parent (like <Schedule>) and set it to nil
See yourself:
Parser
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
if (qName) {
elementName = qName;
}
if (self.currentPart) { // Are we in a
// Check for standard nodes
if ([elementName isEqualToString:@"departure"]) {
self.currentPart.departure = self.currentProperty;
} else if ([elementName isEqualToString:@"arrival"]) {
self.currentPart.arrival = self.currentProperty;
} else if ([elementName isEqualToString:@"vehicle"]) {
self.currentPart.vehicle = self.currentProperty;
} else if ([elementName isEqualToString:@"trackfrom"]) {
self.currentPart.trackfrom = self.currentProperty;
} else if ([elementName isEqualToString:@"trackto"]) {
self.currentPart.trackto = self.currentProperty;
// Are we at the end?
} else if ([elementName isEqualToString:@"part"]) {
[currentLink addPart:self.currentPart]; // Add to parent
self.currentPart = nil; // Set nil
}
} else if (self.currentLink) { // Are we in a
// Check for standard nodes
if ([elementName isEqualToString:@"departure"]) {
self.currentLink.departure = self.currentProperty;
} else if ([elementName isEqualToString:@"arrival"]) {
self.currentLink.arrival = self.currentProperty;
} else if ([elementName isEqualToString:@"info"]) {
self.currentLink.info = self.currentProperty;
// Are we at the end?
} else if ([elementName isEqualToString:@"link"]) {
[currentSchedule addPart:self.currentLink]; // Add to parent
self.currentLink = nil; // Set nil
}
} else if (self.currentSchedule) { // Are we in a ?
// Check for standard nodes
if ([elementName isEqualToString:@"from"]) {
self.currentSchedule.from = self.currentProperty;
} else if ([elementName isEqualToString:@"to"]) {
self.currentSchedule.to = self.currentProperty;
// Are we at the end?
} else if ([elementName isEqualToString:@"schedule"]) { // Corrected thanks to Muhammad Ishaq
[schedules addObject:self.currentSchedule]; // Add to the result node
self.currentSchedule = nil; // Set nil
}
}
// We reset the currentProperty, for the next textnodes..
self.currentProperty = nil;
}
Finally..
Well, that’s it. You can expand / shrink this principle as you like. You can also add a maxElements counter, like in the SeismicXML example of the iPhone SDK to get only a certain number of elements. You can abort the parser with [parser abortParsing]; It is important, that you don’t abort while in a deeper nested node, because this could lead to inconsistencies. You will need to skip them..
Please note, that I wrote this, while watching TV, so you may need to fix some syntax errors ;) But I hope you get the idea..
And long nights follow field-days..
What a weekend. After I started with the real field-testing on Friday evening, it didn’t take me long to realize that I will need to fix a lot of issues :)
Since the girls are out of town, I had time for what I needed to do – refactoring.
I had to modify the online service, since Google and SBB don’t always play nice together. Example? Hmm.. Google thinks, that there is a station named Rathaus, but SBB thinks, there are many many stations called Rathaus.. So I needed reverse geocoding for that. I did my own implementation with Google-Maps – but I cannot open it to anyone since they kinda don’t like that ;) I may publish the source though, I guess.
The next thing was, was to harden that thing – make it foolproof. Not an easy task, you say? Well, I gave it my grandfather for testing, he clicked things I would never click and that’s how I found a few more issues – I think this should be best practice ;)
Another thing I noted was that I fetch a ton of information I didn’t use.. like the vehicle and stuff. So the sections are now implemented as well.
So much about `software is done’
The reason why I made this entry at all is:
– GottaGo is now ready for beta testing..
That means I may invite 100 users to try out gottago without waiting for the AppStore release it.
What do I need/you need to do?
You’ll need an iPhone. (first and second gen will work). iPod touch may also work, would be nice to have a tester.
I need your e-mail address – like in non-spam-e-mail address.
Then I need your UDID/Device Id of your iPhone.. this is a tricky one :) Either you are an iPhone developer and you know how to find it or you can try the following:
- Connect your iWonderTouch with iTunes
- In the Summary tab, click on the label “Serial Number” (yes, move your mouse over the “Serial Number” text and click!).
- The “Serial Number” label should become “Identifier” and the ID should get longer ;)
- You may screenshot this ID or type it into the e-mail by hand.. UPDATE: As Marc Liyanage noted in the comments: Just hit cmd-c after you see the identifier and paste it wherever you want it.. (thanks!) :)
Should be it. Just send it to: m.m.ammann@gmail.com or leave a comment below. I will send you further instructions like our bugtracking system and stuff.
Sunshine follows rain – GottaGo in the wild
Well.. it took me a while to get here.. And here we are now.
GottaGo is done. (Well, as far as software can be done..) I’m very happy to tell, that GottaGo is ATM. out in the wild for testing and has already been submitted to the AppStore.
Here are some high quality pictures of GottaGo in action:






Well, what has happened so far?
The main problem was the absence of NSXMLDocument/Element. When I started the project, I chose NSXMLDocument over NSXMLParser (SAX) because it’s way easier to handle difficult documents.
Because the app gets its data from Google and SBB over their respective APIs, a flexible XML parser was needed. Especially for SBB. If you’ve ever dealt with the SBB page, you know what I’m talking about.
To my bad, NSXMLDocument was not going to be included in the final SDK – what now?
In the last blog post I mentioned my options. Alea iacta est ;)
First I tried to make it work without a proxy – using IconoraXML but this project was kinda unmaintained and even failed to build. My other approach, to write a wrapper for libxml2 was kinda overdosed.
So I had to rewrite the complete Google and SBB parsing stuff because I screwed up in the first place – this time using NSXMLParser.
What is NSXMLParser – you might ask. It’s actually a SAX parser for Objective-C, which means you look at 1 element at a time. There is no DOM tree or whatsoever. That is a problem if you have hierarchical data – obviously. Let’s say you have 3 train-connections, each with sections.. now how’d you know what section is in which connection if you don’t know about the parent node? I guess you get the point.
If you are really interested, grab the SeismicXML example for the SDK to see how it works in detail. Basically, you just work your way through that Document recursively and always add the stuff you `find’ to your current parent-object. Once you get it, it’s easy to follow..
Sounds like an easy deal, eh? Well, that might be true for the Google data. It was, and that’s what I did.
But SBB? No go. The loader wouldn’t even let me load the html. So what now? – Yes, a proxy was needed – and that’s what was next.
On http://couch.codesofa.com/api/sbb/from/Source1[;Source2 ..]/to/Destination1[;Destination2 ..].xml you see the result (Example). I think this is the first real API available to everyone for SBB.ch .
This was made using the Okapi-Framework with a lot of XPath magic :)
In the next days, I will release the source-code for it, together with an introduction into Okapi since it’s the most basic project I can think of – I just need to polish the code a bit..
So now it was quite easy to parse the SBB data..
Lessons learned? Well, there’s nothing more adorable than a good webservice ;)
What’s next? Favorites and Address book stuff.. But first are some other apps I wanted to get my hands on. (Top secret!)
GottaGo – Why it’s not out there yet..
Well, first of all, thanks for the great response on the first sneak preview of `GottaGo’ – even though some people thought I’ve been on weed during the video presentation – I wasn’t :) It’s quite difficult to talk in presentation-loudness at 2am where I live..
So, what kept me from submitting to the AppStore?
Well, first of all I had to get my hands on a JesusPhone.. One I could work with. – Done -
You might say – there is a Simulator, the phone should be a small stage for the final testing. Yes, that’s what I thought.
Apparently, Apple allowed system libraries to be compiled into your software, while using the Simulator. Well – and since NSXMLDocument is not included in the final build of the SDK – I’m quite frankly – doomed now when I try to compile on the iPhone.
My options now are:
- libxml2 wrapper:
- fix the iconara to work with iphone (linker errors)
- write my own (jeeez)
- use plain libxml2:
- spaghetti code
- wheee
- use my own webservice to aggregate and send a small xml and parse via NSXMLParser (SAX):
- sbb might block me for too many requests
- bottleneck
- yet another system that may fail
I think I’m going with the own webservice. It doesn’t feel right though. I think in a device that powerful, there should be a simple implementation of the DOM. I see the iPhone as a mobile device which should profit as much as possible from different webservices and cache only necessary things. Obviously Apple is more concerned about OpenGL(-Games) than about web-service access.
If there is a libxml wizard out there, feel free to contact me :)
I’ll try to focus on libxml for some additional hours and if there is no hope, I’ll set up my own webservice. I hope I’ll be able to submit GottaGo to the AppStore this weekend.
And to clear some things up:
- GottaGo will be free of charge
- GottaGo will only work in Switzerland for now
UPDATE Well.. After some hours of hacking, I was able to put GottaGo on my iPhone in a light-version. That means: location tracking and station finding, but no SBB querying for now. For SBB, I will probably have to proxy the requests since their response html is not even valid html.. But now there is some pressure on my shoulders. I was able to submit to AppStore. The requested release day is: July 19, so stay tuned :)

Welcome to my vacation home – the Codesofa
Well, I’ve been planing this for a while now – but my surroundings kept me quite busy.
Ever since I’ve seen my little brother getting into computers and using linux, I thought about a way to make coding more accessible and more intuitive.
These are the roots of codesofa – bringing coding to the young `gods’ ;) – And of course the older not-so-goddish..
How is this going to work? Learning by doing of course.. With the help of my future projects, I try to give some introductions into various aspects of programming. That means not only show you a design pattern or a function, rather to show how multiple patterns take use of this one function ;) – You will see.. I think there are loads of hurdles when you start in a new language, a new framework or even start programming at all – I don’t try to put everything into a drawer, rather than to give advices and some small guidance..
There are loads of different coding styles.. I focus on readable, performance oriented, standardized (design patterns..) and language specific code.. Or at least I hope so. And I believe that good code is made from loads of contributions – so please feel free to correct (help) where needed.
The other side are my own projects and information about these projects as well as announcements.
As you can see, this blog will focus on coding and nothing else.. maybe some random rants about some really fucked up projects I ran across.
Since I’m finishing my BSc at ETHZ at the moment and working at a great company called Liip, I hope I will be able to provide insight from both sides – the very theoretical and the very pragmatic..
However, the goal is not to separate them rather than to merge them..
In this first period, I will concentrate on the iPhone SDK and Okapi. As you may have read, I’m about to release my first iPhone app called gottaGo – so this will be the topic for the next few weeks.
Of course I don’t feel like I have to do this alone – If you are interested in Objective-C, C and/or PHP (teaching) then drop me a line..
Stay tuned for more..