Commit 34374ba6 by Dima Bart

Adjust BUYAccountCredentials interface to improve discoverability.

- add string constants for valid credential item keys
- add factory methods to eliminate the need to using keys explicitly
- simplify implementation and validation logic
parent 922d7a64
......@@ -154,9 +154,11 @@
NSData *data = [NSJSONSerialization dataWithJSONObject:credentials.JSONRepresentation options:0 error:nil];
return [self putRequestForURL:components.URL body:data completionHandler:^(NSDictionary *json, NSURLResponse *response, NSError *error) {
if (json && !error) {
BUYAccountCredentialItem *emailItem = [BUYAccountCredentialItem itemWithKey:@"email" value:json[@"customer"][@"email"]];
credentials[@"email"] = emailItem;
NSString *email = json[@"customer"][@"email"];
if (email && !error) {
BUYAccountCredentialItem *emailItem = [BUYAccountCredentialItem itemEmailWithValue:email];
[credentials setCredentialItem:emailItem];
[self loginCustomerWithCredentials:credentials callback:block];
}
else {
......@@ -171,9 +173,11 @@
NSData *data = [NSJSONSerialization dataWithJSONObject:credentials.JSONRepresentation options:0 error:nil];
return [self putRequestForURL:components.URL body:data completionHandler:^(NSDictionary *json, NSURLResponse *response, NSError *error) {
if (json && !error) {
BUYAccountCredentialItem *emailItem = [BUYAccountCredentialItem itemWithKey:@"email" value:json[@"customer"][@"email"]];
credentials[@"email"] = emailItem;
NSString *email = json[@"customer"][@"email"];
if (email && !error) {
BUYAccountCredentialItem *emailItem = [BUYAccountCredentialItem itemEmailWithValue:email];
[credentials setCredentialItem:emailItem];
[self loginCustomerWithCredentials:credentials callback:block];
}
else {
......
......@@ -25,40 +25,53 @@
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
/**
* Intended for storing a collection of credential items representing individual values
*/
extern NSString * const BUYAccountFirstNameKey;
extern NSString * const BUYAccountLastNameKey;
extern NSString * const BUYAccountEmailKey;
extern NSString * const BUYAccountPasswordKey;
extern NSString * const BUYAccountPasswordConfirmationKey;
@class BUYAccountCredentialItem;
@interface BUYAccountCredentials : NSObject
NS_ASSUME_NONNULL_BEGIN
/**
* Encapsulates user's credentials represented by BUYAccountCredentialItem
* objects.
*/
@interface BUYAccountCredentials : NSObject
+ (BUYAccountCredentials *)credentialsWithItems:(NSArray<BUYAccountCredentialItem *> *)items;
+ (BUYAccountCredentials *)credentialsWithItemKeys:(NSArray<NSString *> *)keys;
@property (nonatomic, assign, readonly, getter=isValid) BOOL valid;
@property (nonatomic, strong, readonly) NSDictionary *JSONRepresentation;
@property (readonly) NSDictionary *JSONRepresentation;
@property (nonatomic, readonly, getter=isValid) BOOL valid;
+ (BUYAccountCredentials *)credentialsWithItems:(nullable NSArray<BUYAccountCredentialItem *> *)items;
- (instancetype)initWithItems:(nullable NSArray<BUYAccountCredentialItem *> *)items;
- (BUYAccountCredentialItem *)objectForKeyedSubscript:(NSString *)key;
- (void)setObject:(BUYAccountCredentialItem *)obj forKeyedSubscript:(NSString *)key;
- (void)setCredentialItems:(NSArray<BUYAccountCredentialItem *> *)items;
- (void)setCredentialItem:(BUYAccountCredentialItem *)item;
@end
/**
* Represents a key and KVC-validatable value
* Represents a single for user's credentials such as
* email or password.
*/
@interface BUYAccountCredentialItem : NSObject
+ (instancetype)itemWithKey:(NSString *)key value:(NSString *)value;
@property (nonatomic, assign, readonly, getter=isValid) BOOL valid;
@property (nonatomic, strong, readonly) NSString *key;
@property (nonatomic, strong, readonly) NSString *value;
@property (nonatomic, getter=isValid) BOOL valid;
@property (nonatomic, strong) NSString *key;
@property (nonatomic, strong) NSString *value;
+ (instancetype)itemEmailWithValue:(NSString *)value;
+ (instancetype)itemFirstNameWithValue:(NSString *)value;
+ (instancetype)itemLastNameWithValue:(NSString *)value;
+ (instancetype)itemPasswordWithValue:(NSString *)value;
+ (instancetype)itemPasswordConfirmationWithValue:(NSString *)value;
NS_ASSUME_NONNULL_END
+ (instancetype)itemWithKey:(NSString *)key value:(NSString *)value;
- (instancetype)initWithKey:(NSString *)key value:(NSString *)value;
@end
NS_ASSUME_NONNULL_END
\ No newline at end of file
......@@ -26,94 +26,123 @@
#import "BUYAccountCredentials.h"
@class BUYAccountCredentialItem;
NSString * const BUYAccountFirstNameKey = @"first_name";
NSString * const BUYAccountLastNameKey = @"last_name";
NSString * const BUYAccountEmailKey = @"email";
NSString * const BUYAccountPasswordKey = @"password";
NSString * const BUYAccountPasswordConfirmationKey = @"password_confirmation";
#pragma mark - BUYAccountCredentials -
@interface BUYAccountCredentials()
@property (strong, nonatomic) NSMutableDictionary<NSString *, BUYAccountCredentialItem *> *items;
@end
@implementation BUYAccountCredentials
+ (BUYAccountCredentials *)credentialsWithItems:(NSArray<BUYAccountCredentialItem *> *)items
{
BUYAccountCredentials *credentials = [BUYAccountCredentials new];
NSMutableDictionary *keyedItems = [NSMutableDictionary dictionary];
for (BUYAccountCredentialItem *item in items) {
keyedItems[item.key] = item;
return [[BUYAccountCredentials alloc] initWithItems:items];
}
- (instancetype)initWithItems:(NSArray<BUYAccountCredentialItem *> *)items
{
self = [super init];
if (self) {
_items = [NSMutableDictionary new];
if (items.count > 0) {
[self setCredentialItems:items];
}
}
credentials.items = keyedItems;
return credentials;
return self;
}
+ (BUYAccountCredentials *)credentialsWithItemKeys:(NSArray<NSString *> *)keys
#pragma mark - Accessors -
- (BOOL)isValid
{
NSMutableArray *items = [NSMutableArray array];
for (NSString *key in keys) {
BUYAccountCredentialItem *item = [BUYAccountCredentialItem itemWithKey:key value:@""];
[items addObject:item];
__block BOOL valid = YES;
[self.items enumerateKeysAndObjectsUsingBlock:^(NSString *key, BUYAccountCredentialItem *item, BOOL * _Nonnull stop) {
if (!item.isValid) {
valid = NO;
*stop = YES;
}
}];
return valid;
}
- (void)setCredentialItems:(NSArray<BUYAccountCredentialItem *> *)items
{
NSAssert(items, @"BUYAccountCredentialItem array cannot be nil.");
for (BUYAccountCredentialItem *item in items) {
[self setCredentialItem:item];
}
return [BUYAccountCredentials credentialsWithItems:items];
}
- (void)setCredentialItem:(BUYAccountCredentialItem *)item
{
NSAssert(item, @"BUYAccountCredentialItem cannot be nil.");
self.items[item.key] = item;
}
#pragma mark - Serialization -
- (NSDictionary *)JSONRepresentation
{
__block NSMutableDictionary *customer = [NSMutableDictionary dictionary];
[self.items enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, BUYAccountCredentialItem * _Nonnull obj, BOOL * _Nonnull stop) {
[self.items enumerateKeysAndObjectsUsingBlock:^(NSString *key, BUYAccountCredentialItem *obj, BOOL *stop) {
customer[key] = obj.value;
}];
return @{ @"customer": customer };
}
- (BOOL)validateValue:(inout id _Nullable __autoreleasing *)ioValue forKey:(NSString *)inKey error:(out NSError * _Nullable __autoreleasing *)outError
@end
#pragma mark - BUYAccountCredentialItem -
@implementation BUYAccountCredentialItem
#pragma mark - Init -
+ (instancetype)itemEmailWithValue:(NSString *)value
{
return [self.items[inKey] validateValue:ioValue forKey:inKey error:outError];
return [[BUYAccountCredentialItem alloc] initWithKey:BUYAccountEmailKey value:value];
}
- (BUYAccountCredentialItem *)objectForKeyedSubscript:(NSString *)key
+ (instancetype)itemFirstNameWithValue:(NSString *)value
{
return self.items[key];
return [[BUYAccountCredentialItem alloc] initWithKey:BUYAccountFirstNameKey value:value];
}
- (void)setObject:(BUYAccountCredentialItem *)obj forKeyedSubscript:(NSString *)key
+ (instancetype)itemLastNameWithValue:(NSString *)value
{
self.items[key] = obj;
return [[BUYAccountCredentialItem alloc] initWithKey:BUYAccountLastNameKey value:value];
}
- (BOOL)validationForKey:(NSString *)key
+ (instancetype)itemPasswordWithValue:(NSString *)value
{
return [self.items[key] isValid];
return [[BUYAccountCredentialItem alloc] initWithKey:BUYAccountPasswordKey value:value];
}
- (BOOL)isValid
+ (instancetype)itemPasswordConfirmationWithValue:(NSString *)value
{
__block BOOL valid = YES;
[self.items enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, BUYAccountCredentialItem * _Nonnull obj, BOOL * _Nonnull stop) {
valid = valid && [obj isValid];
}];
return valid;
return [[BUYAccountCredentialItem alloc] initWithKey:BUYAccountPasswordConfirmationKey value:value];
}
@end
@implementation BUYAccountCredentialItem
+ (instancetype)itemWithKey:(NSString *)key value:(NSString *)value
{
BUYAccountCredentialItem *item = [BUYAccountCredentialItem new];
item.key = key;
item.value = value;
return item;
return [[BUYAccountCredentialItem alloc] initWithKey:key value:value];
}
- (NSString *)value
- (instancetype)initWithKey:(NSString *)key value:(NSString *)value
{
return _value ?: @"";
}
self = [super init];
if (self) {
NSAssert(value, @"Cannot initialize BUYAccountCredentialItem with nil value.");
- (BOOL)validateValue:(inout id _Nullable __autoreleasing *)ioValue forKey:(NSString *)inKey error:(out NSError * _Nullable __autoreleasing *)outError
{
self.value = *ioValue;
self.valid = self.value.length > 0;
return [self isValid];
_key = key;
_value = value;
_valid = value.length > 0;
}
return self;
}
@end
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment