Is it possible to use an Enum as a property for my model? I currently have a class like this:
typedef NS_ENUM(NSUInteger, ListType) {
ListTypeDay,
ListTypeWeek,
ListTypeMonth,
ListTypeYear,
ListTypeCustom
};
#interface ListItem : RLMObject;
#property (nonatomic, copy) NSString *title;
#property (nonatomic, assign) ListType itemType;
#property (nonatomic, assign) BOOL isFinish;
#property (nonatomic, assign) NSTimeInterval targetTime;
#end
RLM_ARRAY_TYPE(ListItem)
Terminal output:
Terminating app due to uncaught exception 'RLMException', reason: 'Can't persist property 'itemType' with incompatible type. Add to ignoredPropertyNames: method to ignore.'
No, you can't store custom types (enums included) in Realm. See Supported Types in the documentation.
Realm supports the following property types: BOOL, bool, int, NSInteger, long, long long, float, double, NSString, NSDate, NSData, and NSNumber tagged with a specific type.
Simply replace NSUInteger to NSInteger in type definition.
typedef NS_ENUM(NSInteger, ListType)
Related
I am using JSONModel to cast values from server:
#interface PaymentCardsResponse: JSONModel
#property (strong, nonatomic) NSArray<JSONPaymentCard *> *userCards;
#end
But when later I try to access this
response.userCards.forEach { card in } //here is an error
I have an error:
Precondition failed: NSArray element failed to match the Swift Array Element type
Expected JSONPaymentCard but found __NSDictionaryI
Why do I have it there? What am I missing?
In the README file of JSONModel, there is a note saying:
#interface OrderModel : JSONModel
#property (nonatomic) NSInteger orderId;
#property (nonatomic) float totalPrice;
#property (nonatomic) NSArray <ProductModel> *products;
#end
Note: the angle brackets after NSArray contain a protocol. This is not the same as the Objective-C generics system. They are not mutually exclusive, but for JSONModel to work, the protocol must be in place.
JSONModel uses the type in the <> to determine the specific type of array to deserialise, and it is specifically noted that you can't replace this with Objective-C generics system ("not the same"!), so if you did:
#property (strong, nonatomic) NSArray<JSONPaymentCard *> *userCards;
You are not telling JSONModel what model type the array should contain, so it just dumbly deserialises NSDictionarys. You can do both Objective-C generics, and tell JSONModel the type of the array, as demonstrated by the next code snippet in the README.
#property (strong, nonatomic) NSArray<JSONPaymentCard *> <JSONPaymentCard> *userCards;
So I am using a Realm for my project, I have an object, 'Pedido' (spanish for order) that has many 'V3Producto' objects, as follows:
#interface V3Producto : RLMObject
#property NSString *codeProd; // Este es el código de barras!
#property NSString *codigo;
#property NSNumber<RLMDouble> *descuento;
#property NSString *detailProd;
#property NSInteger idid;
#property NSInteger idCompania;
#property NSNumber<RLMDouble> *priceProd;
#property NSInteger stock;
#property int cantidadComprada;
#property int cantidad; // cantidad de stock
And the code for the 'Pedidos' (orders)
#interface Pedido : RLMObject
#property NSNumber<RLMDouble> *idUbicacion;
#property NSString *fechaPedido;
#property NSString *sucursal;
#property NSNumber<RLMDouble> *filterId;
#property RLMArray<V3Producto*> *productos;
When I run the app, as soon as it loads I get the error: 'RLMException', reason: 'Property 'productos' requires a protocol defining the contained type - example: RLMArray' which is quite strange since, before adding the RLMArray seemed to work just fine! Any V3Producto seems to be a perfectly fine and valid RLMObject!
Any ideas?
EDIT:
I've tried renaming 'productos' to something else as other threads with the same name suggest but that didn't fix it.
This is because when declaring an RLMArray property, the type must be marked as conforming to a protocol by the same name as the objects it should contain according to Realm Docs
Syntex to declare an RLMArray is :-
RLM_ARRAY_TYPE(ObjectType)
#property RLMArray<ObjectType *><ObjectType> *arrayOfObjectTypes;
Your code should be:-
RLM_ARRAY_TYPE(V3Producto)
#interface Pedido : RLMObject
#property NSNumber <RLMDouble> *idUbicacion;
#property NSString *fechaPedido;
#property NSString *sucursal;
#property NSNumber <RLMDouble> *filterId;
#property RLMArray <V3Producto*> <V3Producto> *productos;
#end
The proper way to declare a RLMArray, would be as follows:
RLM_ARRAY_TYPE(V3Producto)
#interface Pedido : RLMObject
#property NSNumber<RLMDouble> *idUbicacion;
...
#property RLMArray<V3Producto*><V3Producto> *productosPedido;
Note the I had to declare the type I want to use as an array with a MACRO (in the first line) and the declaration of the array is slightly different (you have to set the type plus the macro you've declared).
I'm integrating Realm into my app. I need to know how to store a custom class object in an RLMObject subclass.
The only properties allowed to be saved in Realm are, accoding to the Documentation:
Realm supports the following property types: BOOL, bool, int,
NSInteger, long, long long, float, double, NSString, NSDate, NSData,
and NSNumber tagged with a specific type.
If you need to store another object (you're mentioning an instance of a custom class), the officially supported way to doing so is creating a subclass of RLMObject (assuming you're on Objective-C) and, inside a property in your parent object, create the reference, like mentioned an example in the docs:
#import <Realm/Realm.h>
#class Person;
// Dog model
#interface Dog : RLMObject
#property NSString *name;
#property Person *owner;
#end
RLM_ARRAY_TYPE(Dog) // define RLMArray<Dog>
// Person model
#interface Person : RLMObject
#property NSString *name;
#property NSDate *birthdate;
#property RLMArray<Dog *><Dog> *dogs;
#end
RLM_ARRAY_TYPE(Person) // define RLMArray<Person>
In this example we have a property owner in the Dog model. I think that's what you're looking for.
I have the following enum:
typedef NS_ENUM(NSUInteger, GraphType) {
GraphTypeRawData,
GraphTypeFilteredData
};
The compiler accepts without warning me declaring it as a property primitive, or as a pointer:
#property (nonatomic, assign) GraphType graphType;
VS
#property (nonatomic, assign) GraphType *graphType;
Which is the correct one to use? (And why?)
It's a primitive type. Don't use a pointer unless you have a very clear and specific reason to track a pointer to a primitive type (which will be very rare).
I'm developing an iOS 5.0+ app and I'm creating a Category for an UIButton:
#interface UIButton (NotificationBall)
#property (nonatomic, assign) NSInteger type;
#property (nonatomic, assign) NSInteger index;
#end
And its implementation:
#import "UIButton+NotificationBall.h"
#implementation UIButton (NotificationBall)
#dynamic type;
#dynamic index;
#end
Searching on internet I've found this question, but I haven't found any examples with NSInteger.
Do I need to use NSNumber instead of NSInteger?
If I use, NSNumber, what do I have to do?
Only Objective-C objects can be set as
associated objects, scalars cannot be used directly.
So you could declare the property as
#property (nonatomic, strong) NSNumber *type;
and directly use the code from the answer https://stackoverflow.com/a/5500525/1187415
that you referenced to.
Or you keep the NSInteger property, and wrap/unwrap it to NSNumber
in the getter/setter method like this:
-(void)setType:(NSInteger)type
{
objc_setAssociatedObject(self, &UIB_TYPE_KEY, #(type), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
-(NSInteger)type
{
return [objc_getAssociatedObject(self, &UIB_TYPE_KEY) integerValue];
}
Remark: "type" and "index" are quite common names. You should consider prepending the property names with some prefix, to
avoid a possible name collision with existing properties of UIButton.