Categories
Computing Web Development

Rails HTTP error 406 in response to JSON requests

Had a painful experience last night trying to get Rails to properly handle a JSON request coming from an Objective-C client. Rails was issuing a semi-exotic HTTP error 406. Error 406 means that the user agent – your browser, my iPhone app – cannot handle the response being sent to it. Apparently it all stems from an HTTP request header, Accept, which tells the server what content it can 'digest'.

In any case, to cure this problem I looked at what Accept header Firefox was sending when Rails was successfully handling its requests. By copying Firefox's Accept header and sending it to with my request, I was able to overcome the 406 error and get a happy 200 response.

The Accept string that worked was:

text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

If this does not work, also examine the Rails controller. Make sure that all REST methods return JSON representations.

Share
Categories
Computing iphone

UITableView cell recycling: knowing what’s visible

On my iOS app project, I need to know what is visible in a UITableView and what's not. Each cell displays a unique countdown timer which updates the label in the cell. UITableView recommends you let it recycle the cells used to display the table. What I could not figure out is what cell is being recycled out of the table. Still, the documentation for the recycling method dequeueReusableCellWithIdentifier is confusing (to me). 

The method's signature

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

actually returns you the cell that is being replaced.

Better yet, you can use the cell's properties to find out which cell it was. Not a major revelation but maybe it will help someone out there. You can play with my test project and see for yourself.

Share
Categories
Computing iphone Mac OS X

Private methods in Objective-C

Coming from the Java world, I love, care and embrace all things private, including private methods. Objective-C supports the feature but it appears to me (based on very shallow Googling) that there is not too much familiarity (or use) with it. I looked in a book I recently acquired, Learn Objective-C for Java Developers (Learn Series). While not a book a perfect book, it does cover the how-to of private methods in Objective-C.  

The key to the approach is to leverage Objective-C categories. Categories are a mind-blowingly nifty in the fact that they allow you, among other things, to augment objects you did not create with your own methods. While there are other ways of 'hiding' private methods, most of them result in warnings in Xcode. So here goes…

Say you have an object called CoolWidget. You create the header file (CoolWidget.h)for it as usual, i.e.:

@interface CoolWidget:NSObject
{
    int publicVar;

    @private
    int somePrivateVar;
}

// public methods
-(void) doSomething:(BOOL)cool;

@end

To add private methods to it, you would create a category for the object in a separate header file (CoolWidget+Private.h):

@interface CoolWidget (Private)

// private methods
-(void) doSomethingPrivate:(BOOL)cooler;

@end

All that's left for you to do is to include the additional header file, CoolWidget+Private.h in your implementation file, CoolWidget.m (though categories are often/normally implemented in their own .m file).

Update:

As my friend Glenn Barnett points out in his tweet, there is no such think as private methods in Objective-C. Unlike C++ or Java, there is no real 'enforcement' of access to the methods. Privacy, overall, is purely by convention. 

Share
Share