3

I am pretty new to iPhone development and I am getting this error output. I know what is happening, I just don't know how to fix it.

 Terminating app due to uncaught exception 'NSUnknownKeyException', reason: 
'[<loginData 0x6b1c> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key UserEMailAddress.'

Basically I am using the XML parser and trying to store data into my created class 'loginData.' The first element I come to, is UserEMailAddress and the code is trying to store that value into the class variable UserEMailAddress of the same name. But its throwing that error.

Obviously something went awry when I created my class. Somehow I guess things were not set up right and it can't input the data into the class. All I did to create loginData was do a file->new-> class object.

Here is the class code.

loginData.h

#import <Foundation/Foundation.h>

@interface loginData : NSObject{
  NSString *UserEMailAddress;
  NSString *SessionUID;
  NSString *SessionExpirationUTCDT;

 }

@property (nonatomic, retain) NSString *UserEMailAddress;
@property (nonatomic, retain) NSString *SessionUID;
@property (nonatomic, retain) NSString *SessionExpirationUTCDT;

@end

loginData.m

  #import "loginData.h"

  @implementation loginData

  @synthesize UserEMailAddress=_UserEMailAddress;
  @synthesize SessionUID=_SessionUID;
  @synthesize SessionExpirationUTCDT=_SessionExpirationUTCDT;

  @end

pretty simple stuff, nothing too complex.

the last method accessed before the crash is in my XMLParser, which is..

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
        if (!currentElementValue) {
           // init the ad hoc string with the value     
        currentElementValue = [[NSMutableString alloc] initWithString:string];
    } else {
        // append value to the ad hoc string    
        [currentElementValue appendString:string];
    }
    NSLog(@"Processing value for : %@", string);
  } 

I'm sure I just made a small mistake in making my class, but I don't know what that would be. Thanks in advance.

The only other method where it looks as if the variables are input to my class is this one.

  - (void)parser:(NSXMLParser *)parser 
   didEndElement:(NSString *)elementName
   namespaceURI:(NSString *)namespaceURI 
   qualifiedName:(NSString *)qName {

   if ([elementName isEqualToString:@"LoginResponse"]) {
       // We reached the end of the XML document
       return;
   }

  //if ([elementName isEqualToString:@"user"]) {
      // We are done with user entry – add the parsed user 
      // object to our user array
      //[users addObject:user];
      // release user object
      //[user release];
      //user = nil;
   // } 
   else {
        // The parser hit one of the element values. 
      // This syntax is possible because User object 
       // property names match the XML user element names   
      [loginData setValue:currentElementValue forKey:elementName];
  }   

  currentElementValue = nil;
}
User97693321
  • 3,336
  • 7
  • 45
  • 69
