RKClient is nil - restkit

This line of code:
RKClient *client = [RKClient sharedClient];
returns nil for client.
RKLogConfigureByName("RestKit", RKLogLevelTrace);
gives:
I restkit:RKLog.m:33 RestKit initialized...
Any suggestions?

You may want to look into using RKObjectManager, instead. RKObjectManager creates an RKClient, and is the main mechanism to serialize / deserialize objects.

OK, this is because the method just delivers the shared client. Which is nil until you use something like this:
RKClient *client = [RKClient clientWithBaseURL:url];
==== UPDATE
As #Dan suggested, using RKObjectManager is the better way to go.

Related

What are these method parameters called in Swift?

I'm just taking my first steps with Swift and after having worked with things like PHP, Ruby, JavaScript and Python, this is all totally new to me.
So, I have code like this:
class DerpController: NSURLConnectionDelegate, NSURLConnectionDataDelegate {
func connection(connection: NSURLConnection!, didReceiveResponse response: NSURLResponse) {
println("response received")
}
func connection(connection: NSURLConnection!, didReceiveData data: NSData!) {
println("data received")
}
func connectionDidFinishLoading(connection: NSURLConnection!) {
println("request finished")
}
}
What are these things called: didReceiveResponse, didReceiveData? Are they some kind kind of message identifier or what?
And is func connection one overloaded method or are there actually two that are identified by these "didReceive..." names?
didReceiveResponse is an external parameter name. response and data are local parameter names.
This means that the first function is called with myDerpController.connection(url, didReceiveResponse:response). But within the body of the function you refer to the parameter as response.
The second function is a typo, and should be didReceiveData
These are delegate methods defined by NSURLConnectionDataDelegate, which is a protocol you have adopted.
In Swift, a parameter can have both an internal (parameter, local) name and an external (argument, caller) name. The internal name (response:, data:) is entirely up to you; the name provided by the docs and by code completion is just a "serving suggestion". The external name, however, needs to match the selector name by which Objective-C (or any other caller) will seek it. The method is called e.g. connection:didReceiveData: so you must use an external name didReceiveData for the second parameter in order to be called.
You also asked (irrelevantly) about overloading. Overloading by type is legal in Swift but not in Objective-C; the latter uses names (selectors) alone. You're biting off a lot at once here because you've chosen to start with an example involving heavy interplay between Swift and Objective-C, to understand which you really need to know at least the rudiments of both languages.

syntax of #selector

