My hovercraft is full of eels

Enumerating results from an asynchronous network call in Objective-C

by Simon Harris

I have a facade over an asynchronous network call—that also performs pagination, ie multiple network calls in order to handle very large result sets—along the lines of this but I now want to use it in a context where knowing when it’s finished iterating is important (e.g in an NSOperation):

[myClient enumerateFoosAtURL:URL usingBlock:^(id foo, BOOL *stop) {
  ...
} failure:^(NSError *error) {
  ...
}];

The simplest thing might be to add an extra block but that is so sucky I nearly vomited in my mouth just typing out the example below:

[myClient enumerateFoosAtURL:URL usingBlock:^(id foo, BOOL *stop) {
  ...
} success:^{
  // we're done
} failure:^(NSError *error) {
  ...
}];

A less sucky option might be to indicate if there are more to come:

[myClient enumerateFoosAtURL:URL usingBlock:^(id foo, BOOL more, BOOL *stop) {
  ...
  if (!more) {
    // we're done
  }
} failure:^(NSError *error) {
  ...
}];

Yet another option that I think I like the most might be to simply transform the semantics of the original into this:

[myClient enumerateFoosAtURL:URL usingBlock:^(id foo, BOOL *stop) {
  ...
} finished:^(NSError *error) {
  if (error) {
    // an error occurred
  } else {
    // we're done
    ...
  }
}];

Update

Tony Wallace suggested that he prefered the

“less sucky option” because it makes it more obvious that the method returns paginated results.

And I have to say I agree with him on that. The only fly in the oitment however, turns out to be some filtering performed within the API methods which meant that determining if there were more results would have required some fancy look-ahead code.

In the end I went with my last option. It seems to have worked out rather painlessly :)

Previously