I have a singleton networking class as well as a singleton object that needs to persist throughout my app. The singleton is initialized based on data retrieved from a web call, so right now my code works, and I have the following in my singleton networking class:
- (void)initializeObjectWithSuccess:(void (^)(BOOL))success
failure:(void (^)(NSError *error))failure {
[self.HTTPClient postPath:[NSString stringWithFormat:@"users/%@/", [CPUser sharedUser].name parameters:[self createParameters] success:^(AFHTTPRequestOperation *operation, id responseObject) {
id json = [NSJSONSerialization JSONObjectWithData:responseObject
options:NSJSONReadingAllowFragments
error:nil];
[[CPList sharedList] setIdentifier:json[@"id"]];
[[CPList sharedList] setImages:json[@"images"]];
if (success) {
success(YES);
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
failure(error);
}];
}
I don't know how to initialize all the properties I need on my singleton CPList without setting them within this method, however I know that this is not proper encapsulation because the CPRequestManager Class should know nothing about the CPList Class
If your issue is that you don't want this class to know the name of CPList
and the detail that it's a singleton and that it can access it with +[CPList sharedInstance]
then you can just pass in an object that conforms to a protocol. This basically moves the knowledge of the singleton somewhere else
- (void)initializeObjectWithList:(id<CPList>)list
success:(void (^)(BOOL))success
failure:(void (^)(NSError *error))failure;
{
[self.HTTPClient postPath:[NSString stringWithFormat:@"users/%@/", [CPUser sharedUser].name parameters:[self createParameters] success:^(AFHTTPRequestOperation *operation, id responseObject) {
id json = [NSJSONSerialization JSONObjectWithData:responseObject
options:NSJSONReadingAllowFragments
error:nil];
[list setIdentifier:json[@"id"]];
[list setImages:json[@"images"]];
if (success) {
success(YES);
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
failure(error);
}];
}
Or you could remove all knowledge that there is a "list" and just have this method return the actual data and then the caller can set it on the list
- (void)initializeObjectWithSuccess:(void (^)(NSString *ID, NSArray *images))success
failure:(void (^)(NSError *error))failure;
{
[self.HTTPClient postPath:[NSString stringWithFormat:@"users/%@/", [CPUser sharedUser].name parameters:[self createParameters] success:^(AFHTTPRequestOperation *operation, id responseObject) {
id json = [NSJSONSerialization JSONObjectWithData:responseObject
options:NSJSONReadingAllowFragments
error:nil];
if (success) {
success(json[@"id"], json[@"images"]);
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
failure(error);
}];
}
Without any further context it's hard to suggest structural changes but here's two potential refactoring that might get you thinking about what you coudld do