Where's my mistake here in subclassing GDataEntryBase and adding extensions?

50 views
Skip to first unread message

Morgan Aldridge

unread,
Nov 19, 2012, 4:55:47 PM11/19/12
to gdata-objec...@googlegroups.com
I've built the Objective-C Client Library and have it linking and working with my application (incl. GTMOAuth2) and can pull data back. I need to work with the Provisioning API (still XML-only) so am building out the additions I need within my own application. I think I have finally figured out how all of this works and I'm _very_ close to reading custom elements, but I'm missing something.

I've subclassed GDataServiceGoogle, GDataEntryBase, and GDataFeedBase and am getting correct data back. I'm starting with a simple & straightforward element type: quota. So, I've added the following value construct:

@interface GDataQuotaProperty : GDataValueConstruct <GDataExtension>
+ (NSString *)extensionElementURI;
+ (NSString *)extensionElementPrefix;
+ (NSString *)extensionElementLocalName;
@end

@implementation GDataQuotaProperty
+ (NSString *)extensionElementURI       { return kGDataNamespaceGApps; }
+ (NSString *)extensionElementPrefix    { return kGDataNamespaceGAppsPrefix; }
+ (NSString *)extensionElementLocalName { return @"quota"; }
@end

And I've added the following methods to the GDataEntryBase subclass:

- (GDataQuotaProperty *)quota;

- (void)setQuota:(GDataQuotaProperty *)val;


Implemented as follows:


- (GDataQuotaProperty *)quota {

    return [self objectForExtensionClass:[GDataQuotaProperty class]];

}


- (void)setQuota:(GDataQuotaProperty *)val {

    [self setObject:val forExtensionClass:[GDataQuotaProperty class]];

}


As documented in GDataObject.h (and I've been working off of GDataServiceGoogleCalendar, GDataEntryCalendar, and GDataFeedCalendar as a reference implementation), in the GDataBaseEntry subclass I've addExtensionDeclarations as follows:


- (void)addExtensionDeclarations {

    [super addExtensionDeclarations];

    

    Class entryClass = [self class];

    

    // User extensions

    [self addExtensionDeclarationForParentClass:entryClass

                                   childClasses:[GDataQuotaProperty class], nil];

}


However, when I try to call the quota method as follows in my callback:


    GDataTextConstruct *titleTextConstruct = [user title];

    NSString *title = [titleTextConstruct stringValue];

    GDataQuotaProperty *quotaConstruct = [user quota];

    NSString *quota = [quotaConstruct stringValue];


I get an exception and this error:


    2012-11-19 12:42:22.667 Google Apps Open Directory Sync[47679:903] -[GDataEntryBase quota]: unrecognized selector sent to instance 0x2836d0


In the above example I do get the user's name back correctly without error. So, what am I missing here?


As mentioned, I've been comparing with the Service/Feed/Entry implementation for Calendar (specifically the accessLevel & color elements and methods) and am just not seeing what I'm missing.


Thanks in advance for any assistance you can provide.

Greg Robbins

unread,
Nov 20, 2012, 3:44:17 AM11/20/12
to gdata-objec...@googlegroups.com
The error indicates your service is instantiating the base class, GDataEntryBase, since it has no way to know what subclass to use for the XML returned by the server for the entry.

Entry classes can specify the "kind" that identifies the class in the XML. For example, some APIs use category elements in the XML:

@implementation GDataEntryDrawingDoc
+ (void)load { [self registerEntryClass]; }
+ (NSString *)standardEntryKind { return @"http://schemas.google.com/docs/2007#drawing"; }
@end

and some use kind attributes:

@implementation GDataEntryCalendar
+ (void)load { [self registerEntryClass]; }
+ (NSString *)standardKindAttributeValue { return @"calendar#calendar"; }
@end

If the library cannot match the kind string from the XML to a registered entry class, then the app must use a service method that specifies the class of entry to create, such as the method fetchEntryWithURL:entryClass:completionHandler:

Morgan Aldridge

unread,
Nov 20, 2012, 2:08:17 PM11/20/12
to gdata-objec...@googlegroups.com
On Tuesday, November 20, 2012 3:44:49 AM UTC-5, Greg Robbins wrote:
 
Entry classes can specify the "kind" that identifies the class in the XML. For example, some APIs use category elements in the XML:

@implementation GDataEntryDrawingDoc
+ (void)load { [self registerEntryClass]; }
+ (NSString *)standardEntryKind { return @"http://schemas.google.com/docs/2007#drawing"; }
@end

and some use kind attributes:

@implementation GDataEntryCalendar
+ (void)load { [self registerEntryClass]; }
+ (NSString *)standardKindAttributeValue { return @"calendar#calendar"; }
@end

Aha! I had implemented `classForEntries` in my GDataFeedBase subclass, but I had missed `standardEntryKind`. Once I implemented that (returning the full schema URL), it was able to correctly use my subclass and so my selector could be called.

Thanks!
Reply all
Reply to author
Forward
0 new messages