#dynamic how to set properties? - core-data

H file:
#interface TaskTypeEntity : NSManagedObject
#property (nonatomic, retain) UIColor *color;
#property (nonatomic, retain) UIImage *image;
#property (nonatomic, retain) NSString * name;
#property (nonatomic, retain) NSNumber * status;
#property (nonatomic, retain) NSSet *task;
#property (nonatomic, retain) NSSet *taskCount;
#end
M file:
#implementation TaskTypeEntity
#dynamic color;
#dynamic image;
#dynamic name;
#dynamic status;
#dynamic task;
#dynamic taskCount;
- (void) add:(TaskTypeEntity*)data
{
TaskTypeEntity *taskTypeEntity = [NSEntityDescription insertNewObjectForEntityForName:ENTITY_NAME inManagedObjectContext:content];
taskTypeEntity.name = data.name;
taskTypeEntity.image = data.image;
taskTypeEntity.color = data.color;
BOOL result = [content save:nil];
if (result) {
NSLog(#"success%#", data);
}else{
NSLog(#"fail");
}
}
#end
When setting the property, It doesn't work:
TaskTypeEntity *taskTypeEntity = [TaskTypeEntity alloc];
taskTypeEntity.name = #"dfdfd";
[taskTypeModel add:taskTypeEntity];
error:
* Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[TaskTypeEntity setName:]: unrecognized selector sent to instance 0x8a7b070'
Please help me, thank you

According to the NSManagedObject class reference:
Important: This method is the designated initializer for
NSManagedObject. You must not initialize a managed object simply by
sending it init.
The method of reference in the above quoted text is insertNewObjectForEntityForName:inManagedObjectContext: and can be used thusly:
NSManagedObject *object = [NSEntityDescription
insertNewObjectForEntityForName:#"Item"
inManagedObjectContext:context];
EDIT (In response...)
This code is just plain wrong:
TaskTypeEntity *taskTypeEntity = [TaskTypeEntity alloc];
Even if TaskTypeEntity were not a NSManagedObject it would still be wrong, as you never called an initializer.
The fact that it is a NSManagedObject makes it even more wrong, because you are never supposed to alloc/init one of those.
Why not try something like this (I assume you are using transformable attributes for image and color):
+ (instancetype)taskTypeEntityInMOC:(NSManagedObjectContext*)context
name:(NSString*)name
image:(UIImage*)image
color:(UIColor*)color
{
TaskTypeEntity *taskTypeEntity = [NSEntityDescription insertNewObjectForEntityForName:ENTITY_NAME inManagedObjectContext:content];
taskTypeEntity.name = name;
taskTypeEntity.image = image;
taskTypeEntity.color = color;
return taskTypeEntity;
}
Then you can call it...
TaskTypeEntity *taskTypeEntity =
[TaskTypeEntity taskTypeEntityInMOC:context
name:(NSString*)name
image:(UIImage*)image
color:(UIColor*)color];

Related

RestKit direct + inverse relationship mapping

As a newbie RestKit user I'm having a conceptual understanding problem with CoreData relationship mapping.
Let's say we have a CoreData model with just two entities in master/detail relationship:
#interface Master : NSManagedObject
#property (nonatomic, retain) NSString *objectId;
#property (nonatomic, retain) NSString *display;
#property (nonatomic, retain) NSSet *childrens;
#end
#interface Children : NSManagedObject
#property (nonatomic, retain) NSString *objectId;
#property (nonatomic, retain) NSString *display;
#property (nonatomic, retain) Master *father;
#end
The RestKit mapping for this model is:
RKEntityMapping *masterMapping = ...
RKEntityMapping *childrenMapping = ...
... property mappings ...
masterMapping.identificationAttributes = #[ #"objectId" ];
childrenMapping.identificationAttributes = #[ #"objectId" ];
[masterMapping addPropertyMapping:[RKRelationshipMapping
relationshipMappingFromKeyPath:#"childrens" toKeyPath:#"childrens"
withMapping:childrensMapping]];
[childrenMapping addPropertyMapping:[RKRelationshipMapping
relationshipMappingFromKeyPath:#"father" toKeyPath:#"father"
withMapping:masterMapping]];
Here is how the http get response is modeled (I can change it):
{
objectId: "3",
display: "a master object",
childrens: [
{
objectId: "1",
display: "a child object",
father: { objectId: "3" }
},
{
objectId: "2",
display: "another child object",
father: { objectId: "3" }
}
]
}
The problem is that the previous mapping definition would lead to a circular mapping error from RestKit when associating it with some RKResponseDescriptor.
I've read RestKit documentation and many stackoverflow.com similar threads, but still I don't understand how to set up a full CoreData model relationship mapping, provided that I need to have both relations available in my code (i.e. I need to explicitly access father from a children, and childrens from a master entity).
Any help will be appreciated.
Many thanks in advance!
I've figured out by myself my mapping understanding problem, and I'd like to share that just in case: a RestKit model mapping is not meant to be defined on the model in "absolute" terms, but "relatively" to the RESTful operations on the model.
Put in other terms, a model entity can have more than one RestKit mapping, each corresponding to how that entity is referred in GET/POST/PATCH/etc. operations.
I hope this can help others to ease the understanding of RestKit beautiful framework!

Is there way to check device model in Apportable SDK?

I have to implement some special behaviour for particular device model. So I need to check device model.
I'm using
[UIDevice currentDevice] name];
but it's return me something like this
Nexus 7 running Apportable
I think it's kind of weird result. Any other way to do it?
use [[UIDevice currentDevice] nativeModel]
NSLog(#"%#", [[UIDevice currentDevice] nativeModel]);
will generate D/Spin ( 3956): 2014-04-14 09:44:21.446 Spin[3956:2752] Nexus 7 in logcat output
There is more information about the UIDevice API extensions in .apportable/SDK/System/UIKit/UIDevice.h
Apportable typically makes API decisions for iOS ports to be as seamless as possible. If you actually want an Android specific result, a non-iOS API extension is usually created.
Here are some details on the UIDevice.h mappings to the Android Build API's:
#property (nonatomic, readonly) NSString *nativeSystemName; -> #"Android"
#property (nonatomic, readonly) NSString *nativeCPUABI; -> Build.CPU_ABI
#property (nonatomic, readonly) NSString *nativeModel; -> Build.MODEL
#property (nonatomic, readonly) NSString *nativeProduct; -> Build.PRODUCT
#property (nonatomic, readonly) NSString *nativeManufacturer; -> Build.MANUFACTURER
#property (nonatomic, readonly) NSString *nativeSystemVersion; -> Build.RELEASE
#property (nonatomic, readonly) NSUInteger nativeSDKVersion; -> Build.SDK_INT

Transient attribute not found in entity

I'm trying to get the first letter of an attribute (autor) from my pre populated sqlite database. I have no problems retriving data from the database using coredata. But when I try to get data from my transient property, I get this error message: "NSFetchedResultsController ERROR: object { Autor = "\U00cdtalo Calvino"; } returned nil value for section name key path 'FirstLetter'. Object will be placed in unnamed section"...
I have created a transient attribute called FirstLetter and inside my entity Cit. I have also my class for the entity defined.
Cit.h
#interface Cit : NSManagedObject {
#private
}
#property (nonatomic, retain) NSString * Autor;
#property (nonatomic, retain) NSString * FirstLetter;
- (NSString *) FirstLetter;
#end
Cit.m
#import "Cit.h"
#implementation Cit
#dynamic Autor;
#dynamic FirstLetter;
- (NSString *) FirstLetter {
NSLog(#"doing");
[self willAccessValueForKey:#"FirstLetter"];
NSString * initial = [[self valueForKey:#"Autor"] substringToIndex:1];
[self didAccessValueForKey:#"FirstLetter"];
return initial;
}
#end
I cannot get the it to work. Does anyone have a solution for that??? thanks!
I did something similar in my model class, but I didn't bother creating a transient object in the model. I just added a - (NSString *)sectionIndex method to my model that returned the first letter of the string, same as you.
So, I'd try deleting the transient attribute from your model and see if that works any better.

How to create generic id type properties?

I'm new to iOS and Objective-C and trying to create a class that has a generic property.
#interface HeaderInfo : NSObject {
NSString *label;
id value;
}
#property (nonatomic, retain) NSString *label;
#property (nonatomic, retain) id value;
- (HeaderInfo *)initWithLabel:(NSString *)lbl value:(id)val;
#end
Then I'm trying to add this class to an array:
[generalSection.items addObject:[[HeaderInfo alloc] initWithLabel:#"Tacho seal security" value:#"Some String Value"]];
[generalSection.items addObject:[[HeaderInfo alloc] initWithLabel:#"Tacho seal security" value:YES]];
but compiler doesn't like the 2nd addition and says:
Warning: passing argument 2 of 'initWithLabel:value:' makes pointer from integer without a cast
What I'm doing wrong? Any help is greatly appreciated.
And also how can check the value later on whether it's a BOOL or NSString?
Thanks.
The BOOL type is not a object, so you can't pass it as id (a generic object).
You should pass an NSNumber. An NSNumber is an object that encapsulate numbers when you want to pass a number as an object.
You can create a NSNumber like this : [NSNumber numberWithBool:YES];
You can retrieve the value with [value boolValue];
If you want to check the type of object you're having at runtime you can to it like that :
if ([value isKindOfClass:[NSNumber class]]) {
//It's a number
}
else if ([value isKindOfClass:[NSString class]]) {
//It's a string
}

Core Data question

the problem I am trying to solve in an application that is using Core Data is to be able to hold a calculated value in a NSManagedObject custom ivar. The calculated value that I want to store is in fact an image. I do not want to persist these images; I build them and destroy them throughout the lifetime of the application. I tried along the lines of:
#interface RTStaffImage : NSManagedObject {
UIImage *image;
}
// Custom properties
#property (nonatomic, retain) UIImage *image;
// Managed object properties
#property (nonatomic, retain) NSNumber *imageID;
#property (nonatomic, retain) NSString *imageName;
and custom accessors methods:
- (void)setImage (UIImage*)im;
- (UIImage *)image;
and in the implementation:
#implementation RTStaffImage
#synthesize image;
#dynamic imageID;
#dynamic imageName;
This fails at runtime with unrecognised selector problems:
-[NSManagedObject setImage:]: unrecognized selector sent to instance
The above approach is what Apple (or, at least as far as I see having read the docs) outlines for transient properties so it should work :-(
Any ideas, comments?
- (void)setImage (UIImage*)im;
you are missing a colon between setImage and (UIImage*). This is the correct version:
- (void)setImage:(UIImage*)im;
And where are the implementations of those two methods?
-[NSManagedObject setImage:]: unrecognized selector sent to instance
just curious, I read NSManagedObject there, are you sure you create an instance of RTStaffImage there?
Yeah, you have these backwards:
#synthesize image;
#dynamic imageID;
#dynamic imageName;
You're providing an implementation for setImage and image, so image should be #dynamic, and the others you need synthesized methods for, so use #synthesize for imageID and imageName.
Good point, they should all be #dynamic since you're with CoreData.
2nd attempt: you have set RTStaffImage as the Class name in the Entity, right?
3rd attempt: is RTStaffImage.m actually part of the Target being built?

Resources