ok without using NSInvocation, let's say I have this code:
...
array = [NSMutableArray arrayWithObjects:#"Yoda", #"Jedi", #"Darth Vader", #"Darth Vader", #"Darth Vader" , #"Darth Vader", nil];
SEL removeObjectMessage = #selector(removeObject:inRange:);
//does array allow us to remove and object in a range? if so let's do this
if ([array respondsToSelector:removeObjectMessage]){
NSRange darthVaderRange=NSMakeRange(2, 3);
[array removeObject:#"Darth Vader"inRange:darthVaderRange];
}
how would I perform that last line in the form of the SEL removeObjectMessage? I would have to put a wrapper around the range? I just want to see the syntax of how all that mess would look...
You could do:
if ([array respondsToSelector:removeObjectMessage]){
NSRange darthVaderRange=NSMakeRange(2, 3);
objc_msgSend(array, removeObjectMessage, #"Darth Vader", darthVaderRange);
}
Though that seems pretty fragile...
Unfortunately, if you're passing an argument that's not of type id, you have to use an NSInvocation object. (Otherwise, you could use performSelector:withObject:withObject:.)
There's no existing method that allows you to pass a selector and non-object arguments and get a valid method call. If it were a method that took only object arguments, you would do [array performSelector:removeObjectMessage withObject:#"Darth Vader" withObject:someHypotheticalRangeObject].
But to do it with an NSRange, you would have to either use NSInvocation (which you've said you don't want to do) or create a category on NSObject and use the low-level Objective-C runtime functions to define a method that takes a selector, an object argument and a non-object argument and calls the appropriate method.

Passing primitives to an OCMock's stub

I'm learning how to use OCMock to test my iPhone's project and I have this scenario: a HeightMap class with a getHeightAtX:andY: method, and a Render class using HeightMap. I'm trying to unit test Render using some HeightMap mocks. This works:
id mock = [OCMockObject mockForClass:[Chunk class]];
int h = 0;
[[[mock stub] andReturnValue:OCMOCK_VALUE(h)] getHeightAtX:0 andY:0];
Of course, works only for x=0 and y=0. I want to test using a "flat" height map. This means I need to do something like this:
id chunk = [OCMockObject mockForClass:[Chunk class]];
int h = 0;
[[[chunk stub] andReturnValue:OCMOCK_VALUE(h)] getHeightAtX:[OCMArg any] andY:[OCMArg any]];
But this raises two compilation warnings:
warning: passing argument 1 of 'getHeightAtX:andY:' makes integer from pointer without a cast
and a runtime error:
unexpected method invoked: 'getHeightAtX:0 andY:0 stubbed: getHeightAtX:15545040 andY:15545024'
What am I missing? I found no way to pass a anyValue to this mock.
It's been awhile since this question has been asked but I ran into this issue myself and couldn't find a solution anywhere. OCMock now supports ignoringNonObjectArgs so an example of an expect would be
[[[mockObject expect] ignoringNonObjectArgs] someMethodWithPrimitiveArgument:5];
the 5 doesn't actually do anything, just a filler value
OCMock doesn't currently support loose matching of primitive arguments. There's a discussion about potential changes to support this on the OCMock forums, though it seems to have stalled.
The only solution I've found is to structure my tests in such a way that I know the primitive values that will be passed in, though it's far from ideal.
Use OCMockito instead.
It supports primitive argument matching.
For instance, in your case:
id chunk = mock([Chunk class]);
[[given([chunk getHeightAtX:0]) withMatcher:anything() forArgument:0] willReturnInt:0];
In addition to Andrew Park answer you could make it a little bit more general and nice looking:
#define OCMStubIgnoringNonObjectArgs(invocation) \
({ \
_OCMSilenceWarnings( \
[OCMMacroState beginStubMacro]; \
[[[OCMMacroState globalState] recorder] ignoringNonObjectArgs]; \
invocation; \
[OCMMacroState endStubMacro]; \
); \
})
The you can use it like that:
OCMStubIgnoringNonObjectArgs(someMethodParam:0 param2:0).andDo(someBlock)
You can do the same for expecting. This case is for stubbing as topic starter request. It was tested with OCMock 3.1.1.
You could do like this:
id chunk = OCMClassMock([Chunk class])
OCMStub([chunk ignoringNonObjectArgs] getHeightAtX:0 andY:0]])
Readmore at: http://ocmock.org/reference/#argument-constraints
Despite being fairly hacky, the approach of using expectations to store the passed block to call later in the test code has worked for me:
- (void)testVerifyPrimitiveBlockArgument
{
// mock object that would call the block in production
id mockOtherObject = OCMClassMock([OtherObject class]);
// pass the block calling object to the test object
Object *objectUnderTest = [[Object new] initWithOtherObject:mockOtherObject];
// store the block when the method is called to use later
__block void (^completionBlock)(NSUInteger value) = nil;
OCMExpect([mockOtherObject doSomethingWithCompletion:[OCMArg checkWithBlock:^BOOL(id value) { completionBlock = value; return YES; }]]);
// call the method that's being tested
[objectUnderTest doThingThatCallsBlockOnOtherObject];
// once the expected method has been called from `doThingThatCallsBlockOnOtherObject`, continue
OCMVerifyAllWithDelay(mockOtherObject, 0.5);
// simulate callback from mockOtherObject with primitive value, can be done on the main or background queue
completionBlock(45);
}

change type from id to subclassed nsmanagedobject

I need this operation bsc method receive id and i like to using dot syntax to set object later.
Currently i do by this way. But maybe somebody know more elegant way?
-(NSError *) updateObject:(id)object operation:(NSInteger)operation;
{
CurrentCompany *obj1 = nil;
...
CompanyStuff *obj2 = nil;
if ([[[(CurrentCompany *)object entity] name] isEqualToString:#"CurrentCompany"]) obj1 = (CurrentCompany *)object;
if ([[[(CompanyStuff *)object entity] name] isEqualToString:#"CompanyStuff"]) obj2 = (CompanyStuff *)object;
NSLog(#"UpdatedObject:%#",obj1);
If these classes conform to a common protocol or inherit from a common superclass that declares the properties, you can just statically type the variable as that protocol or superclass. If neither of these are the case, it doesn't seem like they should be treated interchangeably anyway.
Also, this isn't really related, but the explicit cast from id to the specific class is pointless. You can just assign.

Cocoa JSON - Check whether array or dictionary

I am using the Cocoa JSON framework ( http://code.google.com/p/json-framework/ ) to communicate with an API.
The problem is that the API returns a dictionary if there is an error but returns an array of the results if it works.
Is there a good way to detect if the JSONValue is an array or a dictionary?
Thanks.
You can use isKindOfClass: to test whether the object is an instance of NSDictionary or of any subclass thereof.
In most circumstances, you would be better served by a respondsToSelector: check, but this is one case where you really are better off testing its class membership.
Of course, you can test whether it's an array instead of whether it's a dictionary; as long as the API you're using only returns an array or dictionary, the effect is the same.
For true robustness, test both array and dictionary membership, and throw an exception or present an error if the object is neither.
Maybe try to check length property.
if (jsonObj.length) {
//doSomeWork
}
Try this:
if ([YourData isKindOfClass:[NSArray class]])
{
NSLog(#"Array format found");
}
else
{
NSLog(#"Dictionary format found");
}

Resources