I've subclassed the PFObject with the following Class (dynamic properties, and +load & parseClassName Methods in .m file)
#interface DAOpponents : PFObject <PFSubclassing>
#property (nonatomic, strong) PFObject* fromUser;
#property (nonatomic, strong) PFObject* toUser;
#property (nonatomic) BOOL isVisible;
#property (nonatomic) BOOL isPersistent;
+ (NSString *)parseClassName;
#end
In a Unit Test I try to create a Sample DAOpponents-Object:
DAOpponents* follow = [DAOpponents object];
follow.fromUser = user1; // caught "NSInvalidArgumentException", "PFObject values may not have class: PFUser"
follow.toUser = user2;
[follow save];
If I do the same without a subclassed Version of the opponents there's no Exception
PFObject* follow = [[PFObject alloc] initWithClassName:#"DAOpponents"];
[follow setObject:user1 forKey:#"fromUser"]; // no exception!!!
[follow setObject:user1 forKey:#"toUser"];
Why does a subclassed PFObject can not point to a PFUser object?
Any help appreciated! Thanks a lot!
I was able to get around this problem by first subclassing PFUser, then using my subclass called User in my other PFObject subclasses.
My PFUser subclass, User.h:
#import <Parse/Parse.h>
#class Person;
#class Parish;
#interface User : PFUser<PFSubclassing>
//+ (NSString *)parseClassName;
// Return the current user
+ (User *)currentUser;
#property (retain) NSNumber *acceptedAgreements;
#property (retain) NSNumber *isAdmin;
#property (retain) Person *person;
#end
and my User.m:
#import "User.h"
#import <Parse/PFObject+Subclass.h>
#import "Person.h"
#implementation User
#dynamic acceptedAgreements;
#dynamic isAdmin;
#dynamic person;
//+ (NSString *)parseClassName {
// return #"User";
//}
// Return the current user
+ (User *)currentUser {
return (User *)[PFUser currentUser];
}
#end
Related
I have old project written on Objective-C. Need to do migration to Realm.
I created several objects/classes inheritance from RLMObject. When I do fetching objects only with one main object type (ConnectionRealm) - working fine, but if I do add (only add, not include, not use) to project two or more another classes (inheritance from RLMObject), like as FloorRealm class, APP crash on [ConnectionRealm allObjects] without any errors.
Also ConnectionRealm contains RLMArray of FloorRealm. App still crashing.
(Can`t solve and understand this few days.) Thanks.
Connection Model:
#import <Foundation/Foundation.h>
#import <Realm/Realm.h>
#import "FloorRealm.h"
#interface ConnectionRealm : RLMObject
#property int connectionID;
#property NSString *name;
#property NSString *localIPAddress;
#property NSString *localPort;
#property NSString *remoteIPAddress;
#property NSString *remotePort;
#property NSString *userName;
#property NSString *password;
#property NSString *deviceID;
#property RLMArray <FloorRealm *> *floors;
- (instancetype)initWith:(NSString *)name
localIP:(NSString *)localIPAddress
localPort:(NSString *)lPort
remoteIP:(NSString *)remoteIPAddress
remotePort:(NSString *)rPort
userName:(NSString *)userName
password:(NSString *)password
deviceID:(NSString *)deviceID;
#end
#import "ConnectionRealm.h"
#implementation ConnectionRealm
- (instancetype)initWith:(NSString *)name
localIP:(NSString *)localIPAddress
localPort:(NSString *)lPort
remoteIP:(NSString *)remoteIPAddress
remotePort:(NSString *)rPort
userName:(NSString *)userName
password:(NSString *)password
deviceID:(NSString *)deviceID {
if (self = [super init]) {
self.connectionID = [self incrementID];
self.name = name;
self.localIPAddress = localIPAddress;
self.localPort = lPort;
self.remoteIPAddress = remoteIPAddress;
self.remotePort = rPort;
self.userName = userName;
self.password = password;
self.deviceID = deviceID;
}
return self;
}
+ (NSString *)primaryKey { return #"connectionID"; }
- (int)incrementID {
RLMResults *objects = [ConnectionRealm allObjects];
return self.connectionID = [[objects maxOfProperty:#"connectionID"] intValue] + 1;
}
#end
FloorModel:
#import <Realm/Realm.h>
#interface FloorRealm : RLMObject
#property int floorID;
#property NSInteger floorNumber;
#property NSString *floorName;
- (instancetype)initWith:(NSInteger)floorNumber floorName:(NSString *)name;
#end
RLM_ARRAY_TYPE(FloorRealm)
#import "FloorRealm.h"
#implementation FloorRealm
- (instancetype)initWith:(NSInteger)floorNumber floorName:(NSString *)name {
if (self = [super init]) {
self.floorID = [self incrementID];
self.floorNumber = floorNumber;
self.floorName = name;
}
return self;
}
+ (NSString *)primaryKey { return #"floorID"; }
- (int)incrementID {
RLMResults *objects = [FloorRealm allObjects];
return self.floorID = [[objects maxOfProperty:#"floorID"] intValue] + 1;
}
#end
[SOLVED]
RLM_ARRAY_TYPE(FloorRealm) need put on ConnectionRealm in .h after #includes. But in official docs written another.
Also: #property RLMArray <FloorRealm *><FloorRealm> *floors; instead of #property RLMArray <FloorRealm *> *floors;
I created test project with the same models and seed all errors. Strange, but in original project Xcode not showing this errors.
When I look around the Cocoa Touch API, I can find some classes declared along with categories in the same header file, e.g.
#interface NSArray : NSObject <NSCopying, NSMutableCopying, NSSecureCoding, NSFastEnumeration>
#property (readonly) NSUInteger count;
// and some other properties
#end
#interface NSArray (NSExtendedArray)
#property (readonly, copy) NSString *description;
// and some other properties
#end
Now I am trying to do the same thing with my class, like as follow:
#interface ARCTextbook : NSObject
#property (nonatomic) NSInteger ID;
#property (nonatomic) NSString *name;
#end
#interface ARCTextbook (Student)
#property (nonatomic) NSInteger studentID;
#property (nonatomic, getter=isUsed) BOOL used; // Used by a student?
#end
However, when I tried to access studentID or used property, I got an unrecognized selector error. Am I missing anything?
Cheers.
This is Associated Objects, you can refer documentation in below:
http://www.davidhamrick.com/2012/02/12/Adding-Properties-to-an-Objective-C-Category.html
How to store not id type variable use a objc_getAssociatedObject/objc_setAssociatedObject?
ARCTextbook.h
#import <Foundation/Foundation.h>
#interface ARCTextbook : NSObject
#property (nonatomic) NSInteger ID;
#property (nonatomic) NSString *name;
#end
#interface ARCTextbook (Student)
#property (nonatomic) NSInteger studentID;
#property (nonatomic, getter=isUsed) BOOL used; // Used by a student?
#end
ARCTextbook.m
#import "ARCTextbook.h"
#import <objc/runtime.h>
#implementation ARCTextbook
#end
static NSString *kStudentID = #"kStudentID";
static NSString *kUsed = #"kUsed";
#implementation ARCTextbook (Student)
#dynamic studentID;
#dynamic used;
- (void)setStudentID:(NSInteger)aStudentID {
objc_setAssociatedObject(self, (__bridge const void *)(kStudentID), #(aStudentID), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (NSInteger)studentID {
return [objc_getAssociatedObject(self, (__bridge const void *)(kStudentID)) integerValue];
}
- (void)setUsed:(BOOL)aUsed {
objc_setAssociatedObject(self, (__bridge const void *)(kUsed), #(aUsed), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (BOOL)isUsed {
return [objc_getAssociatedObject(self, (__bridge const void *)(kUsed)) boolValue];
}
#end
ViewController.m
#import "ViewController.h"
#import "ARCTextbook.h"
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
ARCTextbook *t = [[ARCTextbook alloc] init];
t.studentID = 2;
t.used = YES;
}
#end
I am attempting to use this JSONModel library in an app I'm building. I've been following this article, but for some reason I keep getting (null) when attempting to parse the json string. I was told that it is because I'm not creating a json instance; but it seems to me I am. Below is the code, can anyone see what I'm missing? I'm attempting to use this web service, with these inputs:
emailAddress: wufpakjack#yahoo.com;
password: test;
companyId: 2579;
scheduleDate: 20140415.
myShiftModel.h
#import "JSONModel.h"
#interface myShiftModel : JSONModel
#property (assign, nonatomic) NSString *shiftName;
#property (assign, nonatomic) NSString *shiftStartTime;
#property (assign, nonatomic) NSString *shiftPosition;
#end
dailyViewModel.h
#import "JSONModel.h"
#import "myShiftModel.h"
#protocol dailyViewModel #end
#interface dailyViewModel : JSONModel
#property (assign, nonatomic) int numAvailableXChanges;
#property (strong, nonatomic) NSString *todaysForecast;
#property (assign, nonatomic) int todaysTemperature;
#property (strong, nonatomic) myShiftModel *workShift;
#end
dailyFeed.h
#import "JSONModel.h"
#import "dailyViewModel.h"
#interface dailyFeed : JSONModel
#property (strong, nonatomic) NSArray <dailyViewModel> *workShifts;
#end
mainViewController.m
#import "mainViewController.h"
#import "JSONModelLib.h"
#import "JSONModel+networking.h"
#import "dailyFeed.h"
#interface mainViewController () {
dailyFeed *feed;
}
#end
#implementation mainViewController
- (void)viewDidAppear:(BOOL)animated {
NSString *email = [[NSString alloc]initWithFormat:#"wufpakjack#yahoo.com"];
NSString *pass = [[NSString alloc]initWithFormat:#"test"];
NSString *compID = [[NSString alloc]initWithFormat:#"2579"];
NSString *date = [[NSString alloc]initWithFormat:#"20140415"];
NSString *urlString = [NSString stringWithFormat:#"http://qa.shiftzen.com/ws/schedutils.asmx/GetDailyView?emailAddress=%#&password=%#&companyId=%#&scheduleDate=%#", email,pass,compID,date];
NSLog(#"%#", urlString);
[JSONHTTPClient getJSONFromURLWithString:urlString
completion:^(NSDictionary *json, JSONModelError *err) {
NSError* error = nil;
feed = [[dailyFeed alloc] initWithDictionary:json error:&error];
NSLog(#"shifts: %#", feed.workShifts);
}];
}
#end
Any guidance would be greatly appreciated.
Warmest regards,
DB
[X-Post from parse.com]
Person is a subclass of PFObject.
Address is also a subclass of PFObject. Address has a #property of type Person.
i.e.
// Person.h
#interface Person : PFObject<PFSubclassing>
#property (retain) NSString *firstName;
#property (retain) NSString *secondName;
+ (NSString *)parseClassName;
#end
// Person.m
#import <Parse/PFObject+Subclass.h>
#implementation PP4MEAddress
#dynamic firstName;
#dynamic firstName;
+ (NSString *)parseClassName {
return #"Person";
}
// Address.h
#interface Address : PFObject<PFSubclassing>
#property (retain) Person *deliverToPerson;
#property (retain) NSString *line1;
#property (retain) NSString *line2;
+ (NSString *)parseClassName;
// Address.m
#import <Parse/PFObject+Subclass.h>
#implementation PP4MEAddress
#dynamic deliverToPerson;
#dynamic line1;
#dynamic line2;
+ (NSString *)parseClassName {
return #"Address";
}
Both subclasses are registered in the App Delegate.
In a method in MyViewController I want to set these as so
e.g.
-(void)myMethod
{
Address *address = [Address object];
address.deliverToPerson.firstName = #"John";
address.deliverToPerson.secondName = #"Smith";
address.line1 = #"123";
address.line2 = #"Main Street";
[address saveInBackground];
}
When this code executes, an entry of Class Address is input into the Data Browser on the Parse.com Web App. However, the only columns are objectId, createdAt, updatedAt and ACL
I imagine this is because, under the hood the Address #property of type Person is not being allocated and initialised.
How do I overcome this?
Do I write a custom setter and getter for
#property (retain) Person *deliverToPerson;
in Address.m ?
If so, I notice that the #property is atomic and thus will I need to write locking code in said setter and getter?
Thank You
I am not familiar with parse.com, but I strongly assume that you have to
allocate the Person object before setting the relationship. Something like
Address *address = [Address object];
address.line1 = #"123";
address.line2 = #"Main Street";
Person *person = [Person object];
person.firstName = #"John";
person.secondName = #"Smith";
address.deliverToPerson = person;
[address saveInBackground];
you have to set your PFobject
like this
PFObject *anotherPlayer = [PFObject objectWithClassName:#"Player"];
[anotherPlayer setObject:#"DataValue" forKey:#"Name"];
I have a basic Core Data model which look like this :
I auto-generated data model files and it's give me something like that :
BSStudent.h
//
// BSStudent.h
//
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
#class BSFormation;
#interface BSStudent : NSManagedObject
#property (nonatomic, retain) NSString * firstname;
#property (nonatomic, retain) NSString * lastname;
#property (nonatomic, retain) NSDate * birthdate;
#property (nonatomic, retain) id thumbnail;
#property (nonatomic, retain) NSSet *formations;
#end
#interface BSStudent (CoreDataGeneratedAccessors)
- (void)addFormationsObject:(BSFormation *)value;
- (void)removeFormationsObject:(BSFormation *)value;
- (void)addFormations:(NSSet *)values;
- (void)removeFormations:(NSSet *)values;
#end
BSStudent.m
//
// BSStudent.m
//
#import "BSStudent.h"
#import "BSFormation.h"
#implementation BSStudent
#dynamic firstname;
#dynamic lastname;
#dynamic birthdate;
#dynamic thumbnail;
#dynamic formations;
#end
I tried to simply save a BSStudent object by doing the following :
BSStudent *newStudent = (BSStudent *)[NSEntityDescription entityForName:kBSStudent inManagedObjectContext:self.managedObjectContext];
newStudent.firstname = firstname;
newStudent.lastname = lastname;
newStudent.birthdate = birthdate;
newStudent.thumbnail = thumbnail;
NSError *error;
if (![self.managedObjectContext save:&error]) {
NSLog(#"Error: %#", [error localizedDescription]);
}
But my app always crash with error : [NSEntityDescription setFirstname:]: unrecognized selector sent to instance 0x1f021e00
Someone figuring out what's happening here ?
One possible explanation is that you are using the wrong string in:
BSStudent *newStudent = (BSStudent *)[NSEntityDescription entityForName:kBSStudent inManagedObjectContext:self.managedObjectContext];
Try and check what newStudent actually is:
BSStudent *newStudent = (BSStudent *)[NSEntityDescription entityForName:kBSStudent inManagedObjectContext:self.managedObjectContext];
NSLog(#"New Student: %#", [newStudent description]);
newStudent.firstname = firstname;
maybe it will clarify things...