Jesse Durham
  • 285
  • 1
  • 5
  • 18
  • Did you try to clean and build your target again? – akashivskyy Dec 08 '11 at 16:08
  • Yes. No change. I have heard 'clean' still leaves some things around unchanged but I doubt that would apply to this. – Jesse Durham Dec 08 '11 at 16:15
  • Xcode will not use the variable `UserEMailAddress` you declared in the header, but will generate a iver called `_UserEMailAddress ` thus making your declaration of `UserEMailAddress` unused. Also Class names start capitols and properties do not, just the other way around then the way you did it. – rckoenes Dec 08 '11 at 16:16
  • So is XCode not using that variable whats causing the error to be thrown? Or is it just an FYI thing? Every example I have seen on declaring variables in classes has shown it that way. (at least on the iOS dev resources on apple's site) – Jesse Durham Dec 08 '11 at 16:37
  • Where's the code that actually stores values found in xml file into your object? – pronvit Dec 08 '11 at 20:50
  • Can you show WHERE do you set the value of `UserEMailAddress`? – akashivskyy Dec 08 '11 at 20:57
  • @JesseDurham: I would like to see one example where they declare instance variables without underscores and synthesise them with underscores. It doesn't work, and it won't work. – dreamlax Dec 08 '11 at 21:11
  • @dreamlax - Ive done the exact same thing in other places in my code and it works fine. – Jesse Durham Dec 08 '11 at 21:34
  • @Kashiv - I am following this guide for XML parsing http://wiki.cs.unh.edu/wiki/index.php/Parsing_XML_data_with_NSXMLParser so my knowledge is a bit limited on the subject. I have wondered myself where the value is actually being input into UserEMailAddress based on that guide's code(which is the same thing with different variable names) – Jesse Durham Dec 08 '11 at 21:38
  • I edited my original to contain the location of where it looks the data is being stored. As an FYI, my variable names are the same as the key values. – Jesse Durham Dec 08 '11 at 21:44
  • @dreamlax http://developer.apple.com/library/ios/#documentation/iphone/conceptual/iPhone101/Articles/06_ImplementingController.html - click the bubble that says "To synthesize the accessor methods for the user name property . . ." I'm starting to think with the way it reads, that the underscore is a new feature of xcode 4.2 – Jesse Durham Dec 08 '11 at 21:59
  • 1
    @JesseDurham: You're the one that didn't read it, here's the relevent excerpt: **By adding the underscore to `userName` in your @synthesize code line, you tell the compiler to use `_userName` as the name of the instance variable for the `userName` property. Because you didn’t declare an instance variable called `_userName` in your class, this code line also asks the compiler to synthesize that as well.** – dreamlax Dec 08 '11 at 22:22
  • @JesseDurham: Essentially this means that you end up with TWO instance variables with similar names, in the above excerpt, you will end up with `_userName` and `userName` instance variables. – dreamlax Dec 08 '11 at 22:22
  • @dreamlax - OK so why is it when i remove the underscore the issue is still there? – Jesse Durham Dec 09 '11 at 14:16
  • @JesseDurham: Because the issue likely lies elsewhere, but nevertheless, the underscore/no-underscore issue needed to be fixed. – dreamlax Dec 09 '11 at 19:53
  • @dreamlax - well I appreciate the help with fixing the underscore issue but my original error still exists. – Jesse Durham Dec 09 '11 at 20:53

5 Answers5

2

Lets look at your code:

loginData.h

@interface loginData : NSObject{
  NSString *UserEMailAddress;
  ...
 }

@property (nonatomic, retain) NSString *UserEMailAddress;
...

@end

loginData.m

@implementation loginData

@synthesize UserEMailAddress=_UserEMailAddress;
...

@end

If you notice, you synthesize the property to a missing variable name, _UserEMailAddress. you should replace that with UserEMailAddress, and your code will work fine.

Richard J. Ross III
  • 55,009
  • 24
  • 135
  • 201
  • I actually tried that.. It doesn't change anything. The error is still the same. – Jesse Durham Dec 08 '11 at 15:40
  • @Jesse - then you have another error as well as this one, but be sure, this is the error in the code you have shown. – hooleyhoop Dec 08 '11 at 21:23
  • @hooleyhoop are you sure? I followed apple's dev site for most of the declarations here. http://developer.apple.com/library/ios/#documentation/iphone/conceptual/iPhone101/Articles/06_ImplementingController.html click on the bubble that says "To synthesize the accessor methods for the user name property . . ." I'm starting to think the way it reads, the underscore is a new feature to xcode 4.2 – Jesse Durham Dec 08 '11 at 22:01
  • @Jesse - No, nothing to do with Xcode 4.2, it has always been this way. You really must follow the naming conventions (as others have pointed out). Your Class must be called LoginData (you have loginData). Your iVar must be called _userEmailAddress (note underscore - you have UserEMailAddress). Your Property must be userEmailAddress (no underscore - you have UserEMailAddress). Your Synthesize must be _userEmailAddress=userEmailAddress. – hooleyhoop Dec 08 '11 at 22:23
  • @hooleyhoop - Are the naming conventions the reason I'm getting the error here? I mean, I just did a copy/paste from the document I linked with different variable names.... – Jesse Durham Dec 09 '11 at 14:19
  • @Jesse Yes! it is the reason. You copied everything except the important bit. ok, i've been punked or whatever.. – hooleyhoop Dec 09 '11 at 14:42
  • @hooleyhoop - Ok, I deleted and renamed my class LoginData and that did fix it. I'm kind of dumbfounded it was actually that sensitive... (i come from a C background where nothing like this happens) Thanks for the help. – Jesse Durham Dec 09 '11 at 15:53
  • @hooleyhoop - actually.. I take that back. I had a typo that was causing data to be rewritten to the same variable and the XML storing of my program was never being executed. All my variables and files have the naming conventions. The error still exists. – Jesse Durham Dec 09 '11 at 20:53
2

I was facing the same issue because I renamed a attribute manually starting from a header - *.h - file. It look like by doing this, somewhere the manually renamed attribute remains referenced with the original name.

In order to fix this, I renamed back the attribute to the original name and them started a rename from source file - *.m.

0

I managed to solve it as I use the same example. What I did is use the names in the xml as my variables in my XMLParser.h For example, if your XML File is like that:

<Foo>
 <Param1>
  <UserEMailAddress>foo</UserEMailAddress>
  <SessionUID>foo</SessionUID>
  <SessionExpirationUTCDT>foo</SessionExpirationUTCDT>
 </Param1>
</Foo>

Your loginData.h will stay:

#import <Foundation/Foundation.h>

@interface loginData : NSObject{
  NSString *UserEMailAddress;
  NSString *SessionUID;
  NSString *SessionExpirationUTCDT;

 }

@property (nonatomic, retain) NSString *UserEMailAddress;
@property (nonatomic, retain) NSString *SessionUID;
@property (nonatomic, retain) NSString *SessionExpirationUTCDT;

@end

As far for me on my project, I receive both empty and correct data, for example:

2013-03-29 20:23:40.862 ******* [5271:907] Preccessing value for : 

2013-03-29 20:23:40.863 *******[5271:907] Preccessing value for : 20/03/13
2013-03-29 20:23:40.865 *******[5271:907] Preccessing value for : 

2013-03-29 20:23:40.866 *******[5271:907] Preccessing value for : 14:07
2013-03-29 20:23:40.868 *******[5271:907] Preccessing value for :  

And this is the parsed data, and not the tags, but that's a start.

Idan Moshe
  • 1,675
  • 4
  • 28
  • 65
0

Go to the connection inspector of your xib of loginData view controller & remove the reference of UserEMailAddress. After that it will run. Try It... :)

