116 lines
4.1 KiB
Swift
116 lines
4.1 KiB
Swift
//
|
|
// Copyright 2021 Signal Messenger, LLC
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
//
|
|
|
|
import Foundation
|
|
import SignalCoreKit
|
|
import SignalServiceKit
|
|
|
|
public struct RegistrationCountryState: Equatable, Dependencies {
|
|
// e.g. France
|
|
public let countryName: String
|
|
// e.g. +33
|
|
public let callingCode: String
|
|
// e.g. FR
|
|
public let countryCode: String
|
|
|
|
public init(countryName: String, callingCode: String, countryCode: String) {
|
|
self.countryName = countryName
|
|
self.callingCode = callingCode
|
|
self.countryCode = countryCode
|
|
}
|
|
|
|
public static var defaultValue: RegistrationCountryState {
|
|
AssertIsOnMainThread()
|
|
|
|
let countryCode: String = PhoneNumberUtil.defaultCountryCode()
|
|
let callingCodeNumber: NSNumber = phoneNumberUtil.getCallingCode(forRegion: countryCode)
|
|
let callingCode = "\(COUNTRY_CODE_PREFIX)\(callingCodeNumber)"
|
|
let countryName = PhoneNumberUtil.countryName(fromCountryCode: countryCode)
|
|
|
|
return RegistrationCountryState(countryName: countryName, callingCode: callingCode, countryCode: countryCode)
|
|
}
|
|
|
|
// MARK: -
|
|
|
|
public static func countryState(forE164 e164: String) -> RegistrationCountryState? {
|
|
for countryState in allCountryStates {
|
|
if e164.hasPrefix(countryState.callingCode) {
|
|
return countryState
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
public static var allCountryStates: [RegistrationCountryState] {
|
|
RegistrationCountryState.buildCountryStates(searchText: nil)
|
|
}
|
|
|
|
public static func buildCountryStates(searchText: String?) -> [RegistrationCountryState] {
|
|
let searchText = searchText?.strippedOrNil
|
|
let countryCodes: [String] = NSObject.phoneNumberUtil.countryCodes(forSearchTerm: searchText)
|
|
return RegistrationCountryState.buildCountryStates(countryCodes: countryCodes)
|
|
}
|
|
|
|
public static func buildCountryStates(countryCodes: [String]) -> [RegistrationCountryState] {
|
|
return countryCodes.compactMap { (countryCode: String) -> RegistrationCountryState? in
|
|
guard let countryCode = countryCode.strippedOrNil else {
|
|
owsFailDebug("Invalid countryCode.")
|
|
return nil
|
|
}
|
|
guard let callingCode = NSObject.phoneNumberUtil.callingCode(fromCountryCode: countryCode)?.strippedOrNil else {
|
|
owsFailDebug("Invalid callingCode.")
|
|
return nil
|
|
}
|
|
guard let countryName = PhoneNumberUtil.countryName(fromCountryCode: countryCode).strippedOrNil else {
|
|
owsFailDebug("Invalid countryName.")
|
|
return nil
|
|
}
|
|
guard callingCode != "+0" else {
|
|
owsFailDebug("Invalid callingCode.")
|
|
return nil
|
|
}
|
|
|
|
return RegistrationCountryState(
|
|
countryName: countryName,
|
|
callingCode: callingCode,
|
|
countryCode: countryCode
|
|
)
|
|
}
|
|
}
|
|
}
|
|
|
|
// MARK: -
|
|
|
|
public struct RegistrationPhoneNumber {
|
|
public let countryState: RegistrationCountryState
|
|
public let nationalNumber: String
|
|
public let e164: E164?
|
|
|
|
public init(countryState: RegistrationCountryState, nationalNumber: String) {
|
|
self.countryState = countryState
|
|
self.nationalNumber = nationalNumber
|
|
self.e164 = E164("\(countryState.callingCode)\(nationalNumber)")
|
|
}
|
|
}
|
|
|
|
public class RegistrationPhoneNumberParser {
|
|
private let phoneNumberUtil: PhoneNumberUtil
|
|
|
|
public init(phoneNumberUtil: PhoneNumberUtil) {
|
|
self.phoneNumberUtil = phoneNumberUtil
|
|
}
|
|
|
|
public func parseE164(_ phoneNumber: E164) -> RegistrationPhoneNumber? {
|
|
guard
|
|
let countryState = RegistrationCountryState.countryState(forE164: phoneNumber.stringValue),
|
|
let phoneNumber = phoneNumberUtil.parseE164(phoneNumber)
|
|
else {
|
|
return nil
|
|
}
|
|
let nationalNumber = phoneNumberUtil.nationalNumber(for: phoneNumber)
|
|
return RegistrationPhoneNumber(countryState: countryState, nationalNumber: nationalNumber)
|
|
}
|
|
}
|