我就职过的公司,都出现过不止一次因为后台实际数据类型和文档不一致导致的程序线上崩溃问题。原则上即使服务器离线了,app 都不应该直接闪退,所以 app 应当具有对服务器异常情况进行处理的能力。使用 ValueX 可以有效避免后台返回数据类型异常导致的程序崩溃。
@"<null>"
值假如我得到一个值 NSString *obj
,实际上可能是 NSNull ,可能是 NSNumber ,可能是空数据的 @"<null>"
或者 @"(null)"
等各种表述。那么我需要确保 NSSafeString(obj)
的结果一定是 NSString 类型的值,如果是空数据,就应该是 nil。如果是 @123
这样的数字,那么应该得到 @"123"
这样的字符串。
如果是 json 数据,它可能以 NSData 类型存在,可能以 Json 字符串 NSString 类型存在,可能以 NSArray 或者 NSDictionary 对象形式存在。我需要的是我要什么类型就能直接获取。例如 ValueX(obj).stringValue
就得到这个数据的 Json 字符串,ValueX(obj).dictionaryValue
就得到这个数据的字典对象。
所以这个库就分为两部份工作,一部分是将实际类型与定义类型一致化;第二部分是将已知类型转换成它能够转换的其他类型。
针对 ObjC 中常用的 6 种数据类型 NSString、NSNumber、NSData、NSArray、NSSet、NSDictionary 一一进行判断,写出6个函数:
FOUNDATION_EXTERN NSString * __nullable NSSafeString(id obj); |
确保从这些函数出来的值是与定义类型一致的值。
即使拿到的值与定义类型一致,有时候我们要用的可能又是其他类型。
FOUNDATION_EXTERN VXObject *ValueX(id <VXConvertable>obj); |
确保 VXObject 类型可以通过点语法直接得到原数据所能够转换的其他类型。VXObject 是一种中间类型,针对上述 6 种数据类型,每一种可以转换成其他哪些类型进行一一判断。
其中,NSNumber 只可以转换为 NSString、NSData,遵循 VXConvertable 协议。表示数字的 NSString,可以转换成 NSNumber,表示 Json 的字符串可以转换成对应的 NSArray 或者 NSDictionary,遵守 VXConvertableData 协议。反过来 NSArray、NSSet 或者 NSDictionary 则遵守 VXConvertableObject 协议。
@interface NSString (VXObject) <VXConvertableData> |
它们的协议内容是:
@protocol VXConvertable <NSObject> |
就按照这个思路进行开发,实现的代码就不再赘述了。