iPhone SDK / Objective C Syntax Question - iphone

To all,
I was looking at the sample project from http://iphoneonrails.com/ and I saw they took the NSObject class and added methods to it for the SOAP calls.
Their sample project can be downloaded from here http://iphoneonrails.com/downloads/objective_resource-1.01.zip.
My question is related to my lack of knowledge on the following syntax as I haven't seen it yet in a iPhone project.
There is a header file called NSObject+ObjectiveResource.h where they declare and change NSObject to have extra methods for this project. Is the "+ObjectiveResource.h" in the name there a special syntax or is that just the naming convention of the developers.
Finally inside the class NSObject we have the following
#import <Foundation/Foundation.h>
#interface NSObject (ObjectiveResource)
// Response Formats
typedef enum {
XmlResponse = 0,
JSONResponse,
} ORSResponseFormat;
// Resource configuration
+ (NSString *)getRemoteSite;
+ (void)setRemoteSite:(NSString*)siteURL;
+ (NSString *)getRemoteUser;
+ (void)setRemoteUser:(NSString *)user;
+ (NSString *)getRemotePassword;
+ (void)setRemotePassword:(NSString *)password;
+ (SEL)getRemoteParseDataMethod;
+ (void)setRemoteParseDataMethod:(SEL)parseMethod;
+ (SEL) getRemoteSerializeMethod;
+ (void) setRemoteSerializeMethod:(SEL)serializeMethod;
+ (NSString *)getRemoteProtocolExtension;
+ (void)setRemoteProtocolExtension:(NSString *)protocolExtension;
+ (void)setRemoteResponseType:(ORSResponseFormat) format;
+ (ORSResponseFormat)getRemoteResponseType;
// Finders
+ (NSArray *)findAllRemote;
+ (NSArray *)findAllRemoteWithResponse:(NSError **)aError;
+ (id)findRemote:(NSString *)elementId;
+ (id)findRemote:(NSString *)elementId withResponse:(NSError **)aError;
// URL construction accessors
+ (NSString *)getRemoteElementName;
+ (NSString *)getRemoteCollectionName;
+ (NSString *)getRemoteElementPath:(NSString *)elementId;
+ (NSString *)getRemoteCollectionPath;
+ (NSString *)getRemoteCollectionPathWithParameters:(NSDictionary *)parameters;
+ (NSString *)populateRemotePath:(NSString *)path withParameters:(NSDictionary *)parameters;
// Instance-specific methods
- (id)getRemoteId;
- (void)setRemoteId:(id)orsId;
- (NSString *)getRemoteClassIdName;
- (BOOL)createRemote;
- (BOOL)createRemoteWithResponse:(NSError **)aError;
- (BOOL)createRemoteWithParameters:(NSDictionary *)parameters;
- (BOOL)createRemoteWithParameters:(NSDictionary *)parameters andResponse:(NSError **)aError;
- (BOOL)destroyRemote;
- (BOOL)destroyRemoteWithResponse:(NSError **)aError;
- (BOOL)updateRemote;
- (BOOL)updateRemoteWithResponse:(NSError **)aError;
- (BOOL)saveRemote;
- (BOOL)saveRemoteWithResponse:(NSError **)aError;
- (BOOL)createRemoteAtPath:(NSString *)path withResponse:(NSError **)aError;
- (BOOL)updateRemoteAtPath:(NSString *)path withResponse:(NSError **)aError;
- (BOOL)destroyRemoteAtPath:(NSString *)path withResponse:(NSError **)aError;
// Instance helpers for getting at commonly used class-level values
- (NSString *)getRemoteCollectionPath;
- (NSString *)convertToRemoteExpectedType;
//Equality test for remote enabled objects based on class name and remote id
- (BOOL)isEqualToRemote:(id)anObject;
- (NSUInteger)hashForRemote;
#end
What is the "ObjectiveResource" in the () mean for NSObject? What is that telling Xcode and the compiler about what is happening..?
After that things look normal to me as they have various static and instance methods. I know that by doing this all user classes that inherit from NSObject now have all the extra methods for this project.
My question is what is the parenthesis are doing after the NSObject. Is that referencing a header file, or is that letting the compiler know that this class is being over ridden.
Thanks again and my apologies ahead of time if this is a dumb question but just trying to learn what I lack.

