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.