3

I have some code in Objective-C. I think, I received type NSString, but when I try to save it in Core Data, I get a user.clientID = clientID; error, like:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Unacceptable type of value for attribute: property = "clientID"; desired type = NSString; given type = __NSCFNumber; value = 29.'

So, here's my code:

my Data manager singleton PKDataManager.h

+(PKDataManager*) sharedManager;

- (void)updateCoreDataUserWithID:(NSString*) userID
                 andClientID:(NSString*) clientID;

PKDataManager.m

- (void)updateCoreDataUserWithID:(NSString*) userID
                 andClientID:(NSString*) clientID{

       PKUser*user = [NSEntityDescription 
       insertNewObjectForEntityForName:@"PKUser" 
       inManagedObjectContext:self.managedObjectContext];
       user.userID = userID;
       user.clientID = clientID; ///// error showing here
       [self.managedObjectContext insertObject:user];
       [self.managedObjectContext save:nil];
}

my singleton for API PKServerManager.h

+ (PKServerManager*) sharedManager;

- (void) sendUserID:(NSString*) userID
              onSuccess:(void(^)(NSString* clientID)) success
              onFailure:(void(^)(NSError* error, NSInteger statusCode)) failure;

PKServerManager.m

- (void) sendUserID:(NSString*) userID
                  onSuccess:(void(^)(NSString* clientID)) success
                  onFailure:(void(^)(NSError* error, NSInteger statusCode)) failure{
        NSDictionary* params =
        [NSDictionary dictionaryWithObjectsAndKeys:
         userID, @"userID", nil];
        [self.requestOperationManager
         POST:@"app/registration"
         parameters:params
         progress:nil
         success:^(NSURLSessionTask *task, NSDictionary* responseObject) {
            NSLog(@"JSON: %@", responseObject);
            NSString* clientID = (NSString*)[responseObject objectForKey:@"clientId"];
            if (success) {
                success(clientID);
            }
         } failure:^(NSURLSessionTask *operation, NSError *error) {
         }];
}

and my CODE: PKProfile.m

[[PKServerManager sharedManager]
     sendUserID:profile.userID
     onSuccess:^(NSString* clientID) {
         NSLog(@"clientID %@", clientID);
         [[PKDataManager sharedManager] updateCoreDataUserWithID: profile.userID
                                                     andClientID: clientID];
     }
     onFailure:^(NSError *error, NSInteger statusCode) {
     }];
Rickest Rick
  • 1,519
  • 1
  • 15
  • 28
Peter
  • 55
  • 1
  • 6
  • Where is `profile.userID` set? – Nathan Hillyer Feb 07 '18 at 16:27
  • Put a breakpoint after `NSString* clientID = (NSString*)[responseObject objectForKey:@"clientId"];`check on debugger if clientID is actually a NSString or you are just forcing a cast on a NSNumber – Leonardo Feb 07 '18 at 16:30

2 Answers2

3

in your PKServerManager.m

replace following line of code:

NSString* clientID = (NSString*)[responseObject objectForKey:@"clientId"];

with

NSString* clientID = [NSString stringWithFormat:@"%@",[responseObject objectForKey:@"clientId"]];
Krunal
  • 77,632
  • 48
  • 245
  • 261
  • 3
    Which makes you want to ask why this code assumes `clientId` is a string but the server is sending it as a number. – rmaddy Feb 07 '18 at 16:31
3

Your error is telling you that the response included a numeric value for client ID (and is represented in the responseObject as a NSNumber; NSCFNumber is part of the broader NSNumber class cluster). It would appear that your JSON response included something like:

{
    ...,
    "clientId": 42
}

rather than

{
    ...,
    "clientId": "42"
}

Rather than focusing on how to convert this NSNumber to a NSString, I would instead be inclined to consider changing client ID throughout the app to be a NSInteger (or a NSNumber). If these IDs are really numeric values, it's best to have a type that reflects that.

Rob
  • 415,655
  • 72
  • 787
  • 1,044
  • 1
    You are absolutely right ! If `clientId` is number (integer) value, then it should be handled using `NSInteger`. – Krunal Feb 07 '18 at 17:22