OCMock stub isSelected property - ios

I am trying to stub the selected property on UIButton. The getter is defined as:
#property (nonatomic, getter=isSelected) BOOL selected;
My stub looks like this:
[[[button stub] andReturnValue:OCMOCK_VALUE(TRUE)] isSelected];
I receive the following error when I run the test:
Return value does not match method signature; signature declares 'c' but value is 'i'.
I think this is something to do with the getter=isSelected part but not sure what's going on
Is it possible to stub this type of getter?

This is annoying. The problem is that passing TRUE to OCMOCK_VALUE results in the creation of a value of type integer. The message you get is OCMock's way of saying that the method/property you want to stub is a boolean but you provided an integer.
You can force the creation of a an actual boolean value with either of the following:
[[[button stub] andReturnValue:OCMOCK_VALUE((BOOL){TRUE})] isSelected];
[[[button stub] andReturnValue:#YES] isSelected];
By the way, a similar problem occurs with different number types but unfortunately fixing this in OCMock isn't trivial. See here for example: https://github.com/erikdoe/ocmock/pull/58.

This doesn't answer my question but incase anyone else stumbles across this problem a workaround is to do a partial mock of an actual instance of UIButton.
UIButton *button = [[UIButton alloc] init];
button.selected = TRUE;
id mockButton = [OCMockObject partialMockForObject:button];

Related

How to pass on string parameter to another method through button selector?

I have this below delegate method that receives stickerURLString as input:
- (void)selectedSticker:(NSString *)stickerURLString {
//...
[self.stickerPreviewButton addTarget:self action:#selector(sendStickerPreviewButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
//...
}
And the selector calls this method sendStickerPreviewButtonPressed:
- (void)sendStickerPreviewButtonPressed: (NSString *)stickerURLString {
[self.delegate InputFunctionView:self sendSticker:stickerURLString];
}
As you can see in order to make this work as expected I have to pass on stickerURLString from selectedSticker method to sendStickerPreviewButtonPressed.
I have tried this:
[self.stickerPreviewButton performSelector:#selector(sendStickerPreviewButtonPressed:) withObject:stickerURLString];
instead of this:
[self.stickerPreviewButton addTarget:self action:#selector(sendStickerPreviewButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
But I got "terminating with uncaught exception of type NSException" error.
So anyone knows how to pass on string parameter to another method through button selector?
If you are using performSelector to call the function then you can use this variation
(id)performSelector:(SEL)aSelector
withObject:(id)object;
Documentation
https://developer.apple.com/reference/objectivec/1418956-nsobject/1418764-performselector
You can also check on this answer where another solution is explained, in my opinion probably more complex but useful
https://stackoverflow.com/a/14161831/1502070
For UIControl object function 1st parameter is id type, passes by control itself , you get uibutton object as a parameter in sendStickerPreviewButtonPressed: function which is not convertible to string , So you got an error, You may pass string By extending UIbutton class by your custom class . then Create button of your own class, anr get you custom property form sender button .
-(void)sendStickerPreviewButtonPressed:(mycustomButton*)sender{
//sender.myCustomString
}

Set bool property of all objects in the array

I've a model class called PhotoItem. In which I have a BOOL property isSelected
#interface PhotoItem : NSObject
/*!
* Indicates whether the photo is selected or not
*/
#property (nonatomic, assign) BOOL isSelected;
#end
I've an NSMutableArray which holds the object of this particular model. What I want to do is, in a particular event I want to set the bool value of all objects in the array to true or false. I can do that by iterating over the array and set the value.
Instead of that I tried using:
[_photoItemArray makeObjectsPerformSelector:#selector(setIsSelected:) withObject:[NSNumber numberWithBool:true]];
But I know it won't work and it didn't. Also I can't pass true or false as the param in that (since those are not object type). So for fixing this issue, I implemented a custom public method like:
/*!
* Used for setting the photo selection status
* #param selection : Indicates the selection status
*/
- (void)setItemSelection:(NSNumber *)selection
{
_isSelected = [selection boolValue];
}
And calling it like:
[_photoItemArray makeObjectsPerformSelector:#selector(setItemSelection:) withObject:[NSNumber numberWithBool:true]];
It worked perfectly. But my question is, Is there any better way to achieve this without implementing a custom public method ?
Is there any better way to achieve this without implementing a custom public method?
This sounds like you are asking for opinion, so here is mine: Keep it simple.
for (PhotoItem *item in _photoItemArray)
item.isSelected = YES;
Why obfuscate a simple thing with detours through obscure methods when you can write code that anybody will immediately understand?
Another way of doing the same thing would be:
[_photoItemArray setValue:#YES forKey:#"isSelected"];
This does not need the custom additional setter method because KVC does the unboxing for you.
But again I would vote against using such constructs. I think they are distracting from the simple meaning and confusing developers that come after you.

What is the -(CGRect *)frame method in iOS?

Codes:
if (!CGRectContainsPoint([[viewArray objectAtIndex:0] frame], CGPointMake(newX, newY)) )
{
....
}
Question
I wanna to get a "frame" value of a UIView in a view array, so i used this:
((UIView *)[viewArray objectAtIndex:0]).frame
I utilize (UIView *) to compulsively convert an id object to UIView, otherwise it will trigger error like "Property 'frame' not found on object of type 'id'". But the method below seems successfully escape from this error:
[[viewArray objectAtIndex:0] frame]
So [id frame] can Automatically detect the id's real type and then make it to call the method?
I really wanna to know methods like
[id frame]----id's real type is UIView
[id view ]----id's real type is UIViewController
Are these methods getter methods or setter methods? I cannot tell the diffrence and the apple document show them like :
#property(nonatomic) CGRect frame
Thx a lot for your help!
The method called in the end is -(CGRect)frame;. Using the dot syntax is just a syntactic sugar the objective-c compiler provides. For this sugar to work, the compiler needs to know the type of the object it uses.
On the other end, objective-c uses message passing for calling methods. Which means that when you use the syntax [id message], it will try to execute the selector #selector(message) on id. id being a special type denoting any object in the runtime, it accepts every selector and will throw an unknown selector exception at runtime if the object cannot execute it.
By defining a property like: #property(nonatomic) CGRect frame the property works as both a getter and setter.
For example, to modify the width of a frame, you might write:
CGRect frame = myView.frame;
frame.size.width = 100;
myView.frame = frame;
For a good description of dot notation, see this fine answer.

RACObserve(), RAC() - how to set a BOOL value based on an NSString

Being a ReactiveCocoa newbie, I'm hoping for some advice with this:
I'm trying to create a dynamic form that contains multiple Field objects parsed from an XML file. Each Field can have muliple validation rules that will run against the Field's NSString *value param.
For the RAC part of the question-
inside each Field object, I want to bind BOOL completed to a signal that checks the Field's *value param against an array of rules. So far I've gotten here with my thinking:
#implementation Field
self = [super init];
if (self) {
RAC(self, completed) = [RACObserve(self, value) filter:^BOOL(NSString *fieldValue) {
NSLog(#"%s::self.completed = %d\n", sel_getName(_cmd), self.completed); // trying to watch the values here, with no luck
NSLog(#"%s::fieldValue = %#\n", sel_getName(_cmd), fieldValue); // same here, I'd like to be able to view the `*value` here but so far no luck
return [self validateCurrentValue]; // currently this method just checks value.length > 5
}];
}
return self;
The *value param has already been bound to my view model (successfully) and it gets updated each time a textfield changes.
What I'm looking for is a basic example or best-practice, the code above crashes when run so I know I'm missing something fundamental.
Thanks all
-filter: is simply passing values from RACObserve(self, value) through unchanged, but only if the block returns YES. So that means you're trying to set completed to values of whatever type value is. That's Probably Bad®.
But the good news is that you're really close!
Instead of filtering, you want to transform. You want to take every value and map it to something other thing. Namely whether that value passes validation. To do that, we use -map::
RAC(self, completed) = [RACObserve(self, value) map:^(NSString *fieldValue) {
return #([self validateCurrentValue]);
}];

Is it possible to declare a variable type from string?

I don't know the technical term for this.I am wondering in Objective C, if it is possible to declare a variable like this:
NSClassFromString(aClassName) *var;
or
[NSClassFromString(aClassName) class] *var;
Apparently, the above two are not correct. What I want is to dynamically declare a variable.
Thanks.
You should make the ivar of id type, and then make it dynamically typed. For example, if you want to dynamically type it NSString, you can do like this :
id ivar;
Class myClass = NSClassFromString(#"NSString");
ivar = [[myClass alloc] initWithString:#"abc"];
You'll have to declare var as an id, and then instantiate it like:
var = [[NSClassFromString(aClassName) alloc] init];
The only point of declaring a type is compile-time type-checking, so there shouldn't be a problem as long as you only throw messages at the object that it can handle.
id is they type of a dynamically typed variable. If you need to check to see if a variable conforms to a particular class you can use -isKindOfClass:.
You can dynamically test if a class is some type with [var isKinkdOfClass:NSClassFromString(aClassName)]

Resources