Can not create NSError: unrecognized selector - initialization

I am trying to create a NSError category to make pre-defined errors based upon status codes. However, any time that I try to create a NSError from my category, I get a
+[NSError errorWithDomain:code:userInfo:]: unrecognized selector sent to class 0x2b2b20
I have also tried calling the instance version of the NSError Initializer but this has the same result.
+(NSError*)errorOfType:(ErrorType)errorType inClassNamed:(NSString*)_nsClassName andMessage:(NSString*)_nsMessage
{
return [[[self class] alloc]initWithType:errorType inClassNamed: _nsClassName andMessage:_nsMessage];
}
#pragma mark -
#pragma mark - Init
-(id)initWithType:(ErrorType)errorType inClassNamed:(NSString*)_nsClassName andMessage:(NSString*)_nsMessage
{
NSInteger _nCode = [self codeFromErrorType:errorType];
NSDictionary *_nsUserInfo = [self localizedDescriptionForErrorType:errorType andMessage:_nsMessage];
NSLog(#"Why Does this fail? Is this Nil? %#, \n%i, \n%#", _nsClassName, _nCode, _nsUserInfo);
if ([self respondsToSelector:#selector(initWithDomain:code:userInfo:)]) {
if (self = [self initWithDomain:_nsClassName code:_nCode userInfo:_nsUserInfo]){
}
}else{
NSLog(#"NSERROR Did not create!!!");
}
return self;
}
When I run this code calling the static method, The output is:
2013-05-10 17:46:18.851 BMPassSDK-DemoApp[99692:c07] Why Does this fail? Is this Nil? Domain,
107,
{
NSLocalizedDescription = "A connection to the server could not be made. Please Try again later. ";
}
2013-05-10 17:46:18.851 BMPassSDK-DemoApp[99692:c07] NSERROR Did not create!!!
2013-05-10 17:46:18.852 BMPassSDK-DemoApp[99692:c07] +[NSError errorWithDomain:code:userInfo:]: unrecognized selector sent to class 0x2b2b20
(lldb) po 0x2b2b20
$0 = 2829088 NSError
(lldb)
Anyone have any suggestions on what I am missing?

When I first made this class it was a subclass of NSError. Later, when I tried to convert it from a subclass to category, I accidentally renamed my header file's base class to type NSObject instead of NSError. This is of course what was causing my issue because NSObjects do not respond to the selector initWithDomain:code:userInfo.
Anyways, thanks everyone for looking. Hope it helps someone else.

Related

Object allocated without autorelease keyword inside autoreleasepool. What happens?

#autoreleasepool {
MyObject *tempObj = [[MyObject alloc] init]; // no autorelease mentioned here
}
Once the control is out of previous block, does tempObj get released? Even though I have not added autorelease? Why?

CLLocationManager not returning correct location

I'm working on an app where it checks your location every minute or so to see if your location changed. I am simulating the location changes by using a simulated location in xCode. First I'll do London, then when it updates that I'll change it to something like Tokyo, and then when it's time to check the location again it just won't update, it still thinks it's in London.
-(void)recheckLocation{
locationManager = nil;
[recheckLocation invalidate];
locationManager = [[CLLocationManager alloc]init];
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters;
[locationManager startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
geocoder = [[CLGeocoder alloc] init];
[locationManager stopUpdatingLocation];
// Reverse Geocoding
[geocoder reverseGeocodeLocation:newLocation completionHandler:^(NSArray *placemarks, NSError *error) {
NSLog(#"Found placemarks: %#, error: %#", placemarks, error);
if (error == nil && [placemarks count] > 0) {
placemark = [placemarks objectAtIndex:0];
NSString *Location = [NSString stringWithFormat:#"%#, %#",placemark.locality, placemark.administrativeArea];
recheckLocation = [NSTimer scheduledTimerWithTimeInterval:60.0f target:self selector:#selector(recheckLocation) userInfo:nil repeats:YES];
} else {
NSLog(#"%#", error.debugDescription);
}
} ];
}
No matter how many times I changed the location it just keeps giving me the same location every time rather than the correct one. Can someone tell me what I am doing wrong?
Its bit older post and I am having basic knowledge in CLLocationManager stuff, but still I am trying to address the problem. I understand from your above code that CLLocationManager is recreated everytime. CLLocationManager is like a singleton class you don't need to recreate everytime. You just need to call [locationManager startUpdatingLocation]; .
Also everytime you are calling [geocoder reverseGeocodeLocation:xxx]. Probably you need to find accuracy before you do this so that it will not get called again and again.

Connecting from IOS to ASP.Net Webservce

I am writing an IPad App that needs to connect to a webservice that returns and integer like this:
<int xmlns="http://schemas.microsoft.com/2003/10/Serialization/">0</int>
My code looks like this
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:verficationURL]];
[request setHTTPMethod:#"GET"];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
}
-(void) connection: (NSURLConnection *)connection didReceiveData:(NSData *)data{
[self.responseData appendData:data];
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection {
NSString *result = [[NSString alloc] initWithData:self.responseData encoding:NSUTF8StringEncoding];
NSLog(#"array: %s", result);
}
The connection does finish loading, but I am unable to get the value 0 out of the result. What is the right way to do this. Thank You
I'm assuming you get the result, so will respond only regarding the parsing.
I'm usually using XMLReader for easy xml parsing. There are also other third-party libraries that you can use, or use NSXMLParsing directly, however, you'll need to write a little more code for that.
Using it, the code for parsing would look like this:
NSError *error = nil;
NSDictionary *dict = [XMLReader dictionaryForXMLData:self.responseData error:&error];
NSNumber *result = [dict valueForKey:#"int"];
if(error||!result){
// handle error (either the result is not xml format, or the xml doesn't contain a 'int' key)
}
else {
// handle result
}
I haven't tested this exact code, but it should be mostly correct.
Please create REST based Web Services as it becomes very easy to interact with the DB and move on to JSON.

Why does OCMock cause nsnotificaiton center to have EXC_BAD_ACCESS when using mockObserver

I setup mock observers like this:
id quartileObserverMock = [OCMockObject observerMock];
[[NSNotificationCenter defaultCenter] addMockObserver:quartileObserverMock
name:kVPAdPlayerDidReachQuartileNotification
object:self.adPlayer];
[[quartileObserverMock expect]
notificationWithName:kVPAdPlayerDidReachQuartileNotification
object:self.adPlayer
userInfo:#{#"quartile" : #(VPAdPlayerFirstQuartile), #"trackingEvent" : VPCreativeTrackingEventFirstQuartile}];
my unit tests run; but I get spurious EXC_BAD_ACCESS errors when the notificaiton is posted.
i.e.
[[NSNotificationCenter defaultCenter]
postNotificationName:kVPAdPlayerDidReachQuartileNotification
object:self.adPlayer
userInfo:#{#"quartile" : #(quartile), #"trackingEvent" : trackingEvent}];
When I comment out the observermock code my tests run fine every single time.
When I put the code back in, I get spurious crashes on postNotiicaitonName:object:userInfo, maybe once every 2.5 times.
Anyone got any ideas?
Refer the following sample code, this might help you. It worked for me
- (void)test__postNotificationwithName__withUserInfo
{
id observerMock = [OCMockObject observerMock];
[[NSNotificationCenter defaultCenter] addMockObserver:observerMock name:#"NewNotification" object:nil];
NSDictionary *userInfo = [[NSDictionary alloc] initWithObjectsAndKeys:#"2",#"2", nil];
[[observerMock expect] notificationWithName:#"NewNotification" object:[OCMArg any] userInfo:userInfo];
NotificationClass *sut = [[NotificationClass alloc] init];
[sut postNotificationwithName:#"NewNotification" userInfo:userInfo];
[[NSNotificationCenter defaultCenter] removeObserver:observerMock];
[observerMock verify];
}
and my posting notification method
- (void)postNotificationwithName:(NSString *)notifName userInfo:(NSDictionary *)userInfo
{
[[NSNotificationCenter defaultCenter] postNotificationName:notifName object:self userInfo:userInfo];
}
Please note:
observerMock always raise an exception when an unexpected notification is received.
Remove the mocked observer from the NSNotificationCenter at the end of the test case.
There are a couple of reasons why this could be happening (I know, because I just solved both of them them in my own code today)
1) A mock observer from a previous test was not removed
2) An non-mock instance object from a previous test is observing for the same notification, but that object has since become obsolete. In my case, an instance object from my setUp method was listening to the notification, but when it was dealloced, it did not remove itself from the NSNotificationCenter's observers list.
In both cases the solution is to use
[[NSNotificationCenter defaultCenter] removeObserver:name:object:]
Depending on the scope: 1) in the dealloc of all classes that observe NSNotificationCenter, 2) in the tearDown method, or 3) at the end of the test case (as #PrasadDevadiga mentioned)

Add NSString to NSMutableArray if NSString is not already pressent - not working

Can't understand why this won't work, it simply says id num hasn't been used before every time... and never adds it to the array. Any help on this would be much appreciated. I'm almost certainly missing something obvious, but its driving me mad.
- (IBAction)idNumInputEnd:(id)sender
{
// Check if ID Number has been used before, if it hasnt, add it to the list.
NSString *idNumCheck = idNumberInput.text;
if ([idNumberList containsObject:idNumCheck])
{
NSLog(#"This id number has been used before, ask user if he would like to reload the data");
}
else
{
NSLog(#"This id number hasn't been used before and is thus being added to the array");
[idNumberList addObject:idNumCheck];
}
}
My suspect (shared by Martin, as per his comment) that idNumberList has never been allocated and initialized to an empty NSMutableArray.
If that's the case ARC will assign nil to idNumberList, therefore [idNumberList containsObject:idNumCheck] will evaluate to nil, as well as [idNumberList addObject:idNumCheck]
In other terms your evaluated code becomes something like
if (nil) {
NSLog(#"This id number has been used before, ask user if he would like to reload the data");
} else {
NSLog(#"This id number hasn't been used before and is thus being added to the array");
nil;
}
Given that, the else branch will always be taken, the addObject call to a nil object will fail silently and this causes the behavior you're experiencing.
To fix that, initialize idNumberList like follows:
idNumberList = [[NSMutableArray alloc] init];

Resources