I am currently making an Objective-C library for an API. To easily manage the data, I have created some classes acting as models.
For example, I have an Account class which contains all the data concerning one specific account. I would like to make it easy to init this class and I thought about something like this :
@interface Account : NSObject
@property (nonatomic, readonly) NSUInteger accountID;
@property (nonatomic, readonly) NSString *username;
// Other properties...
+ (instancetype)accountWithUsername:(NSString *)username success:(void (^)(Account *))success failure:(void (^)(NSError *))failure;
- (instancetype)initWithUsername:(NSString *)username success:(void (^)(Account *))success failure:(void (^)(NSError *))failure;
@end
@implementation Account
+ (instancetype)accountWithUsername:(NSString *)username success:(void (^)(Account *))success failure:(void (^)(NSError *))failure
{
return [[JPImgurAccount alloc] initWithUsername:username success:success failure:failure];
}
- (instancetype)initWithUsername:(NSString *)username success:(void (^)(Account *))success failure:(void (^)(NSError *))failure
{
self = [super init];
// Launch asynchronous requests, the callback will be called when it's finished
return self; // Returning an empty object until the asynchronous request is finished
}
@end
However, returning an empty object through the init method bothers me a bit and I ask myself if it's a really good idea but I can't find why it could be risky.
So I'm asking you: can I use this structure? If not, why? Should I go in classic way with a single init method coupled to a loadWithUsername:(NSString *)username success:(void (^)(JPImgurAccount *))success failure:(void (^)(NSError *))failure method?
Thanks.
I don't think your approach is good practice. As a user of the API, when I see a method that starts with "init" I expect the returned object to be ready to use immediately. It looks like you need to use the Factory design pattern. Create an AccountFactory class with this method:
+ (void)createAccountWithUsername:(NSString*)username success:(void (^)(Account *))success failure:(void (^)(NSError *))failure;
Notice that it returns void, so the user understand that the object is only available once the request has finished successfully. Also, the user understand that he's not expected to create an instance of Account directly. That's the approach I would use.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With