how to convert Arabic numbers to English numbers in swift?
This will replace any arabic number to english
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
if textField.keyboardType == .numberPad && string != "" {
let numberStr: String = string
let formatter: NumberFormatter = NumberFormatter()
formatter.locale = Locale(identifier: "EN")
if let final = formatter.number(from: numberStr) {
textField.text = "\(textField.text ?? "")\(final)"
}
return false
}
return true
}
dont forget setting the delegate:
yourTextField.delegat = self
Swift-5 solution for all non-Latin string occurrences.
extension String {
var containsNonEnglishNumbers: Bool {
return !isEmpty && range(of: "[^0-9]", options: .regularExpression) == nil
}
var english: String {
return self.applyingTransform(StringTransform.toLatin, reverse: false) ?? self
}
}
Usage -
textField.addTarget(self, action: #selector(didChangeText(field:)), for: .editingChanged)
@objc func didChangeText(field: UITextField) {
if ((field.text?.containsNonEnglishNumbers) != nil) {
field.text = field.text?.english
}
}
You need to convert the arabic number string to english first and then do the calculation part.
let numberStr: String = "٨٦٩١٢٨٨١"
let formatter: NumberFormatter = NumberFormatter()
formatter.locale = NSLocale(localeIdentifier: "EN") as Locale!
let final = formatter.number(from: numberStr)
let doubleNumber = Double(final!)
print("\(doubleNumber)")
From Any language, To Any Language
You can convert digits from ANY language to ANY other language in a single line code like:
"12345".convertedDigitsToLocale(Locale(identifier: "FA")) /* ۱۲۳۴۵ */
"۱۲۳۴۵".convertedDigitsToLocale(Locale(identifier: "EN")) /* 12345 */
with the following extension:
extension String {
private static let formatter = NumberFormatter()
func clippingCharacters(in characterSet: CharacterSet) -> String {
components(separatedBy: characterSet).joined()
}
func convertedDigitsToLocale(_ locale: Locale = .current) -> String {
let digits = Set(clippingCharacters(in: CharacterSet.decimalDigits.inverted))
guard !digits.isEmpty else { return self }
Self.formatter.locale = locale
let maps: [(original: String, converted: String)] = digits.map {
let original = String($0)
let digit = Self.formatter.number(from: original)!
let localized = Self.formatter.string(from: digit)!
return (original, localized)
}
return maps.reduce(self) { converted, map in
converted.replacingOccurrences(of: map.original, with: map.converted)
}
}
}
The Swift Package
You can find this extension and some more useful extensions with their unit test Here on the github and use them easily as a Swift package.