iYoung
  • 3,596
  • 3
  • 32
  • 59
0

Perhaps the issue here may be that you aren't properly conforming to Key Value Coding principals. For example, this document describes that a “key” must begin with a lowercase letter. If you don't follow the documentation to the ‘t’—especially about something as fundamental as KVC—you're likely to venture into strange, sometimes unexplainable behaviour.

dreamlax
  • 93,976
  • 29
  • 161
  • 209
  • I tried this as well, it gives the same error only with userEMailAddress instead of UserEMailAddress. Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[ setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key userEMailAddress.' – Jesse Durham Dec 09 '11 at 21:00
  • OK i fixed it!! In my code, the method where I store the value using the line [LoginData setValue:currentElementValue forKey:elementName]; I pretty much assumed the error was being generated from the "forKey:" command. So I decided to test some java style code and took that whole line out and replaced it with user.userEMailAddress = currentElementValue; This, stored the value into the class just fine. I need to do some more research into keys and see if this will have any negative effects later. – Jesse Durham Dec 09 '11 at 21:07
  • After reading that article, I actually found the problem with the KVC. In the line [LoginData setValue:currentElementValue forKey:elementName] LoginData is incorrect. I initialized LoginData as user earlier in my code. Replacing LoginData with user fixes the issue. Thanks for the help. – Jesse Durham Dec 09 '11 at 21:29