Search code examples
iosobjective-ccore-dataiphonecoredatarecipes

I cannot insert value with NSNumber datatype into my coredata


Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Unacceptable type of value for attribute: property = "XXXXX"; desired type = NSNumber; given type = NSTaggedPointerString; value = 0.'

Tried: [enter image description here][1]

 [message setValue:localID forKey:@"local_id"];

localID is of type NSNumber

DataModel image: [1]: https://i.sstatic.net/7WTlU.png

 [self insertInLocatDB:print_data entityName:@"Message_data" withPredicate:@"receiver_id" filterWith:@"unique_id"];

Using this to insert into CoreData:

 -(void)insertInLocatDB :(NSMutableArray *)arr_msg entityName:(NSString*)name withPredicate:(NSString*)predicateText filterWith:(NSString*)filterText
{
    NSEntityDescription *entitydesc=[NSEntityDescription entityForName:name inManagedObjectContext:app.context];
    NSFetchRequest *request=[[NSFetchRequest alloc]init];
    [request setEntity:entitydesc];
    NSInteger local_id =[self getMaxLocalId:name];


    for(int i=0; i<[arr_msg count]; i++)
    {
        [fetched_data removeAllObjects];
        NSPredicate *predicate =[NSPredicate predicateWithFormat:@"%@ like %@ ",predicateText,[[arr_msg objectAtIndex:i]objectForKey:predicateText]];
        [request setPredicate:predicate];
        NSError *error;
        NSArray *matchingData=[app.context executeFetchRequest:request error:&error];

        local_id=local_id+1;

        for (NSManagedObject *obj in matchingData)
        {
            [fetched_data addObject:[obj valueForKey:filterText]];
        }
        NSString *filter=[[arr_msg objectAtIndex:i] objectForKey:filterText];
        if(![fetched_data containsObject:filter])
        {
            NSManagedObject *message=[[NSManagedObject alloc] initWithEntity:entitydesc insertIntoManagedObjectContext:app.context];
            [arr_keys setArray:[[arr_msg objectAtIndex:i] allKeys]];
            [arr_values setArray:[[arr_msg objectAtIndex:i] allValues]];
            [message setValue:[NSNumber numberWithInteger:local_id] forKey:@"local_id"];
            for (int i=0;i<[arr_keys count];i++)
            {
                if( [[message.entity propertiesByName] objectForKey:[arr_keys objectAtIndex:i]] != nil
                   && ([[[message.entity propertiesByName] objectForKey:[arr_keys objectAtIndex:i]] isKindOfClass:[NSAttributeDescription class]]) )
                {
                    [message setValue:[arr_values objectAtIndex:i] forKey:[arr_keys objectAtIndex:i]];
                }
            }
            [arr_keys removeAllObjects];
            [arr_values removeAllObjects];
        }
    }
}

Solution

  • If you have a core data attribute as shown in my screen shot.

    enter image description here

    Then, the following snippet of code will work for you.

    BOOL result;
        NSManagedObjectContext *context = [self managedObjectContext];
    
        // Create a new managed object
        NSManagedObject *newMessage = [NSEntityDescription insertNewObjectForEntityForName:@"message"
                                                                  inManagedObjectContext:context];
        [newMessage setValue:[NSNumber numberWithInt:local_id] forKey:@"local_id"];
        [newMovie setValue:movieName forKey:@"message"];
    
        NSError *error = nil;
        // Save the object to persistent store
        result = YES;
        if (![context save:&error]) {
            result = NO;
            NSLog(@"Can't Save! %@ %@", error, [error localizedDescription]);
        }
        return  result;
    

    and a function to get the managed object context

    - (NSManagedObjectContext *)managedObjectContext {
        NSManagedObjectContext *context = nil;
        id delegate = [[UIApplication sharedApplication] delegate];
        if ([delegate performSelector:@selector(managedObjectContext)]) {
            context = [delegate managedObjectContext];
        }
        return context;
    }
    

    Edited Code of Sandhya.

    -(NSInteger)getMaxLocalId :(NSString*)entitiyName
    {
        NSEntityDescription *entitydesc=[NSEntityDescription entityForName:entitiyName inManagedObjectContext:app.context];
        NSFetchRequest *request=[[NSFetchRequest alloc]init];
        [request setEntity:entitydesc];
        NSInteger local_id = 0;
        request.fetchLimit = 1;
        request.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"local_id" ascending:NO]];
        NSError *error = nil;
        local_id=[[app.context executeFetchRequest:request error:&error].firstObject integerValue];
        return local_id;
    }
    

    Then used the following to insert in to CoreData

    NSInteger local_id =[self getMaxLocalId:name];
    local_id=local_id+1;
    [message setValue:[NSNumber numberWithInteger:local_id] forKey:@"local_id"];
    

    make sure you get the local_id.

    As you have NSInteger, For conversion you should use [NSNumber numberWithInteger:] Instead of [NSNumber numberWithInt:]

    UPDATE 2 :

    NSString *filter=[[arr_msg objectAtIndex:i] objectForKey:filterText];
    if(![fetched_data containsObject:filter])
    {
        NSManagedObject *message=[[NSManagedObject alloc] initWithEntity:entitydesc insertIntoManagedObjectContext:app.context];
        [arr_keys setArray:[[arr_msg objectAtIndex:i] allKeys]];
        [arr_values setArray:[[arr_msg objectAtIndex:i] allValues]];
        [message setValue:[NSNumber numberWithInteger:local_id] forKey:@"local_id"];
        for (int i=0;i<[arr_keys count];i++)
        {
            if( [[message.entity propertiesByName] objectForKey:[arr_keys objectAtIndex:i]] != nil
               && ([[[message.entity propertiesByName] objectForKey:[arr_keys objectAtIndex:i]] isKindOfClass:[NSAttributeDescription class]]) )
            {
                if(![[arr_keys objectAtIndex:i] isEqualToString:@"local_id"]){
                    [message setValue:[arr_values objectAtIndex:i] forKey:[arr_keys objectAtIndex:i]];
                }
            }
        }
        [arr_keys removeAllObjects];
        [arr_values removeAllObjects];
    }