If I encode a string like this:
var escapedString = originalString.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)
it doesn't escape the slashes /.
I've searched and found this Objective C code:
NSString *encodedString = (NSString *)CFURLCreateStringByAddingPercentEscapes(
NULL,
(CFStringRef)unencodedString,
NULL,
(CFStringRef)#"!*'();:#&=+$,/?%#[]",
kCFStringEncodingUTF8 );
Is there an easier way to encode an URL and if not, how do I write this in Swift?
Swift 3
In Swift 3 there is addingPercentEncoding
let originalString = "test/test"
let escapedString = originalString.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)
print(escapedString!)
Output:
test%2Ftest
Swift 1
In iOS 7 and above there is stringByAddingPercentEncodingWithAllowedCharacters
var originalString = "test/test"
var escapedString = originalString.stringByAddingPercentEncodingWithAllowedCharacters(.URLHostAllowedCharacterSet())
println("escapedString: \(escapedString)")
Output:
test%2Ftest
The following are useful (inverted) character sets:
URLFragmentAllowedCharacterSet "#%<>[\]^`{|}
URLHostAllowedCharacterSet "#%/<>?#\^`{|}
URLPasswordAllowedCharacterSet "#%/:<>?#[\]^`{|}
URLPathAllowedCharacterSet "#%;<>?[\]^`{|}
URLQueryAllowedCharacterSet "#%<>[\]^`{|}
URLUserAllowedCharacterSet "#%/:<>?#[\]^`
If you want a different set of characters to be escaped create a set:
Example with added "=" character:
var originalString = "test/test=42"
var customAllowedSet = NSCharacterSet(charactersInString:"=\"#%/<>?#\\^`{|}").invertedSet
var escapedString = originalString.stringByAddingPercentEncodingWithAllowedCharacters(customAllowedSet)
println("escapedString: \(escapedString)")
Output:
test%2Ftest%3D42
Example to verify ascii characters not in the set:
func printCharactersInSet(set: NSCharacterSet) {
var characters = ""
let iSet = set.invertedSet
for i: UInt32 in 32..<127 {
let c = Character(UnicodeScalar(i))
if iSet.longCharacterIsMember(i) {
characters = characters + String(c)
}
}
print("characters not in set: \'\(characters)\'")
}
You can use URLComponents to avoid having to manually percent encode your query string:
let scheme = "https"
let host = "www.google.com"
let path = "/search"
let queryItem = URLQueryItem(name: "q", value: "Formula One")
var urlComponents = URLComponents()
urlComponents.scheme = scheme
urlComponents.host = host
urlComponents.path = path
urlComponents.queryItems = [queryItem]
if let url = urlComponents.url {
print(url) // "https://www.google.com/search?q=Formula%20One"
}
extension URLComponents {
init(scheme: String = "https",
host: String = "www.google.com",
path: String = "/search",
queryItems: [URLQueryItem]) {
self.init()
self.scheme = scheme
self.host = host
self.path = path
self.queryItems = queryItems
}
}
let query = "Formula One"
if let url = URLComponents(queryItems: [URLQueryItem(name: "q", value: query)]).url {
print(url) // https://www.google.com/search?q=Formula%20One
}
Swift 4 & 5
To encode a parameter in URL I find using .alphanumerics character set the easiest option:
let urlEncoded = value.addingPercentEncoding(withAllowedCharacters: .alphanumerics)
let url = "http://www.example.com/?name=\(urlEncoded!)"
Using any of the standard Character Sets for URL Encoding (like .urlQueryAllowed or .urlHostAllowed) won't work, because they do not exclude = or & characters.
Note that by using .alphanumerics it will encode some characters that do not need to be encoded (like -, ., _ or ~ -– see 2.3. Unreserved characters in RFC 3986). I find using .alphanumerics simpler than constructing a custom character set and do not mind some additional characters to be encoded. If that bothers you, construct a custom character set as is described in How to percent encode a URL String, like for example:
// Store allowed character set for reuse (computed lazily).
private let urlAllowed: CharacterSet =
.alphanumerics.union(.init(charactersIn: "-._~")) // as per RFC 3986
extension String {
var urlEncoded: String? {
return addingPercentEncoding(withAllowedCharacters: urlAllowed)
}
}
let url = "http://www.example.com/?name=\(value.urlEncoded!)"
Warning: The urlEncoded parameter is force unwrapped. For invalid unicode string it might crash. See Why is the return value of String.addingPercentEncoding() optional?. Instead of force unwrapping urlEncoded! you can use urlEncoded ?? "" or if let urlEncoded = urlEncoded { ... }.
Swift 5:
extension String {
var urlEncoded: String? {
let allowedCharacterSet = CharacterSet.alphanumerics.union(CharacterSet(charactersIn: "~-_."))
return self.addingPercentEncoding(withAllowedCharacters: allowedCharacterSet)
}
}
print("\u{48}ello\u{9}world\u{7}\u{0}".urlEncoded!) // prints Hello%09world%07%00
print("The string ü#foo-bar".urlEncoded!) // prints The%20string%20%C3%BC%40foo-bar
Swift 3:
let originalString = "http://www.ihtc.cc?name=htc&title=iOS开发工程师"
1. encodingQuery:
let escapedString = originalString.addingPercentEncoding(withAllowedCharacters:NSCharacterSet.urlQueryAllowed)
result:
"http://www.ihtc.cc?name=htc&title=iOS%E5%BC%80%E5%8F%91%E5%B7%A5%E7%A8%8B%E5%B8%88"
2. encodingURL:
let escapedString = originalString.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)
result:
"http:%2F%2Fwww.ihtc.cc%3Fname=htc&title=iOS%E5%BC%80%E5%8F%91%E5%B7%A5%E7%A8%8B%E5%B8%88"
Swift 4 & 5 (Thanks #sumizome for suggestion. Thanks #FD_ and #derickito for testing)
var allowedQueryParamAndKey = NSCharacterSet.urlQueryAllowed
allowedQueryParamAndKey.remove(charactersIn: ";/?:#&=+$, ")
paramOrKey.addingPercentEncoding(withAllowedCharacters: allowedQueryParamAndKey)
Swift 3
let allowedQueryParamAndKey = NSCharacterSet.urlQueryAllowed.remove(charactersIn: ";/?:#&=+$, ")
paramOrKey.addingPercentEncoding(withAllowedCharacters: allowedQueryParamAndKey)
Swift 2.2 (Borrowing from Zaph's and correcting for url query key and parameter values)
var allowedQueryParamAndKey = NSCharacterSet(charactersInString: ";/?:#&=+$, ").invertedSet
paramOrKey.stringByAddingPercentEncodingWithAllowedCharacters(allowedQueryParamAndKey)
Example:
let paramOrKey = "https://some.website.com/path/to/page.srf?a=1&b=2#top"
paramOrKey.addingPercentEncoding(withAllowedCharacters: allowedQueryParamAndKey)
// produces:
"https%3A%2F%2Fsome.website.com%2Fpath%2Fto%2Fpage.srf%3Fa%3D1%26b%3D2%23top"
This is a shorter version of Bryan Chen's answer. I'd guess that urlQueryAllowed is allowing the control characters through which is fine unless they form part of the key or value in your query string at which point they need to be escaped.
Swift 4:
It depends by the encoding rules followed by your server.
Apple offer this class method, but it don't report wich kind of RCF protocol it follows.
var escapedString = originalString.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)!
Following this useful tool you should guarantee the encoding of these chars for your parameters:
$ (Dollar Sign) becomes %24
& (Ampersand) becomes %26
+ (Plus) becomes %2B
, (Comma) becomes %2C
: (Colon) becomes %3A
; (Semi-Colon) becomes %3B
= (Equals) becomes %3D
? (Question Mark) becomes %3F
# (Commercial A / At) becomes %40
In other words, speaking about URL encoding, you should following the RFC 1738 protocol.
And Swift don't cover the encoding of the + char for example, but it works well with these three # : ? chars.
So, to correctly encoding each your parameter , the .urlHostAllowed option is not enough, you should add also the special chars as for example:
encodedParameter = parameter.replacingOccurrences(of: "+", with: "%2B")
Hope this helps someone who become crazy to search these informations.
Everything is same
var str = CFURLCreateStringByAddingPercentEscapes(
nil,
"test/test",
nil,
"!*'();:#&=+$,/?%#[]",
CFStringBuiltInEncodings.UTF8.rawValue
)
// test%2Ftest
Swift 4.2
A quick one line solution. Replace originalString with the String you want to encode.
var encodedString = originalString.addingPercentEncoding(withAllowedCharacters: CharacterSet(charactersIn: "!*'();:#&=+$,/?%#[]{} ").inverted)
Online Playground Demo
This is working for me in Swift 5. The usage case is taking a URL from the clipboard or similar which may already have escaped characters but which also contains Unicode characters which could cause URLComponents or URL(string:) to fail.
First, create a character set that includes all URL-legal characters:
extension CharacterSet {
/// Characters valid in at least one part of a URL.
///
/// These characters are not allowed in ALL parts of a URL; each part has different requirements. This set is useful for checking for Unicode characters that need to be percent encoded before performing a validity check on individual URL components.
static var urlAllowedCharacters: CharacterSet {
// Start by including hash, which isn't in any set
var characters = CharacterSet(charactersIn: "#")
// All URL-legal characters
characters.formUnion(.urlUserAllowed)
characters.formUnion(.urlPasswordAllowed)
characters.formUnion(.urlHostAllowed)
characters.formUnion(.urlPathAllowed)
characters.formUnion(.urlQueryAllowed)
characters.formUnion(.urlFragmentAllowed)
return characters
}
}
Next, extend String with a method to encode URLs:
extension String {
/// Converts a string to a percent-encoded URL, including Unicode characters.
///
/// - Returns: An encoded URL if all steps succeed, otherwise nil.
func encodedUrl() -> URL? {
// Remove preexisting encoding,
guard let decodedString = self.removingPercentEncoding,
// encode any Unicode characters so URLComponents doesn't choke,
let unicodeEncodedString = decodedString.addingPercentEncoding(withAllowedCharacters: .urlAllowedCharacters),
// break into components to use proper encoding for each part,
let components = URLComponents(string: unicodeEncodedString),
// and reencode, to revert decoding while encoding missed characters.
let percentEncodedUrl = components.url else {
// Encoding failed
return nil
}
return percentEncodedUrl
}
}
Which can be tested like:
let urlText = "https://www.example.com/폴더/search?q=123&foo=bar&multi=eggs+and+ham&hangul=한글&spaced=lovely%20spam&illegal=<>#top"
let url = encodedUrl(from: urlText)
Value of url at the end: https://www.example.com/%ED%8F%B4%EB%8D%94/search?q=123&foo=bar&multi=eggs+and+ham&hangul=%ED%95%9C%EA%B8%80&spaced=lovely%20spam&illegal=%3C%3E#top
Note that both %20 and + spacing are preserved, Unicode characters are encoded, the %20 in the original urlText is not double encoded, and the anchor (fragment, or #) remains.
Edit: Now checking for validity of each component.
For Swift 5 to endcode string
func escape(string: String) -> String {
let allowedCharacters = string.addingPercentEncoding(withAllowedCharacters: CharacterSet(charactersIn: ":=\"#%/<>?#\\^`{|}").inverted) ?? ""
return allowedCharacters
}
How to use ?
let strEncoded = self.escape(string: "http://www.edamam.com/ontologies/edamam.owl#recipe_e2a1b9bf2d996cbd9875b80612ed9aa4")
print("escapedString: \(strEncoded)")
Had need of this myself, so I wrote a String extension that both allows for URLEncoding strings, as well as the more common end goal, converting a parameter dictionary into "GET" style URL Parameters:
extension String {
func URLEncodedString() -> String? {
var escapedString = self.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)
return escapedString
}
static func queryStringFromParameters(parameters: Dictionary<String,String>) -> String? {
if (parameters.count == 0)
{
return nil
}
var queryString : String? = nil
for (key, value) in parameters {
if let encodedKey = key.URLEncodedString() {
if let encodedValue = value.URLEncodedString() {
if queryString == nil
{
queryString = "?"
}
else
{
queryString! += "&"
}
queryString! += encodedKey + "=" + encodedValue
}
}
}
return queryString
}
}
Enjoy!
This one is working for me.
func stringByAddingPercentEncodingForFormData(plusForSpace: Bool=false) -> String? {
let unreserved = "*-._"
let allowed = NSMutableCharacterSet.alphanumericCharacterSet()
allowed.addCharactersInString(unreserved)
if plusForSpace {
allowed.addCharactersInString(" ")
}
var encoded = stringByAddingPercentEncodingWithAllowedCharacters(allowed)
if plusForSpace {
encoded = encoded?.stringByReplacingOccurrencesOfString(" ", withString: "+")
}
return encoded
}
I found above function from this link: http://useyourloaf.com/blog/how-to-percent-encode-a-url-string/.
let Url = URL(string: urlString.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? "")
None of these answers worked for me. Our app was crashing when a url contained non-English characters.
let unreserved = "-._~/?%$!:"
let allowed = NSMutableCharacterSet.alphanumeric()
allowed.addCharacters(in: unreserved)
let escapedString = urlString.addingPercentEncoding(withAllowedCharacters: allowed as CharacterSet)
Depending on the parameters of what you are trying to do, you may want to just create your own character set. The above allows for english characters, and -._~/?%$!:
What helped me was that I created a separate NSCharacterSet and used it on an UTF-8 encoded string i.e. textToEncode to generate the required result:
var queryCharSet = NSCharacterSet.urlQueryAllowed
queryCharSet.remove(charactersIn: "+&?,:;#+=$*()")
let utfedCharacterSet = String(utf8String: textToEncode.cString(using: .utf8)!)!
let encodedStr = utfedCharacterSet.addingPercentEncoding(withAllowedCharacters: queryCharSet)!
let paramUrl = "https://api.abc.eu/api/search?device=true&query=\(escapedStr)"
SWIFT 4.2
Sometimes this happened just because there is space in slug OR absence of URL encoding for parameters passing through API URL.
let myString = self.slugValue
let csCopy = CharacterSet(bitmapRepresentation: CharacterSet.urlPathAllowed.bitmapRepresentation)
let escapedString = myString!.addingPercentEncoding(withAllowedCharacters: csCopy)!
//always "info:hello%20world"
print(escapedString)
NOTE : Don't forget to explore about bitmapRepresentation.
version:Swift 5
// space convert to +
let mstring = string.replacingOccurrences(of: " ", with: "+")
// remove special character
var allowedQueryParamAndKey = NSCharacterSet.urlQueryAllowed
allowedQueryParamAndKey.remove(charactersIn: "!*'\"();:#&=+$,/?%#[]%")
return mstring.addingPercentEncoding(withAllowedCharacters: allowedQueryParamAndKey) ?? mstring
Swift 5
You can try .afURLQueryAllowed option if you want to encode string like below
let testString = "6hAD9/RjY+SnGm&B"
let escodedString = testString.addingPercentEncoding(withAllowedCharacters: .afURLQueryAllowed)
print(escodedString!)
//encoded string will be like en6hAD9%2FRjY%2BSnGm%26B
I have some Strings that vary in length but always end in "listing(number)"
myString = 9AMnep8MAziUCK7VwKF51mXZ2listing28
.
I want to get the String without "listing(number)":
9AMnep8MAziUCK7VwKF51mXZ2
.
Methods I've tried such as .index(of: ) only let you format based off one character. Any simple solutions?
A possible solution is to search for the substring with Regular Expression and remove the result (replace it with empty string)
let myString = "9AMnep8MAziUCK7VwKF51mXZ2listing28"
let trimmedString = myString.replacingOccurrences(of: "listing\\d+$", with: "", options: .regularExpression)
\\d+ searches for one ore more digits
$ represents the end of the string
Alternatively without creating a new string
var myString = "9AMnep8MAziUCK7VwKF51mXZ2listing28"
if let range = myString.range(of: "listing\\d+$", options: .regularExpression) {
myString.removeSubrange(range)
}
Another option is to split the string in parts with "listing" as separator
let result = myString.components(separatedBy: "listing").first
So to solve your issue find the code below with few comments written to try and explain each steps have taken. kindly note i have modified or arrived at this solution using this links as a guide.
https://stackoverflow.com/a/40070835/6596443
https://www.dotnetperls.com/substring-swift
extension String {
//
// Paramter inputString: This is the string you want to manipulate
// Paramter- startStringOfUnwanted: This is the string you want to start the removal or replacement from
//return : The expected output you want but can be emptystring if unable to
static func trimUnWantedEndingString(inputString: String,startStringOfUnwanted: String) -> String{
//Output string
var outputString: String?
//Getting the range based on the string content
if let range = myString.range(of: startStringOfUnwanted) {
//Get the lowerbound of the range
let lower = range.lowerBound
//Get the upperbound of the range
let upper = range.upperBound
//Get the integer position of the start index of the unwanted string i added plus one to ensure it starts from the right position
let startPos = Int(myString.distance(from: myString.startIndex, to: lower))+1
//Get the integer position of the end index of the unwanted string i added plus one to ensure it starts from the right position
let endPos = Int(myString.distance(from: myString.startIndex, to: upper))+1
//Substract the start int from the end int to get the integer value that will be used to get the last string i want to stop trimming at
let endOffsetBy = endPos-startPos
//get thes string char ranges of values
let result = myString.index(myString.startIndex, offsetBy: 0)..<myString.index(myString.endIndex, offsetBy: -endOffsetBy)
//converts the results to string or get the string representation of the result and then assign it to the OutputString
outputString = String(myString[result]);
}
return outputString ?? "";
}
}
let myString = "9AMnep8MAziUCK7VwKF51mXZ2listing28"
String.trimUnWantedEndingString(inputString: myString, startStringOfUnwanted:"listing")
I have a string that is actually a phone number. This string is stored as variable PhoneNumber in my database.
I want to convert this to a type phoneNumber() and then format it using the PhoneNumberKit and then put it back into a label as a string
How should i do this?
Convert the string to integer and then convert the string to phoneNumber struct present in phone number kit?
or is there anyway of simply passing the string itself to format function in phone Numberkit?
I have not written a full code yet. So this is what i have in my code:
func formatTOPhoneNumber(){
// userNumber is the string that is phone number
var userNumber = User.shared.phoneNumber
var num = (userNumber! as NSString).integerValue
}
The PhoneNumberKit library works with strings. Use the parse method to convert it into a PhoneNumber object. Then use the format function to convert it into a string:
var formattedString = ""
do {
let phoneNumberKit = PhoneNumberKit()
let phoneNumber = try phoneNumberKit.parse(userNumber)
formattedString = phoneNumberKit.format(phoneNumber, toType: .e164)
}
catch {
print("Generic parser error")
}
Try reading the documentation before asking a question, you might attract some downvotes when you haven't done any prior research.
I am getting this below string as a response from WS API when they send emoji as a string:
let strTemp = "Hii \\xF0\\x9F\\x98\\x81"
I want it to be converted to the emoji icon like this -> Hii 😁
I think so it is coming in UTF-8 Format as explained in the below Image: Image Unicode
I have tried decoding it Online using UTF-8 Decoder
And i got the emoticon Successfully decoded
Before Decoding:
After Decoding:
But the issue here is I do not know how to work with it in Swift.
I referred following link but it did not worked for me.
Swift Encode/decode emojis
Any help would be appreciated.
Thanks.
As you already given the link of converter tool which is clearly doing UTF-8 encoding and decoding. You have UTF-8 encoded string so here is an example of UTF8-Decoding.
Objective-C
const char *ch = [#"Hii \xF0\x9F\x98\x81" cStringUsingEncoding:NSUTF8StringEncoding];
NSString *decode_string = [NSString stringWithUTF8String:ch];
NSLog(#"%#",decode_string);
Output: Hii 😁
Swift
I'm able to convert \\xF0\\x9F\\x98\\x81 to 😁 in SWift.
First I converted the hexa string into Data and then back to String using UTF-8 encoding.
var str = "\\xF0\\x9F\\x98\\x81"
if let data = data(fromHexaStr: str) {
print(String(data: data, encoding: String.Encoding.utf8) ?? "")
}
Output: 😁
Below is the function I used to convert the hexa string into data. I followed this answer.
func data(fromHexaStr hexaStr: String) -> Data? {
var data = Data(capacity: hexaStr.characters.count / 2)
let regex = try! NSRegularExpression(pattern: "[0-9a-f]{1,2}", options: .caseInsensitive)
regex.enumerateMatches(in: hexaStr, range: NSMakeRange(0, hexaStr.utf16.count)) { match, flags, stop in
let byteString = (hexaStr as NSString).substring(with: match!.range)
var num = UInt8(byteString, radix: 16)!
data.append(&num, count: 1)
}
guard data.count > 0 else { return nil }
return data
}
Note: Problem with above code is it converts hexa string only not combined strings.
FINAL WORKING SOLUTION: SWIFT
I have done this by using for loop instead of [0-9a-f]{1,2} regex because this will also scan 81, 9F, Any Two digits number which is wrong obviously.
For example: I have 81 INR \\xF0\\x9F\\x98\\x81.
/// This line will convert "F0" into hexa bytes
let byte = UInt8("F0", radix: 16)
I made a String extension in which I check upto every 4 characters if it has prefix \x and count 4 and last two characters are convertible into hexa bytes by using radix as mentioned above.
extension String {
func hexaDecoededString() -> String {
var newData = Data()
var emojiStr: String = ""
for char in self.characters {
let str = String(char)
if str == "\\" || str.lowercased() == "x" {
emojiStr.append(str)
}
else if emojiStr.hasPrefix("\\x") || emojiStr.hasPrefix("\\X") {
emojiStr.append(str)
if emojiStr.count == 4 {
/// It can be a hexa value
let value = emojiStr.replacingOccurrences(of: "\\x", with: "")
if let byte = UInt8(value, radix: 16) {
newData.append(byte)
}
else {
newData.append(emojiStr.data(using: .utf8)!)
}
/// Reset emojiStr
emojiStr = ""
}
}
else {
/// Append the data as it is
newData.append(str.data(using: .utf8)!)
}
}
let decodedString = String(data: newData, encoding: String.Encoding.utf8)
return decodedString ?? ""
}
}
USAGE:
var hexaStr = "Hi \\xF0\\x9F\\x98\\x81 81"
print(hexaStr.hexaDecoededString())
Hi 😁 81
hexaStr = "Welcome to SP19!\\xF0\\x9f\\x98\\x81"
print(hexaStr.hexaDecoededString())
Welcome to SP19!😁
I fix your issue but it need more work to make it general , the problem here is that your Emijo is Represented by Hex Byte x9F , so we have to convert this Hex to utf8 then convert it to Data and at last convert data to String
Final result Hii 😁 Please read comment
let strTemp = "Hii \\xF0\\x9F\\x98\\x81"
let regex = try! NSRegularExpression(pattern: "[0-9a-f]{1,2}", options: .caseInsensitive)
// get all matched hex xF0 , x9f,..etc
let matches = regex.matches(in: strTemp, options: [], range: NSMakeRange(0, strTemp.count))
// Data that will hanlde convert hex to UTf8
var emijoData = Data(capacity: strTemp.count / 2)
matches.enumerated().forEach { (offset , check) in
let byteString = (strTemp as NSString).substring(with: check.range)
var num = UInt8(byteString, radix: 16)!
emijoData.append(&num, count: 1)
}
let subStringEmijo = String.init(data: emijoData, encoding: String.Encoding.utf8)!
//now we have your emijo text 😁 we can replace by its code from string using matched ranges `first` and `last`
// All range range of \\xF0\\x9F\\x98\\x81 in "Hii \\xF0\\x9F\\x98\\x81" to replce by your emijo
if let start = matches.first?.range.location, let end = matches.last?.range.location , let endLength = matches.last?.range.length {
let startLocation = start - 2
let length = end - startLocation + endLength
let sub = (strTemp as NSString).substring(with: NSRange.init(location: startLocation, length: length))
print( strTemp.replacingOccurrences(of: sub, with: subStringEmijo))
// Hii 😁
}
I want to remove the special character , in a string so I can convert the value to a double. How do I do it?
Example:
let stringValue = "4,000.50";
I have tried to use the NumberFormatter but getting nil error
let NF = NumberFormatter();
let value = NF.number(from: stringValue);
//nil
If the number string will always be formatted from a specific locale then you need to set the formatter's locale to match. Without setting the locale, the string won't be parsed if the user's locale using different grouping and decimal formatting.
let stringValue = "4,000.50"
let nf = NumberFormatter()
nf.numberStyle = .decimal
nf.locale = Locale(identifier: "en_US")
let value = nf.number(from: stringValue)
FYI - this is Swift, you don't need semicolons at the end of lines.
Same as #rmaddy but using string replacingOccurrences :
var stringValue = "4,000,000.50"
stringValue = stringValue.replacingOccurrences(of: ",", with: "")
let nf = NumberFormatter()
let value = nf.number(from: stringValue)
print(value)
If you know you're working with currency, you could clean-up the text value for any decimal and thousand separator by leveraging the pattern of consecutive digits. If there are any decimals, they would be the last group and would have exactly two digits (for most currencies). On the basis of this assumption, you don't need to know which separator is used and you would also be resilient to the presence of other characters such as the currency name or symbol:
let textValue = "Balance : 1 200,33 Euros"
let nonDigits = CharacterSet(charactersIn: "01234456789").inverted
let digitGroups = textValue.components(separatedBy:nonDigits).filter{!$0.isEmpty}
let textNumber = digitGroups.dropLast().joined(separator:"")
+ ( digitGroups.last!.characters.count == 2
&& digitGroups.count > 1 ? "." : "" )
+ digitGroups.last!
textNumber // 1200.33
If you just want a sanitized string with only digits and decimals, then in Xcode 9.0+ you can just do:
let originalString = "4,000.00"
let numberString = originalString.filter({ "1234567890.".contains($0) })
// numberString -> "4000.00"
Then, converting your sanitized string to a Float is as easy as
if let num = Float(numberString) {
// do something with float
} else {
// failed to init float with string
}