I binded the content of an IKImageBrowserView to an array controller of objects Person implementing the IKImageBrowserItem protocol:
– imageUID
– imageRepresentationType
– imageRepresentation
In the class Person, I want the attribute "photo" to be the same as the attribute "imageRepresentation" (that was added merely to conform to the protocol).
My solution so far is to bind the 2 attributes in the Person init method. However, I don't like to have duplicated attributes, since Person is a model class.
What should I do ? (keeping in mind that I want to preserve the name photo, and not imageRepresentation)
Since imageRepresentation is mandatory for the protocol, but you want to use the photo property, you could implement the method in this way:
- (id)imageRepresentation {
return self.photo
}
In this way you fulfill the protocol, but you are using only photo.
Related
In order to refresh a domain object i.e to re-read the data from database we do refresh().
def b = Book.get(1)
…
b.refresh()
I am wondering whether we can refresh a property of the domain.
Suppose i have bound params to Book object and suppose i want to unbind the author property from the book object then is it possible to achieve that?
Let's consider the Book is defined as
class Book {
String title
String author
String category
}
Suppose I do bindData(bookInstance, params). This will bind to all properties. I want to unbind the author after bindData. Is this possible?
It sounds like you just want to exclude binding a particular property.
bindData(bookInstance, params, [exclude: 'author'])
will bind all of the Book properties except for those listed.
You can conversely use include to explicitly list which properties to bind from params.
bindData(bookInstance, params, [include: 'title', 'category'])
I solved this by using bookInstance.author = bookInstance.getPersistentValue('author').
I want to iterate over the properties of my models in Objective-C. I tried this. Created PropertyUtil class with method classPropsFor:(Class)klass. Please find the attachment. Used objc/runtime.h. The code which I got from the net. In my viewcontroller I am doing this. [PropertyUtil classPropsFor:[self.user class]];. self.user is User model class. What I want to know is how can i iterate over the properties of my models, let's username, password and those values.
You may want to manually list all properties your model has.
Just add a method to your model:
+(NSArray*) propList {
return #[#"prop1", #"prop2"];
}
Then just use key-value coding to get the value
[someObject valueForKey:#"prop1"];
That's pretty straight and simple way if you wish to avoid Obj-C meta functions. Since you add your properties manually anyway, you may also add them in your list as well.
That's of course, if you don't have a large amount of models already and you wish do them all at once.
I'm new to Parse and Swift.
I have an app where people play against each other.
I want to create an activity feed where game results, cheers, heckles (anything really) can show up in a list.
My thought is to create an Activity class that subclasses PFObject and I'd like to have an enum ActivityType to determine what kind of Activity is being created.
Can I set up the Activity object in Parse and the PFObject in Swift so that each Activity is set up with the correct ActivityType?
My thinking is that I need a "Type" column in Parse that's just a number and an init method that reads that number and sets the correct type.
Does that sound about right?
Thanks
You could use a type column in parse, though I'd expect each of your different kinds of feed item to be different classes in parse as they all have different data and relationships, so you could use the class type (name).
In either case this is just a way to identify the type coming from the server. Once you have that you want an organised and common approach to displaying the feed items. To do that you should have a protocol which defines what a feed item needs to provide in order to be displayed on the feed. Then you have a set of classes, each conforming to that protocol, and each dealing with one of the different types of feed item to 'mutate' them into the common format for display.
Using an enum in your app would work, but it could lead you to have one big switch statement dealing with everything. So long as you just use the enum and switch to deal with deciding which class to create to handle the feed item then your code should be well structured.
I've solved this problem. It was 'free' functionality from Parse. I think first of all, you should consider subclassing PFObject (for many reasons). Once you do this, all you have to do is add the enum as a property to your subclass. It's taken care of automatically by Parse.
Parse knows how to convert to NSNumber and vice versa for an enum, no need to worry about that.
Note, in your .m file:
#implementation MyParseObjectSubclass
#dynamic aPropertyIWantPersisted; // declare your properties as dynamic to be managed by Parse
#synthesize aLocalTransientProperty; // if you have transient properties that you don't want persisted to the server.
+ (void)load
{
[self registerSubclass];
}
+ (NSString*)parseClassName
{
return "MySubclass";
}
#end
In my CoreData model, I have an entity called Contact. It has an attribute called profileImage, with the type set to Transformable.
In the Contact class (a subclass of NSManagedObject), I've changed profileImage from being a generic id to being an UploadedImage:
#property (nonatomic, retain) UploadedImage * profileImage;
The UploadedImage class has a few properties of its own.
The problem is that CoreData doesn't know when the properties on the UploadedImage object have changed. If only those properties are changed, the willSave method is never called on the Contact object when the managed object is saved. It works as expected if I change any other property on the Contact object: it just doesn't "see" changes to anything on the UploadedImage object within the Contact object.
What's the correct way to indicate that the managed object needs to be saved? Should I manually call willChangeValueForKey: and didChangeValueForKey: for the key 'profileImage' on my Contact object?
Edit to clarify a couple things
Contact is a CoreData entity, but the ImageUpload class is NOT.
CoreData will save the data in the ImageUpload object (because I implemented the NSCoding protocol methods, I think). If I change a property on the ImageUpload object, AND change a property on the Contact object, the Contact is saved, and that changed value persists on the ImageUpload object when the Contact is loaded from CoreData again.
Unless there's another way I'm not aware of, it sounds like marking the NSManagedObject as dirty is the way to go. You can do that using a separate dirtyFlag attribute, or by simply using the profileImage attribute itself.
One way to automate this would be KVO. You observe all properties of UploadedImage in the Contact class, and then just call self.profileImage = self.profileImage. I'm not sure if this is optimized by the compiler. If it is, you can also call willChangeValueForKey: and didChangeValueForKey:, which should trigger it. If Core Data noticed that the object didn't actually change, you can try to implement NSCopying and assign a copy of the original UploadedImage.
I don't believe Core Data will persist changes made to the subclass. The contract in Core data is between the parent entity and Core Data, so Core Data only responds to changes made to the properties in the entity class.
You can get around this by making that property a NSDictionary in the Entity and in the subclass add the image object to the dictionary.
Expanding upon Scott's solution (no copy necessary!), here is a method for Swift that works with any field:
static func markDirty<C, T>(_ obj: C, _ keyPath: ReferenceWritableKeyPath<C, T>) {
obj[keyPath: keyPath] = obj[keyPath: keyPath]
}
Used like so:
NSManagedObject.markDirty(playlist, \.rules)
Unfortunately it's not possible right now to define it as an instance method, due to limitations with generics.
My question is very simple. I have something like 10 different entities in CoreData, all with the same attributs (name, description ...). To access these attributes i doing in this way:
MyEntity *entity=...;
MyEntity2 *entity2=...;
...
MyEntity10 *entity10=...;
[self myfunction:AnEntity];
After I send a random object to a function
-(void)myfunction:(id)myentity
And here i would like to use a variable which can access the entity attributes whether it's a king of class MyEntity or MyEntity2... The problem is that i can't do:
id myobject=myentity;
NSLog(#"%#", myobject.name);
If someone have a solution to avoid testing the kind of class of the object :)
Thanks !
If you have 10 different entities, I think it's time to move to NSManagedObject subclasses. Then you can define a protocol that encompasses all of the shared attributes, and declare that your NSManagedObject subclasses comply with that protocol. Then your call becomes
-(void)myfunction:(id<SharedAttributesProtocol>)myObject
{
NSLog(#"%#", myObject.name);
}
You mentioned "description" as one of your shared attributes. The -description method is already defined, so you probably want to choose another name for that attribute.
This disadvantage of using a parent NSEntity for the common attributes is that you end up with one very wide table. This table has all of the common attributes, but also has all of the distinct attributes for each of the subentities. Depending on the size of your objects, this will be a performance hit under iOS, although it's not so awful on OS X.
In fact you could call
[myobject valueForKey:#"name"]
or even
[myobject name]
in your function, because the methods are resolved at runtime. If myobject has a "name" attribute, this will work, otherwise it will crash at runtime.
A cleaner solution would be to define one "parent entity" MyEntity with the common attributes name, description etc. Then you can define subentities MyEntity1, MyEntity2, ... which have MyEntity as "Parent Entity". These subentities inherit all attributes/relationships of the parent entity, and can have additional attributes and relationships.
The corresponding managed object subclasses are then subclasses of the MyEntity class. Your function could look like this:
- (void)myfunction:(MyEntity *)myentity
{
NSLog(#"%#", myentity.name);
}
and you can call it with instances of any of the subclasses:
MyEntity1 *myentity1 = ...;
[self myfunction:myentity1];
MyEntity2 *myentity2 = ...;
[self myfunction:myentity2];