This is a Category. It allows you to extend an existing class. Instead of
MyClass : MySuperclass
it's declared via:
MyClass (MyCategoryName)
The name of the file is simply a convention MyClass+MyCategory.h. The filename makes no real difference, but this makes it easy to tell the file contains a category of methods that extends a specific class.
Note that you can implement new methods in a category, but you cannot add instance variables. And to use a category elsewhere in your codebase, all you must do is import the category header and all methods it contains will be made available on the objects the category extends.

This is called a "category" in Objective-C. See the "Categories and Extensions" chapter of The Objective-C Programming Language for more information.
The +ObjectiveResource.h thing is just a common convention for naming files that contain categories. It doesn't have any significance to the compiler.

The first two answers are correct - it's a Category, which is a way to extend the functionality of an existing class.
It's a really powerful feature in Objective-C, but it can be abused too. It can be dangerous to put Categories on low-level classes like NSObject, unless you know exactly what the implications are. For example, if you add methods to NSObject, you are essentially adding the methods to any class that inherits from NSObject, which is pretty much everything. Note that you can only utilize the category methods if you include the header, but it can still produce unexpected results in some cases.

Related

How to create global protocol method in iPhone?

I create one protocol method and I want to implement the protocol method in multiple classes
#protocol XMLProtocol <NSObject>
- (BOOL) hasAllRequiredAttributes :(NSDictionary*)attributeMap;
#end
I have use this following class methods
#import "XMLProtocol.h"
#interface MachineA : NSObject<XMLProtocol>
and its implementation method I will implement the protocol method
- (BOOL) hasAllRequiredAttributes:(NSDictionary *)attributeMap {
return false;
}
and also i use this protocol method in another class
#import "XMLProtocol.h"
#interface MachineB : NSObject<XMLProtocol>
and its implementation method I will implement the protocol method
- (BOOL) hasAllRequiredAttributes:(NSDictionary *)attributeMap {
return false;
}
my thought is where should I call the protocol method. I totally confused. How can i do this.
One way you can define a global implementation for your protocol method (if I understand correctly what you are asking) is defining a category on NSObject:
#implementation NSObject (XMLProtocol)
- (BOOL) hasAllRequiredAttributes:(NSDictionary *)attributeMap {
return false;
}
By doing like this every object will have that method. Don't know if this is sensible, but it's a way.
Another way would be defining a Machine base class from which both MachineA and MachineB derive; the protocol method would be defined in the base class:
#interface Machine : NSObject <XMLProtocol>
...
#implementation Machine
- (BOOL) hasAllRequiredAttributes:(NSDictionary *)attributeMap {
return false;
}
....
#end
#interface MachineA : Machine
...
and any derived class could redefine it, if required.
This is not as "global" as the NSObject category, but it might be a better solution if you can define a base class for all the classes that need implement that protocol.
You must write the implementation of the method in both classes, even if the implementations are identical.
In you particular situation notification would be great help full to you. Notification works same like protocol except it broadcast the message. so you could receive that call on multiple classes.
if you want to done with protocol than also it is very easy. just make sure you current view controller is referenced with delegate (i.e. obj.delegate = self). you can implement that on -viewWillAppear. so your current view controller only get called of that method. Delegate will only call one method at one place in a time.
IMHO a global protocol is not very good design for something as specific as XML parsing.
A #protocol doesn't have any implementation part by itself. It is just an API definition, think of it like a contract. Any class that conforms to a protocol must implement its mandatory methods and properties (there is a #optional clause).
For instance, you may have two implementations of an XML parser, one that works in iOS 4 and another one that works in iOS 5+. Both declared as conforming to XMLProtocol protocol. And both implementing - (BOOL) hasAllRequiredAttributes :(NSDictionary*)attributeMap;, let's imagine that they need to implement it differently.
Thanks to being compliant to XMLProtocol you don't care about the implementation details. You know that you'll pass an attribute map and you'll obtain a boolean indicating if it has all required attributes.
You call the method where ever you use those classes:
id <XMLProcotol> parser;
if (iOS4) {
parser = [[OldXMLParser alloc] initWithString:<#...#>];
} else {
parser = [[NewXMLParser alloc] initWithString:<#...#>];
}
/* you call the method without caring which parser class
* has been actually created thanks to the protocol
*/
if ([parser hasAllRequiredAttributes:theMap]) {
...
}
If the implementation of the methods are identical, you can make both a subclass of a common parent class that implements the common methods, present or not in the protocol.

Creating a class whose methods can be called without an instance of an object (static class)

I'm new to objective c and i want to create a class containing certain methods that can be called in any of my other classes, mostly helper methods. im still learning the syntax and i dont know how to declare it properly
kind of like in java Integer.parseInt( );
Thanks!
Static methods in objective-c are called 'class methods' and can be declared with '+' symbol (while instance methods with '-'), e.g.:
- (void) instanceMethod;
+ (void) classMethod;
To call class method use class name:
[MyClass classMethod];
Those are called (unsurprisingly) class methods. You can declare one by using + instead of - in the method signature, e.g.
#interface MyInteger : NSObject
+ (MyInteger *)parseInt:(NSString *)str;
#end
This method is then called on the class itself, e.g. [MyInteger parseInt:#"12"].
Of course, since this is C, if your class method doesn't actually have much relation to any particular class, you could just define it as a C function instead.
NSInteger myParseInt(NSString *str);
When you see a - sign in front of a method, it's an instance method. That means you can only call that method on an instance of a class.
If you want to create a class method, all you need to do is change that - to a +.
they are called class methods. they are declared and used like this:
#interface MONClass : NSObject
+ (NSString *)convertString:(NSString *)string;
#end
in use:
NSString * converted = [MONClass convertString:string];

iPhone ivar naming convention [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How does an underscore in front of a variable in a cocoa objective-c class work?
I've noticed that in a lot of the reference materials out there, I see that a lot of the time, variables are named _variable in the .h file, then are #synthesize'd in the .m file as
#synthesize variable = _variable;
Why is this done? What am I missing?
Thanks!
There is not consensus on this. Some people like to use it for clarity to separate out class variables, and as another responder noted to avoid conflict with incoming parameter names. Even in Apple sample code the use is mixed.
However, I greatly prefer to not use the _ prefix and have two strong reasons:
1) Some people think the _ is a good indicator of "private". My take is that NO class local variable should be accessed without a setter/getter (property) and thus they are ALL private - given that why not name them in a way easier to read and use autocomplete on? Any overlap in names from parameters is quickly revealed by the compiler, and avoided through more thoughtful naming of parameters (or internal variables).
2) (even better reason) - if you use "refactor" in XCode on an internal class var that is named the same as the property used to access it, the property and synthesize statement will also be renamed. If you use refactor on a class variable prefixed with an _, the property name will not be changed - just the synthesize mapping to the internal name. I pretty much never want the name to vary from the property to the real variable it exposes access to. That alone makes me never want to use _ as a variable prefix, since being able to shift names is just about the most useful thing you can do to improve code clarity.
Using that syntax is an option to make it more clear that the ivar and property are different things.
To code external to the class, there is no difference since it uses the property.
For code in the implementation of the class itself, it can make it more clear when the ivar is used versus the property.
For example, say we have an ivar/property for an NSNumber object:
#interface MyClass : NSObject {
NSNumber *num;
}
#property (nonatomic, retain) NSNumber *num;
- (void)doSomething;
#end
#implementation MyClass
#synthesize num;
- (void)doSomething {
// set the property, num is properly retained
self.num = [NSNumber numberWithInteger:1];
// accidentally set the ivar, num is NOT retained
num = [NSNumber numberWithInteger:2];
}
#end
and now using a different name for the ivar and property:
#interface MyClass : NSObject {
NSNumber *i_num;
}
#property (nonatomic, retain) NSNumber *num;
- (void)doSomething;
#end
#implementation MyClass
#synthesize num = i_num;
- (void)doSomething {
// set the property, num is properly retained
self.num = [NSNumber numberWithInteger:1];
// compiler error, there is no ivar named "num"
num = [NSNumber numberWithInteger:2];
// set the ivar, so it needs to be a retained object
i_num = [[NSNumber alloc] initWithInteger:3];
}
#end
Previous answers are missing the history behind this. Before Objective-C 2.0, there were no properties. So you’d have an object with instance variables like this:
#interface MyObject: NSObject {
NSArray *myArray;
}
#end
But how would you access them from other objects? the solution was to make setters and getters. But to avoid confusion, they would do it like this:
#interface MyObject: NSObject {
NSArray *_myArray;
}
- (NSArray *)myArray;
- (void)setMyArray:(NSArray *)myArray;
#end
The _ serves to clear up confusion between the instance variable _myArray and the method -myArray.
Sometimes people use mVarName (C++) and in Obj-c the style seems to be _varName.
One problem you can have, is imagine that your argument to a function is ...set:(int) x - BUT - you have an iVar called x...well your going to get the compiler crying about stuff like that - not to mention its confusing.
The m,_, whatever helps to show what are member properties of the class.
-(void) set:(int)x
{
x = x; // x is an ivar! heh
}
VS
-(void) set:(int)x
{
_x = x; // ahh I see!
}
This is purely convention. I suppose its common because when you make a method getter call like this:
[myObject variable]
you are actually calling a method, not accessing a variable directly. the _ in front makes it clear that you are talking about a variable. Personally, I find this syntax annoying and distracting. I find it unnecessary, but you are right, it does appear here and there.
I prefer not to use the '_' prefix because Apple does use it consistently. By avoiding the prefix I then have greater confidence that my ivars do not collide with Apple's when I extend a cocoa touch class. Since we do not have access to the base class' source this is really the only way I know of to avoid accidental reuse of existing private ivars.
Much like
Method names beginning with “_”, a single underscore character, are reserved for use by Apple.
My preference, following Google, is simply to append an underscore and explicitly synthesize (even if I'm reimplementing):
#synthesize varName=varName_;
If I see that trailing underscore outside of init..., dealloc or an accessor, I know something's fishy.

Public scope in Objective-C?

I’m sure this is a simple one, but it’s been elusive so far, and I’m stumped ...
How do I declare an Ivar so that it’s accessible from ALL Classes in a project?
[Don’t know if it matters, but the ivar in question is (an instance of) my Model class, whose data needs to be accessible to various view controllers.]
Best as I can tell from "The Scope of Instance Variables” in The Objective-C 2.0 Programming Language
... this would be by using the “#public” directive.
So I’ve tried this in the #interface block where the ivar is declared:
#interface ...
...
#public
ModelClass *theModel;
#end
... But when I try to refer to “theModel” in a different class, the compiler doesn’t auto-complete, and when I type it in anyway, the compiler shows:
“Error: ‘theModel’ undeclared (first use in this function)”.
I assume this is a question of Scope, and that I haven’t made the ivar available appropriately, but how? Somehow I need to access this, or make its pointer available somehow.
Any ideas would be VERY much appreciated. Many thanks!
Perhaps you forgot to put the instance variable inside the braces of the class where all instance variable declarations go?
#interface Foo : NSObject {
// other instance variable declarations
#public
ModelClass *theModel;
}
// method and property declarations
#end
Also, can you show us the code of how you are trying to access the instance variable from elsewhere? The proper syntax should be:
myFooInstance->theModel
where myFooInstance is a value of type "Foo *"
I make properties available to all views managed by a Tab Bar via a singleton representing my data model. This is efficient and allows all Views access to the data (as well as any other application elements. Creating the singleton is straightforward (there are a ton of examples on S.O.). The you just request the instance and get the property values you need.
Here is a framework fro creating the Singleton. The key points are the static instance and the fact that you do the initialization as [[self alloc] init];. This will ensure the object gets cleaned up correctly. All the methods at the bottom of the class are standard from the SDK Docs to make sure release calls are ignored (because the object is shared globally).
Singleton Boilerplate (ApplicationSettings.m):
static ApplicationSettings *sharedApplicationSettings = nil;
+ (ApplicationSettings*) getSharedApplicationSettings
{
#synchronized(self) {
if (sharedApplicationSettings == nil) {
[[self alloc] init]; // assignment not done here
}
}
return sharedApplicationSettings;
}
+ (id)allocWithZone:(NSZone *)zone
{
#synchronized(self) {
if (sharedApplicationSettings == nil) {
sharedApplicationSettings = [super allocWithZone:zone];
return sharedApplicationSettings; // assignment and return on first allocation
}
}
return nil; //on subsequent allocation attempts return nil
}
- (id)copyWithZone:(NSZone *)zone
{
return self;
}
- (id)retain
{
return self;
}
- (unsigned)retainCount
{
return UINT_MAX; //denotes an object that cannot be released
}
- (void)release
{
//do nothing
}
- (id)autorelease
{
return self;
}
You cannot access iVars from any other class.
You have to declare a getter/setter method to change or view a variable from another class - what you are really looking for are properties, that make it easier to define and access these getter/setter methods.
In your example above, you'd have the property defined just after the block that defines the local variable in the header file:
#property (nonatomic, retain) ModelClass *theModel;
In the implementation file you'd have the getter/setter created with the #synthesize statement just after the #implementation line:
#synthesize theModel;
Then if you have an instance of your class created, you access the class instance variable like so:
myInstance.theModel = [[[ModelClass alloc] init] autorelease];
The reason #public & #private are in there are to define visibility for subclasses (which, being extensions of that class type also get all the class local variables defined by a superclass), not for any random class.
The standard Objective-C way of doing it is to have a class method that returns the ivar
In your .h file:
+ (id)defaultModel;
and in your .m file:
static ModelClass * defaultModelInstance;
#implementation ModelClass
+ (id)defaultModel {
if (!defaultModelInstance) {
defaultModelInstance = [[ModelClass alloc] init];
}
return defaultModelInstance;
}
#end
although this will need tweaking if you need a specific ivar instead of just "a ivar that's always the same"
this type of design is used by many Cocoa classes i.e. [NSWorkspace sharedWorkspace]
Think a C global variable.
Adding:
extern ModelClass* theModel;
after the #end in the header will make the variable visible anywhere you include the header.
In the ModelClass.cpp file add:
ModelClass* theModel;
before the class implementation.
The variable will still have a value of nil until you allocate and initialize it though and you will be resposible for ensuring that it gets deallocated at the correct time.
THANK YOU ALL for the very helpful discussion on this topic! Clearly there are several ways to approach things here, so this is a very useful assortment of techniques.
Just to let y'all know that in researching this issue further, I ran across a couple of other very helpful pages, listed below. They include mention of the NSNotificationCenter, which I hadn't heard of before; as well as the idea of the "dependency injection" design pattern.
The idea is to keep "low coupling"(1) between the classes, making the code more modular & better for unit testing.
And while the 'notification' pattern sounds like a great idea, in this case it may be a bit overkill, considering that I only need ONE instance of the data model throughout the run of the app, and it doesn't change throughout.
Finally, even though the "#public" compiler directive is well-documented in Apple's Obj-C guide(2), I later found a fascinating edict in a different doc stating that it shouldn't be used! Quoted from Apple's own Cocoa Fundamentals(3):
"Give the proper scope to your instance variables. Never scope a variable as #public as this violates the principle of encapsulation. ..."
(Strange that they don't mention this in their 'Objective-C 2.0' guide where the directive is actually explained.)
Anyway, here are a couple of other links I found to be full of some great insights as well. FYI:
S.O.: "What’s the best way to
communicate between
viewcontrollers?"(4) <<
CocoaWithLove: "Five approaches to
listening, observing and notifying in
Cocoa"(5)
CocoaWithLove: "Singletons,
AppDelegates and top-level data"(6)
Hope these help. Anyway, thank you all again!
Best,
rond
P.S. Yikes! It won't let me post more than one inline hyperlink, so I'm listing them here instead. Obviously, they’re all prefixed by “http://” ... :O
(1): en.wikipedia.org/wiki/Coupling_(computer_science)
(2): developer.apple.com/DOCUMENTATION/Cocoa/Conceptual/ObjectiveC/Articles/ocDefiningClasses.html#//apple%5Fref/doc/uid/TP30001163-CH12-TPXREF127
(3): developer.apple.com/documentation/Cocoa/Conceptual/CocoaFundamentals/AddingBehaviortoaCocoaProgram/AddingBehaviorCocoa.html#//apple_ref/doc/uid/TP40002974-CH5-SW12
(4): stackoverflow.com/questions/569940/whats-the-best-way-to-communicate-between-viewcontrollers
(5): cocoawithlove.com/2008/06/five-approaches-to-listening-observing.html
(6): cocoawithlove.com/2008/11/singletons-appdelegates-and-top-level.html

How to stub a class method in OCMock?

I often find in my iPhone Objective-C unit tests that I want stub out a class method, e.g. NSUrlConnection's +sendSynchronousRequest:returningResponse:error: method.
Simplified example:
- (void)testClassMock
{
id mock = [OCMockObject mockForClass:[NSURLConnection class]];
[[[mock stub] andReturn:nil] sendSynchronousRequest:nil returningResponse:nil error:nil];
}
When running this, I get:
Test Case '-[WorklistTest testClassMock]' started.
Unknown.m:0: error: -[WorklistTest testClassMock] : *** -[NSProxy doesNotRecognizeSelector:sendSynchronousRequest:returningResponse:error:] called!
Test Case '-[WorklistTest testClassMock]' failed (0.000 seconds).
I've had a really hard time finding any documentation on this, but I assume that class methods aren't supported by OCMock.
I found this tip after a lot of Googling. It works, but is very cumbersome:
http://thom.org.uk/2009/05/09/mocking-class-methods-in-objective-c/
Is there anyway to do this within OCMock? Or can someone think of a clever OCMock category object that could be written to accomplish this sort of thing?
Update for OCMock 3
OCMock has modernized its syntax for supporting class method stubbing:
id classMock = OCMClassMock([SomeClass class]);
OCMStub(ClassMethod([classMock aMethod])).andReturn(aValue);
Update
OCMock now supports class method stubbing out of the box. The OP's code should now work as posted. If there is an instance method with the same name as the class method, the syntax is:
[[[[mock stub] classMethod] andReturn:aValue] aMethod]
See OCMock's Features.
Original Answer
Sample code following Barry Wark's answer.
The fake class, just stubbing connectionWithRequest:delegate:
#interface FakeNSURLConnection : NSURLConnection
+ (id)sharedInstance;
+ (void)setSharedInstance:(id)sharedInstance;
+ (NSURLConnection *)connectionWithRequest:(NSURLRequest *)request delegate:(id<NSURLConnectionDelegate>)delegate;
- (NSURLConnection *)connectionWithRequest:(NSURLRequest *)request delegate:(id<NSURLConnectionDelegate>)delegate;
#end
#implementation FakeNSURLConnection
static id _sharedInstance;
+ (id)sharedInstance { if (!_sharedInstance) { _sharedInstance = [self init]; } return _sharedInstance; }
+ (void)setSharedInstance:(id)sharedInstance { _sharedInstance = sharedInstance; }
+ (NSURLConnection *)connectionWithRequest:(NSURLRequest *)request delegate:(id<NSURLConnectionDelegate>)delegate {
return [FakeNSURLConnection.sharedInstance connectionWithRequest:request delegate:delegate];
}
- (NSURLConnection *)connectionWithRequest:(NSURLRequest *)request delegate:(id<NSURLConnectionDelegate>)delegate { return nil; }
#end
Switching to and from the mock:
{
...
// Create the mock and swap it in
id nsurlConnectionMock = [OCMockObject niceMockForClass:FakeNSURLConnection.class];
[FakeNSURLConnection setSharedInstance:nsurlConnectionMock];
Method urlOriginalMethod = class_getClassMethod(NSURLConnection.class, #selector(connectionWithRequest:delegate:));
Method urlNewMethod = class_getClassMethod(FakeNSURLConnection.class, #selector(connectionWithRequest:delegate:));
method_exchangeImplementations(urlOriginalMethod, urlNewMethod);
[[nsurlConnectionMock expect] connectionWithRequest:OCMOCK_ANY delegate:OCMOCK_ANY];
...
// Make the call which will do the connectionWithRequest:delegate call
...
// Verify
[nsurlConnectionMock verify];
// Unmock
method_exchangeImplementations(urlNewMethod, urlOriginalMethod);
}
Coming from the world of Ruby, I understand exactly what you're trying to accomplish. Apparently, you were literally three hours ahead of me trying to do exactly the same thing today (time zone thing? :-).
Anyway, I believe that this is not supported in the way one would desire in OCMock because stubbing a class method needs to literally reach into the class and changes its method implementation regardless of when, where, or who calls the method. This is in contrast to what OCMock seems to do which is to provide you a proxy object that you manipulate and otherwise operate on directly and in lieu of a "real" object of the specified class.
For example, it seems reasonable to want to stub NSURLConnection +sendSynchronousRequest:returningResponse:error: method. However, it is typical that the use of this call within our code is somewhat buried, thus making it very awkward to parameterize it and swap in a mock object for the NSURLConnection class.
For this reason, I think the "method swizzling" approach you've discovered, while not sexy, is exactly what you want to do for stubbing class methods. To say it's very cumbersome seems extreme -- how about we agree it's "inelegant" and maybe not as convenient as OCMock makes life for us. Nevertheless, it's a pretty concise solution to the problem.
Here is a nice 'gist' with a swizzle implementation for class methods: https://gist.github.com/314009
If you modify your method under test to take a parameter which injects the class of the NSURLConnection, then it's relatively easy to pass in a mock that responds to the given selector (you may have to create a dummy class in your test module which has the selector as an instance method and mock that class). Without this injection, you're using a class method, essentially using NSURLConnection (the class) as a singleton and hence have fallen into the anti-pattern of using singleton objects and the testability of your code has suffered.
Link to the blogpost in the question and RefuX gist inspired me to come up with block enabled implementation of their ideas: https://gist.github.com/1038034