NBPhoneNumberUtil校验比利时、马来西亚手机号返回无效排查
问题背景
iOS开发场景下,使用NBPhoneNumberUtil库对两个已知有效的国际手机号做合法性校验时,号码始终被判定为无效,涉及号码如下:
- 比利时号码:
+32 469 12 59 50 - 马来西亚号码:
+60 1172249141
使用的校验代码如下:
let phoneNumber = // 传入去除所有空格的比利时或马来西亚手机号 let countryCode = // 传入对应国家区域编码,取值为BE或MY let phoneUtil = NBPhoneNumberUtil() do { let parsedPhoneNumber: NBPhoneNumber = try phoneUtil.parse(phoneNumber, defaultRegion: countryCode) var isValid: Bool = phoneUtil.isValidNumber(forRegion: parsedPhoneNumber, regionCode: countryCode) if !isValid { isValid = phoneUtil.isValidNumber(parsedPhoneNumber) && phoneUtil.isPossibleNumber(parsedPhoneNumber) } return isValid } catch let error as NSError { print(error.localizedDescription) return false }
可能的故障诱因
- 号码预处理逻辑错误
代码中仅去除了号码中的空格,但未处理两类异常字符:一是从文本、输入框复制号码时可能携带的零宽空格、换行符、不可见控制符,这类字符会导致号段解析错位;二是部分预处理逻辑会误删号码开头的+前缀,一旦+丢失,库会将开头的国家码(32/60)识别为本地号码的号段部分,按照传入的区域本地号码规则校验,必然判定无效。 - 校验方法使用逻辑错误
isValidNumber(forRegion:regionCode:)的作用是校验号码是否归属指定区域,仅当明确需要校验号码和传入区域的匹配关系时才需要调用。如果传入的号码已经携带+开头的完整国家码,直接调用isValidNumber(parsedPhoneNumber)即可完成有效性校验,不需要额外叠加isPossibleNumber判断——该方法仅做号码长度的粗略校验,不校验号段合法性,冗余调用不会提升校验准确率,反而可能在版本不匹配时引入误判。另外如果传参时号码和countryCode不匹配(比如传入比利时号码时countryCode误传为MY),区域校验方法会直接返回false。 - 库内置元数据版本过旧
NBPhoneNumberUtil的校验规则完全依赖内置的全球电话号码元数据,马来西亚近年新增了11开头的移动号段(本次涉及的马来西亚号码+60 1172249141就属于该类新号段),比利时也在近年调整过移动号段的分配规则,如果集成库之后从未更新过内置的元数据文件,新发放的合法号段会被旧规则判定为无效。 - 解析参数传值错误
当传入号码不带+前缀时,parse方法会完全依赖defaultRegion参数判断号码所属国家,如果传参时出现号码和countryCode错位(比如比利时号码对应传了MY、马来西亚号码对应传了BE),库会按照错误区域的本地号码规则解析,自然返回无效结果。
内容的提问来源于stack exchange,提问作者Lance Samaria
相关产品推荐
相关产品推荐

