Цель C: Хорошая ли практика проверять значения JSON, если вы ожидаете того типа? - PullRequest
0 голосов
/ 01 ноября 2018

В настоящее время я проверяю, является ли значение JSON NSString, а если нет, присваивает свойству строку по умолчанию. Таким образом, я могу предотвратить сбой приложения, если значение JSON равно null, и я могу вернуть объект User с именем и фамилией по умолчанию.

// Пользовательская модель

+ (Email *)getEmailInfoWithDictionary:(id)dict {
  Email *email = [[self alloc] init];
  if ([dict isKindOfClass:[NSDictionary class]]) {
    user.firstname = [NSString checkType:dict[@"firstname"] defaultString:@"John"];
    user.lastname = [NSString checkType:dict[@"lastname"] defaultString:@"Smith"];
  }
}
return user;
}

// Метод категории NSString.

+ (NSString *)checkType:(id)obj defaultString:(NSString *)def {
  if (obj == nil || ![obj isKindOfClass:[NSString class]]) {
    return def;
  }
  return obj;
}

Однако у меня есть пара проблем. Является ли хорошей идеей всегда проверять нулевые значения относительно значений json, чтобы таким образом вы не получили сбоев? Я заметил несколько уроков по Objective C, которые этого не делают. Меня удивляет, не стоит ли мне беспокоиться об этом, и я должен ожидать, что API вернет правильные значения. Мое второе беспокойство - метод, который я использую, хорошая идея или есть лучший способ?

Ответы [ 2 ]

0 голосов
/ 01 ноября 2018

Является ли хорошей идеей всегда проверять нулевые значения относительно значений json, чтобы таким образом вы не получали сбоев?

Заставляет меня задуматься, не стоит ли мне беспокоиться об этом, и я должен ожидать, что API вернет правильные значения.

Да, определенно хорошая идея проверить. Никогда не думайте, что данные, полученные вами от третьих лиц, будут такими, какие вы ожидаете. API меняются. Баги случаются. Защитите код всякий раз, когда вы имеете дело с данными, которые не на 100% под вашим контролем. Лучше показать ошибку пользователю или обработать неожиданные данные каким-нибудь изящным образом, чем аварийное завершение вашего приложения, потому что вы ожидали строку и получили число, или вы получили один словарь вместо массива словаря и т. Д.

Мое второе беспокойство - это метод, который я использую, или есть лучший способ?

Здесь нет хорошего ответа. Каждый случай использования отличается. Как вы обрабатываете плохие данные, зависит от данных и от того, насколько они плохие. Для простого случая, такого как отсутствующее или недействительное имя, предоставление по умолчанию может быть или не быть подходящим. Это зависит от вас и вашего приложения. Может быть лучше пропустить запись или показать ошибку пользователю. Или вы можете выбрать значение по умолчанию для некоторого значения, если это имеет смысл для вашей ситуации.

0 голосов
/ 01 ноября 2018

Я бы сказал, начнем с использования обработки по умолчанию Objective-C nil. В большинстве случаев nil будет делать то, что вы хотите, без сбоев. Напротив, [NSNull null] плохо спроектирован и является постоянной проблемой.

@interface NSObject (MyCasting)
- (NSString *)stringOrNil;
- (NSNumber *)numberOrNil;
- (NSDictionary *)dictionaryOrNil;
- (NSArray *)arrayOrNil;
@end

@implementation NSObject (MyCasting)

- (NSString *)stringOrNil {
    return [self isKindOfClass:NSString.class] ? (NSString *)self : nil;
}

- (NSNumber *)numberOrNil {
    return [self isKindOfClass:NSNumber.class] ? (NSNumber *)self: nil;
}

- (NSDictionary *)dictionaryOrNil {
    return [self isKindOfClass:NSDictionary.class] ? (NSDictionary *)self: nil;
}

- (NSArray *)arrayOrNil {
    return [self isKindOfClass:NSArray.class] ? (NSArray *)self: nil;
}

@end

Это обеспечит вам хороший уровень безопасности, используя nil в качестве значения по умолчанию.

+ (Email *)getEmailInfoWithDictionary:(id)dict {
    Email *email = [[self alloc] init];
    NSDictionary *dictionary = [dict dictionaryOrNil];

    email.firstname = [dictionary[@"firstname"] stringOrNil];
    email.lastname = [dictionary[@"lastname"] stringOrNil];

    return email;
}

Если вам кажется, что вам нужна дополнительная безопасность значений объекта по умолчанию, вы можете использовать оператор ?:.

email.firstname = [dictionary[@"firstname"] stringOrNil] ?: "";
email.lastname = [dictionary[@"lastname"] stringOrNil] ?: "";
...