Convert optional string to double in Swift 3 - ios

I have a option string and want to convert that to double.
this worked in Swift 2 , but since converted to Swift 3, I am getting value of 0.
var dLati = 0.0
dLati = (latitude as NSString).doubleValue
I have check and latitude has a optional string value of something like -80.234543218675654 , but dLati value is 0
*************** ok, new update for clarity *****************
I have a viewcontroller which i have a button in it, and when the button is touched, it will call another viewcontroller and pass a few values to it
here is the code for the first viewcontroller
var currentLatitude: String? = ""
var currentLongitude: String? = ""
var deviceName = ""
var address = ""
// somewhere in the code, currentLatitude and currentLongitude are get set
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "map" {
let destViewController : MapViewController = segue.destination as! MapViewController
print(currentLongitude!) // Print display: Optional(-80.192279355363768)
print(currentLatitude!) // Print display: Optional(25.55692663937162)
destViewController.longitude = currentLongitude!
destViewController.latitude = currentLatitude!
destViewController.deviceName = deviceName
destViewController.address = address
}
}
Here is the code for the second view controller called MapViewController
var longitude: String? = " "
var latitude: String? = ""
.
.
override func viewDidLoad() {
if let lat = latitude {
print(lat) // Print display: optiona(25.55692663937162)
dLati = (lat as NSString).doubleValue
print(dLati) // Print display: 0.0
}
.
.
}
Thanks
Borna

A safe way to achieve this without needing to use Foundation types is using Double's initializer:
if let lat = latitude, let doubleLat = Double(lat) {
print(doubleLat) // doubleLat is of type Double now
}

Unwrap the latitude value safely and then use
var dLati = 0.0
if let lat = latitude {
dLati = (lat as NSString).doubleValue
}

let dLati = Double(latitude ?? "") ?? 0.0

This code works fine.
var dLati = 0.0
let latitude: String? = "-80.234543218675654"
if let strLat = latitude {
dLati = Double(strLat)!
}

You can do this simply in one line.
var latitude: Double = Double("-80.234543218675654") ?? 0.0
This creates a variable named latitude that is of type Double that is either instantiated with a successful Double from String or is given a fallback value of 0.0

When you get a string with double value something like this
"Optional(12.34567)"
You can use a Regex which takes out the double value from the string.
This is the example code for a Regex if the string is "Optional(12.34567)":
let doubleLatitude = location.latitude?.replacingOccurrences(of: "[^\\.\\d+]", with: "", options: [.regularExpression])

Actually the word optional was part of the string. Not sure how it got added in the string? But the way I fixed it was like this. latitude was this string "Optional(26.33691567239162)" then I did this code
let start = latitude.index(latitude.startIndex, offsetBy: 9)
let end = latitude.index(latitude.endIndex, offsetBy: -1)
let range = start..<end
latitude = latitude.substring(with: range)
and got this as the final value
26.33691567239162

Don´t convert it to an NSString, you can force it to a Double but have a fallback if it fails. Something like this:
let aLat: String? = "11.123456"
let bLat: String? = "11"
let cLat: String? = nil
let a = Double(aLat!) ?? 0.0 // 11.123456
let b = Double(bLat!) ?? 0.0 // 11
let c = Double(cLat!) ?? 0.0 // 0
So in your case:
dLati = Double(latitude!) ?? 0.0
Update:
To handle nil values do the following (note that let cLat is nil:
// Will succeed
if let a = aLat, let aD = Double(aLat!) {
print(aD)
}
else {
print("failed")
}
// Will succeed
if let b = bLat, let bD = Double(bLat!) {
print(bD)
}
else {
print("failed")
}
// Will fail
if let c = cLat, let cD = Double(cLat!) {
print(cD)
}
else {
print("failed")
}

In swift 3.1, we can combine extensions and Concrete Constrained Extensions
extension Optional where Wrapped == String
{
var asDouble: Double
{
return NSString(string: self ?? "").doubleValue
}
}
Or
extension Optional where Wrapped == String
{
var asDouble: Double
{
return Double(str ?? "0.00") ?? 0.0
}
}

Swift 4
let YourStringValue1st = "33.733322342342" //The value is now in string
let YourStringValue2nd = "73.449384384334" //The value is now in string
//MARK:- For Testing two Parameters
if let templatitude = (YourStringValue1st as? String), let templongitude = (YourStringValue2nd as? String)
{
movetosaidlocation(latitude: Double(templat)!, longitude: Double(templong)!, vformap: cell.vformap)
}
let YourStringValue = "33.733322342342" //The value is now in string
//MARK:- For Testing One Value
if let tempLat = (YourStringValue as? String)
{
let doublevlue = Double(tempLat)
//The Value is now in double (doublevlue)
}

Related

I get an empty CLLocationCoordinates array when loading data from user defaults

I'm trying to store to UserDefaults an array of CCLocationCoordinates from the tracking portion of my app paired with the name of the tracked route as key, to be able to recall it later on to use it within a function.
The problem is that when I call that function I get the index out of range error. I checked and the array is empty.
As I'm new to user defaults I tried to see other similar posts but they're all about NSUserDefaults and didn't find a solution.
Heres the code for the functions for storing and recalling the array:
func stopTracking2() {
self.trackingIsActive = false
self.trackigButton.backgroundColor = UIColor.yellow
locationManager.stopUpdatingLocation()
let stopRoutePosition = RouteAnnotation(title: "Route Stop", coordinate: (locationManager.location?.coordinate)!, imageName: "Route Stop")
self.actualRouteInUseAnnotations.append(stopRoutePosition)
print(actualRouteInUseCoordinatesArray)
print(actualRouteInUseAnnotations)
drawRoutePolyline() // draw line to show route
// checkAlerts2() // check if there is any notified problem on our route and marks it with a blue circle, now called at programmed checking
saveRouteToUserDefaults()
postRouteToAnalitics() // store route anonymously to FIrebase
}
func saveRouteToUserDefaults() {
// save actualRouteInUseCoordinatesArray : change for function
// userDefaults.set(actualRouteInUseCoordinatesArray, forKey: "\(String(describing: userRoute))")
storeCoordinates(actualRouteInUseCoordinatesArray)
}
// Store an array of CLLocationCoordinate2D
func storeCoordinates(_ coordinates: [CLLocationCoordinate2D]) {
let locations = coordinates.map { coordinate -> CLLocation in
return CLLocation(latitude: coordinate.latitude, longitude: coordinate.longitude)
}
let archived = NSKeyedArchiver.archivedData(withRootObject: locations)
userDefaults.set(archived, forKey: "\(String(describing: userRoute))")
userDefaults.synchronize()
}
func loadRouteFromUserDefaults() {
// gets entry from userRouteArray stored in userDefaults and append them into actualRouteInUseCoordinatesArray
actualRouteInUseCoordinatesArray.removeAll()
actualRouteInUseCoordinatesArray = userDefaults.object(forKey: "\(String(describing: userRoute))") as? [CLLocationCoordinate2D] ?? [CLLocationCoordinate2D]() // here we get the right set of coordinates for the route we are about to do the check on
// load route coordinates from UserDefaults
// actualRouteInUseCoordinatesArray = loadCoordinates()! //error found nil
}
// Return an array of CLLocationCoordinate2D
func loadCoordinates() -> [CLLocationCoordinate2D]? {
guard let archived = userDefaults.object(forKey: "\(String(describing: userRoute))") as? Data,
let locations = NSKeyedUnarchiver.unarchiveObject(with: archived) as? [CLLocation] else {
return nil
}
let coordinates = locations.map { location -> CLLocationCoordinate2D in
return location.coordinate
}
return coordinates
}
}
extension NewMapViewController {
// ALERTS :
func checkAlerts2() {
loadRouteFromUserDefaults() //load route coordinates to check in
// CHECK IF ANY OBSTACLE IS OUN OUR ROUTE BY COMPARING DISTANCES
while trackingCoordinatesArrayPosition != ( (actualRouteInUseCoordinatesArray.count) - 1) {
print("checking is started")
print(actualRouteInUseCoordinatesArray)
let trackingLatitude = actualRouteInUseCoordinatesArray[trackingCoordinatesArrayPosition].latitude
let trackingLongitude = actualRouteInUseCoordinatesArray[trackingCoordinatesArrayPosition].longitude
let alertLatitude = alertNotificationCoordinatesArray[alertNotificationCoordinatesArrayPosition].latitude
let alertLongitude = alertNotificationCoordinatesArray[alertNotificationCoordinatesArrayPosition].longitude
let coordinateFrom = CLLocation(latitude: trackingLatitude, longitude: trackingLongitude)
let coordinateTo = CLLocation(latitude: alertLatitude, longitude: alertLongitude)
let coordinatesDistanceInMeters = coordinateFrom.distance(from: coordinateTo)
// CHECK SENSITIVITY: sets the distance in meters for an alert to be considered an obstacle
if coordinatesDistanceInMeters <= 10 {
print( "found problem")
routeObstacle.append(alertNotificationCoordinatesArray[alertNotificationCoordinatesArrayPosition]) // populate obstacles array
trackingCoordinatesArrayPosition = ( trackingCoordinatesArrayPosition + 1)
}
else if alertNotificationCoordinatesArrayPosition < ((alertNotificationCoordinatesArray.count) - 1) {
alertNotificationCoordinatesArrayPosition = alertNotificationCoordinatesArrayPosition + 1
}
else if alertNotificationCoordinatesArrayPosition == (alertNotificationCoordinatesArray.count - 1) {
trackingCoordinatesArrayPosition = ( trackingCoordinatesArrayPosition + 1)
alertNotificationCoordinatesArrayPosition = 0
}
}
findObstacles()
NewMapViewController.checkCounter = 0
displayObstacles()
}
In the extension you can see the function that uses the array.
Right after the print of the array I get the index out of range error.
Thanks as usual to the community.
After trying various solutions offered I decided to rewrite the whole thing.
So after finding a post on how to code/decode my array to string I decided it was the way to go. It shouldn't be heavy on the system as it's a string that gets saved. Please let me know what you think of this solution.
Thank to #Sh_Khan to point out it was a decoding issue, and to #Moritz to point out I was performing a bad practice.
So the code is:
func storeRoute() {
// first we code the CLLocationCoordinate2D array to string
// second we store string into userDefaults
userDefaults.set(encodeCoordinates(coords: actualRouteInUseCoordinatesArray), forKey: "\(String(describing: NewMapViewController.userRoute))")
}
func loadRoute() {
//first se load string from user defaults
let route = userDefaults.string(forKey: "\(String(describing: NewMapViewController.userRoute))")
print("loaded route is \(route!))")
//second we decode it into CLLocationCoordinate2D array
actualRouteInUseCoordinatesArray = decodeCoordinates(encodedString: route!)
print("decoded route array is \(actualRouteInUseCoordinatesArray))")
}
func encodeCoordinates(coords: [CLLocationCoordinate2D]) -> String {
let flattenedCoords: [String] = coords.map { coord -> String in "\(coord.latitude):\(coord.longitude)" }
let encodedString: String = flattenedCoords.joined(separator: ",")
return encodedString
}
func decodeCoordinates(encodedString: String) -> [CLLocationCoordinate2D] {
let flattenedCoords: [String] = encodedString.components(separatedBy: ",")
let coords: [CLLocationCoordinate2D] = flattenedCoords.map { coord -> CLLocationCoordinate2D in
let split = coord.components(separatedBy: ":")
if split.count == 2 {
let latitude: Double = Double(split[0]) ?? 0
let longitude: Double = Double(split[1]) ?? 0
return CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
} else {
return CLLocationCoordinate2D()
}
}
return coords
}
Rather than using heavy-weight objectiv-c-ish NSKeyed(Un)Archiver and making a detour via CLLocation I recommend to extend CLLocationCoordinate2D to adopt Codable
extension CLLocationCoordinate2D : Codable {
public init(from decoder: Decoder) throws {
var arrayContainer = try decoder.unkeyedContainer()
if arrayContainer.count == 2 {
let lat = try arrayContainer.decode(CLLocationDegrees.self)
let lng = try arrayContainer.decode(CLLocationDegrees.self)
self.init(latitude: lat, longitude: lng)
} else {
throw DecodingError.dataCorruptedError(in: arrayContainer, debugDescription: "Coordinate array must contain two items")
}
}
public func encode(to encoder: Encoder) throws {
var arrayContainer = encoder.unkeyedContainer()
try arrayContainer.encode(contentsOf: [latitude, longitude])
}
}
and replace the methods to load and save data with
func storeCoordinates(_ coordinates: [CLLocationCoordinate2D]) throws {
let data = try JSONEncoder().encode(coordinates)
UserDefaults.standard.set(data, forKey: String(describing: userRoute))
}
func loadCoordinates() -> [CLLocationCoordinate2D] {
guard let data = UserDefaults.standard.data(forKey: String(describing: userRoute)) else { return [] }
do {
return try JSONDecoder().decode([CLLocationCoordinate2D].self, from: data)
} catch {
print(error)
return []
}
}
storeCoordinates throws it hands over a potential encoding error
Load the data with
actualRouteInUseCoordinatesArray = loadCoordinates()
and save it
do {
try storeCoordinates(actualRouteInUseCoordinatesArray)
} catch { print(error) }
Your problem is that you save it as data and try to read directly without unarchiving , You can try
let locations = [CLLocation(latitude: 123, longitude: 344),CLLocation(latitude: 123, longitude: 344),CLLocation(latitude: 123, longitude: 344)]
do {
let archived = try NSKeyedArchiver.archivedData(withRootObject: locations, requiringSecureCoding: true)
UserDefaults.standard.set(archived, forKey:"myKey")
// read savely
if let data = UserDefaults.standard.data(forKey: "myKey") {
let saved = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data) as! [CLLocation]
print(saved)
}
}
catch {
print(error)
}

How can I change a UILabel into a number programmatically? [duplicate]

I'm trying to work out how to cast an Int into a String in Swift.
I figure out a workaround, using NSNumber but I'd love to figure out how to do it all in Swift.
let x : Int = 45
let xNSNumber = x as NSNumber
let xString : String = xNSNumber.stringValue
Converting Int to String:
let x : Int = 42
var myString = String(x)
And the other way around - converting String to Int:
let myString : String = "42"
let x: Int? = myString.toInt()
if (x != nil) {
// Successfully converted String to Int
}
Or if you're using Swift 2 or 3:
let x: Int? = Int(myString)
Check the Below Answer:
let x : Int = 45
var stringValue = "\(x)"
print(stringValue)
Here are 4 methods:
var x = 34
var s = String(x)
var ss = "\(x)"
var sss = toString(x)
var ssss = x.description
I can imagine that some people will have an issue with ss. But if you were looking to build a string containing other content then why not.
In Swift 3.0:
var value: Int = 10
var string = String(describing: value)
Swift 4:
let x:Int = 45
let str:String = String(describing: x)
Developer.Apple.com > String > init(describing:)
The String(describing:) initializer is the preferred way to convert an instance of any type to a string.
Custom String Convertible
Just for completeness, you can also use:
let x = 10.description
or any other value that supports a description.
Swift 4:
Trying to show the value in label without Optional() word.
here x is a Int value using.
let str:String = String(x ?? 0)
To save yourself time and hassle in the future you can make an Int extension. Typically I create a shared code file where I put extensions, enums, and other fun stuff. Here is what the extension code looks like:
extension Int
{
func toString() -> String
{
var myString = String(self)
return myString
}
}
Then later when you want to convert an int to a string you can just do something like:
var myNumber = 0
var myNumberAsString = myNumber.toString()
in swift 3.0 this is how we can convert Int to String and String to Int
//convert Integer to String in Swift 3.0
let theIntegerValue :Int = 123 // this can be var also
let theStringValue :String = String(theIntegerValue)
//convert String to Integere in Swift 3.0
let stringValue : String = "123"
let integerValue : Int = Int(stringValue)!
for whatever reason the accepted answer did not work for me. I went with this approach:
var myInt:Int = 10
var myString:String = toString(myInt)
Multiple ways to do this :
var str1:String="\(23)"
var str2:String=String(format:"%d",234)
let intAsString = 45.description // "45"
let stringAsInt = Int("45") // 45
Swift 2:
var num1 = 4
var numString = "56"
var sum2 = String(num1) + numString
var sum3 = Int(numString)
Swift String performance
A little bit about performance
UI Testing Bundle on iPhone 7(real device) with iOS 14
let i = 0
lt result1 = String(i) //0.56s 5890kB
lt result2 = "\(i)" //0.624s 5900kB
lt result3 = i.description //0.758s 5890kB
import XCTest
class ConvertIntToStringTests: XCTestCase {
let count = 1_000_000
func measureFunction(_ block: () -> Void) {
let metrics: [XCTMetric] = [
XCTClockMetric(),
XCTMemoryMetric()
]
let measureOptions = XCTMeasureOptions.default
measureOptions.iterationCount = 5
measure(metrics: metrics, options: measureOptions) {
block()
}
}
func testIntToStringConstructor() {
var result = ""
measureFunction {
for i in 0...count {
result += String(i)
}
}
}
func testIntToStringInterpolation() {
var result = ""
measureFunction {
for i in 0...count {
result += "\(i)"
}
}
}
func testIntToStringDescription() {
var result = ""
measureFunction {
for i in 0...count {
result += i.description
}
}
}
}
iam using this simple approach
String to Int:
var a = Int()
var string1 = String("1")
a = string1.toInt()
and from Int to String:
var a = Int()
a = 1
var string1 = String()
string1= "\(a)"
Convert Unicode Int to String
For those who want to convert an Int to a Unicode string, you can do the following:
let myInteger: Int = 97
// convert Int to a valid UnicodeScalar
guard let myUnicodeScalar = UnicodeScalar(myInteger) else {
return ""
}
// convert UnicodeScalar to String
let myString = String(myUnicodeScalar)
// results
print(myString) // a
Or alternatively:
let myInteger: Int = 97
if let myUnicodeScalar = UnicodeScalar(myInteger) {
let myString = String(myUnicodeScalar)
}
I prefer using String Interpolation
let x = 45
let string = "\(x)"
Each object has some string representation. This makes things simpler. For example if you need to create some String with multiple values. You can also do any math in it or use some conditions
let text = "\(count) \(count > 1 ? "items" : "item") in the cart. Sum: $\(sum + shippingPrice)"
exampleLabel.text = String(yourInt)
To convert String into Int
var numberA = Int("10")
Print(numberA) // It will print 10
To covert Int into String
var numberA = 10
1st way)
print("numberA is \(numberA)") // It will print 10
2nd way)
var strSomeNumber = String(numberA)
or
var strSomeNumber = "\(numberA)"
let a =123456888
var str = String(a)
OR
var str = a as! String
In swift 3.0, you may change integer to string as given below
let a:String = String(stringInterpolationSegment: 15)
Another way is
let number: Int = 15
let _numberInStringFormate: String = String(number)
//or any integer number in place of 15
If you like swift extension, you can add following code
extension Int
{
var string:String {
get {
return String(self)
}
}
}
then, you can get string by the method you just added
var x = 1234
var s = x.string
let Str = "12"
let num: Int = 0
num = Int (str)

Swift4 : FMDBdatabase - Unexpectedly found nil while unwrapping an Optional value

Update:
In the end, I go to the local SQLite database and replace the NULL value to
"unkown". This works!
I am using FMDatabaseQueue to search an existing sqlite database in iOS.
//Data model
import Foundation
import UIKit
class scoreModel: NSObject {
var lessonName:String = String()
var lessonCode:String = String()
var creditPoint:Double = Double()
var totalStudentNumber:Int = Int()
var teacherName:String = String()
var semesterName:String = String()
var scoreValue:String = String()
var studentCount:Int = Int()
}
Unfortunately, there are some "" string in my database. Like:
teacherName ""
scoreValue ""
While searching, Xcode alerted that
"Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value" in line "teacherName".
I don't need these "" results necessarily as they are not important. How can I fix it?
func queryDB(sql: String) -> NSMutableArray {
openDB ();
let resultArray = NSMutableArray()
SQLiteManager.shareInstance.dbQueue?.inDatabase { (db) in
let dbResult: FMResultSet! = db.executeQuery(sql, withArgumentsIn:[])
if (dbResult != nil)
{
while dbResult.next() {
let model:scoreModel = scoreModel()
model.lessonName = String(dbResult.string(forColumn: "lessonName")!)
model.lessonCode = String(dbResult.string(forColumn: "lessonCode")!)
model.creditPoint = Double(dbResult.double(forColumn: "creditPoint"))
model.semesterName = String(dbResult.string(forColumn: "semesterName")!)
model.teacherName = String(dbResult.string(forColumn: "teacherName")!)
model.totalStudentNumber = Int(dbResult.int(forColumn: "totalStudentNumber"))
model.scoreValue = String(dbResult.string(forColumn: "scoreValue")!)
model.studentCount = Int(dbResult.int(forColumn: "studentCount"))
resultArray.add(model)
}
}
}
return resultArray
}
Thank you!
The problem is that dbResult.string(forColumn: "teacherName") is returning an optional with a nil value, so maybe this object had a nil value when you saved it. It doesn't really matter, what's important is how you want to treat objects that don't have all the fields that you're expecting. The question you need to ask yourself is "how should I handle the case where the thing in the database doesn't have a teacher name?" Here are two ideas:
In order to be considered "valid," everything in the database needs to have all the properties I'm expecting, otherwise I ignore it. That would look like this:
while dbResult.next() {
if let lessonName = String(dbResult.string(forColumn: "lessonName")),
let lessonCode = String.dbResult.string(forColumn: "lessonCode")),
let creditPoint = Double(dbResult.double(forColumn: "creditPoint")),
let semesterName = String(dbResult.string(forColumn: "semesterName")),
let teacherName = String(dbResult.string(forColumn: "teacherName")),
let totalStudentNumber = Int(dbResult.int(forColumn: "totalStudentNumber")),
let scoreValue = String(dbResult.string(forColumn: "scoreValue")),
let studentCount = Int(dbResult.int(forColumn: "studentCount")) {
let model = scoreModel()
model.lessonName = lessonName
... // set lessonCode, etc
resultArray.add(model)
}
}
Another choice is to provide default values using optional coalescing or similar.
while dbResult.next() {
let lessonName = String(dbResult.string(forColumn: "lessonName")) ?? ""
let lessonCode = String.dbResult.string(forColumn: "lessonCode")) ?? ""
let creditPoint = Double(dbResult.double(forColumn: "creditPoint")) ?? ""
let semesterName = String(dbResult.string(forColumn: "semesterName")) ?? ""
let teacherName = String(dbResult.string(forColumn: "teacherName")) ?? ""
let totalStudentNumber = Int(dbResult.int(forColumn: "totalStudentNumber")) ?? 0
let scoreValue = String(dbResult.string(forColumn: "scoreValue")) ?? ""
let studentCount = Int(dbResult.int(forColumn: "studentCount")) ?? 0
let model = scoreModel()
model.lessonName = lessonName
... // set lessonCode, etc
resultArray.add(model)
}

How to know data coming from JSON is a Float or an Integer in Swift 3?

I am getting data from Json and displaying it in table view how to check whether the number is float or double or integer in swift 3 if it is float how to get the no.of digits after decimal can anyone help me how to implement this in swift 3 ?
if specialLoop.attributeCode == "special_price" {
let attributeString: NSMutableAttributedString = NSMutableAttributedString(string: "$ \((arr.price))")
attributeString.addAttribute(NSStrikethroughStyleAttributeName, value: 1, range: NSMakeRange(0, attributeString.length))
let specialPrice = specialLoop.value.replacingOccurrences(of: ".0000", with: "0")
print(specialPrice)
cell.productPrice.text = "$ \(specialPrice)"
cell.specialPriceLabel.isHidden = false
cell.specialPriceLabel.attributedText = attributeString
break
}
else {
cell.specialPriceLabel.isHidden = true
let price = arr.price
print(price)
cell.productPrice.text = "$ \( (price))0"
}
You can use (if let)
let data = [String: Any]()
if let value = data["key"] as? Int {
} else if let value = data["key"] as? Float {
} else if let value = data["key"] as? Double {
}
as describe below, you can find a type of any object (whether custom class or built-in class like - String, Int, etc.).
class demo {
let a: String = ""
}
let demoObj = demo()
print(type(of: demoObj))
--> Output: "demo.Type"

Converting String to Int with Swift

The application basically calculates acceleration by inputting Initial and final velocity and time and then use a formula to calculate acceleration. However, since the values in the text boxes are string, I am unable to convert them to integers.
#IBOutlet var txtBox1 : UITextField
#IBOutlet var txtBox2 : UITextField
#IBOutlet var txtBox3 : UITextField
#IBOutlet var lblAnswer : UILabel
#IBAction func btn1(sender : AnyObject) {
let answer1 = "The acceleration is"
var answer2 = txtBox1
var answer3 = txtBox2
var answer4 = txtBox3
Updated answer for Swift 2.0+:
toInt() method gives an error, as it was removed from String in Swift 2.x. Instead, the Int type now has an initializer that accepts a String:
let a: Int? = Int(firstTextField.text)
let b: Int? = Int(secondTextField.text)
Basic Idea, note that this only works in Swift 1.x (check out ParaSara's answer to see how it works in Swift 2.x):
// toInt returns optional that's why we used a:Int?
let a:Int? = firstText.text.toInt() // firstText is UITextField
let b:Int? = secondText.text.toInt() // secondText is UITextField
// check a and b before unwrapping using !
if a && b {
var ans = a! + b!
answerLabel.text = "Answer is \(ans)" // answerLabel ie UILabel
} else {
answerLabel.text = "Input values are not numeric"
}
Update for Swift 4
...
let a:Int? = Int(firstText.text) // firstText is UITextField
let b:Int? = Int(secondText.text) // secondText is UITextField
...
myString.toInt() - convert the string value into int .
Swift 3.x
If you have an integer hiding inside a string, you can convertby using the integer's constructor, like this:
let myInt = Int(textField.text)
As with other data types (Float and Double) you can also convert by using NSString:
let myString = "556"
let myInt = (myString as NSString).integerValue
You can use NSNumberFormatter().numberFromString(yourNumberString). It's great because it returns an an optional that you can then test with if let to determine if the conversion was successful.
eg.
var myString = "\(10)"
if let myNumber = NSNumberFormatter().numberFromString(myString) {
var myInt = myNumber.integerValue
// do what you need to do with myInt
} else {
// what ever error code you need to write
}
Swift 5
var myString = "\(10)"
if let myNumber = NumberFormatter().number(from: myString) {
var myInt = myNumber.intValue
// do what you need to do with myInt
} else {
// what ever error code you need to write
}
edit/update: Xcode 11.4 • Swift 5.2
Please check the comments through the code
IntegerField.swift file contents:
import UIKit
class IntegerField: UITextField {
// returns the textfield contents, removes non digit characters and converts the result to an integer value
var value: Int { string.digits.integer ?? 0 }
var maxValue: Int = 999_999_999
private var lastValue: Int = 0
override func willMove(toSuperview newSuperview: UIView?) {
// adds a target to the textfield to monitor when the text changes
addTarget(self, action: #selector(editingChanged), for: .editingChanged)
// sets the keyboard type to digits only
keyboardType = .numberPad
// set the text alignment to right
textAlignment = .right
// sends an editingChanged action to force the textfield to be updated
sendActions(for: .editingChanged)
}
// deletes the last digit of the text field
override func deleteBackward() {
// note that the field text property default value is an empty string so force unwrap its value is safe
// note also that collection remove at requires a non empty collection which is true as well in this case so no need to check if the collection is not empty.
text!.remove(at: text!.index(before: text!.endIndex))
// sends an editingChanged action to force the textfield to be updated
sendActions(for: .editingChanged)
}
#objc func editingChanged() {
guard value <= maxValue else {
text = Formatter.decimal.string(for: lastValue)
return
}
// This will format the textfield respecting the user device locale and settings
text = Formatter.decimal.string(for: value)
print("Value:", value)
lastValue = value
}
}
You would need to add those extensions to your project as well:
Extensions UITextField.swift file contents:
import UIKit
extension UITextField {
var string: String { text ?? "" }
}
Extensions Formatter.swift file contents:
import Foundation
extension Formatter {
static let decimal = NumberFormatter(numberStyle: .decimal)
}
Extensions NumberFormatter.swift file contents:
import Foundation
extension NumberFormatter {
convenience init(numberStyle: Style) {
self.init()
self.numberStyle = numberStyle
}
}
Extensions StringProtocol.swift file contents:
extension StringProtocol where Self: RangeReplaceableCollection {
var digits: Self { filter(\.isWholeNumber) }
var integer: Int? { Int(self) }
}
Sample project
swift 4.0
let stringNumber = "123"
let number = Int(stringNumber) //here number is of type "Int?"
//using Forced Unwrapping
if number != nil {
//string is converted to Int
}
you could also use Optional Binding other than forced binding.
eg:
if let number = Int(stringNumber) {
// number is of type Int
}
In Swift 4.2 and Xcode 10.1
let string = "789"
if let intValue = Int(string) {
print(intValue)
}
let integerValue = 789
let stringValue = String(integerValue)
OR
let stringValue = "\(integerValue)"
print(stringValue)
//Xcode 8.1 and swift 3.0
We can also handle it by Optional Binding, Simply
let occur = "10"
if let occ = Int(occur) {
print("By optional binding :", occ*2) // 20
}
Swift 3
The simplest and more secure way is:
#IBOutlet var textFieldA : UITextField
#IBOutlet var textFieldB : UITextField
#IBOutlet var answerLabel : UILabel
#IBAction func calculate(sender : AnyObject) {
if let intValueA = Int(textFieldA),
let intValueB = Int(textFieldB) {
let result = intValueA + intValueB
answerLabel.text = "The acceleration is \(result)"
}
else {
answerLabel.text = "The value \(intValueA) and/or \(intValueB) are not a valid integer value"
}
}
Avoid invalid values setting keyboard type to number pad:
textFieldA.keyboardType = .numberPad
textFieldB.keyboardType = .numberPad
In Swift 4:
extension String {
var numberValue:NSNumber? {
let formatter = NumberFormatter()
formatter.numberStyle = .decimal
return formatter.number(from: self)
}
}
let someFloat = "12".numberValue
Useful for String to Int and other type
extension String {
//Converts String to Int
public func toInt() -> Int? {
if let num = NumberFormatter().number(from: self) {
return num.intValue
} else {
return nil
}
}
//Converts String to Double
public func toDouble() -> Double? {
if let num = NumberFormatter().number(from: self) {
return num.doubleValue
} else {
return nil
}
}
/// EZSE: Converts String to Float
public func toFloat() -> Float? {
if let num = NumberFormatter().number(from: self) {
return num.floatValue
} else {
return nil
}
}
//Converts String to Bool
public func toBool() -> Bool? {
return (self as NSString).boolValue
}
}
Use it like :
"123".toInt() // 123
i have made a simple program, where you have 2 txt field you take input form the user and add them to make it simpler to understand please find the code below.
#IBOutlet weak var result: UILabel!
#IBOutlet weak var one: UITextField!
#IBOutlet weak var two: UITextField!
#IBAction func add(sender: AnyObject) {
let count = Int(one.text!)
let cal = Int(two.text!)
let sum = count! + cal!
result.text = "Sum is \(sum)"
}
hope this helps.
Swift 3.0
Try this, you don't need to check for any condition I have done everything just use this function. Send anything string, number, float, double ,etc,. you get a number as a value or 0 if it is unable to convert your value
Function:
func getNumber(number: Any?) -> NSNumber {
guard let statusNumber:NSNumber = number as? NSNumber else
{
guard let statString:String = number as? String else
{
return 0
}
if let myInteger = Int(statString)
{
return NSNumber(value:myInteger)
}
else{
return 0
}
}
return statusNumber
}
Usage:
Add the above function in code and to convert use
let myNumber = getNumber(number: myString)
if the myString has a number or string it returns the number else it returns 0
Example 1:
let number:String = "9834"
print("printing number \(getNumber(number: number))")
Output: printing number 9834
Example 2:
let number:Double = 9834
print("printing number \(getNumber(number: number))")
Output: printing number 9834
Example 3:
let number = 9834
print("printing number \(getNumber(number: number))")
Output: printing number 9834
About int() and Swift 2.x: if you get a nil value after conversion check if you try to convert a string with a big number (for example: 1073741824), in this case try:
let bytesInternet : Int64 = Int64(bytesInternetString)!
Latest swift3 this code is simply to convert string to int
let myString = "556"
let myInt = Int(myString)
Because a string might contain non-numerical characters you should use a guard to protect the operation. Example:
guard let labelInt:Int = Int(labelString) else {
return
}
useLabelInt()
I recently got the same issue. Below solution is work for me:
let strValue = "123"
let result = (strValue as NSString).integerValue
Swift5 float or int string to int:
extension String {
func convertStringToInt() -> Int {
return Int(Double(self) ?? 0.0)
}
}
let doubleStr = "4.2"
// print 4
print(doubleStr.convertStringToInt())
let intStr = "4"
// print 4
print(intStr.convertStringToInt())
Use this:
// get the values from text boxes
let a:Double = firstText.text.bridgeToObjectiveC().doubleValue
let b:Double = secondText.text.bridgeToObjectiveC().doubleValue
// we checking against 0.0, because above function return 0.0 if it gets failed to convert
if (a != 0.0) && (b != 0.0) {
var ans = a + b
answerLabel.text = "Answer is \(ans)"
} else {
answerLabel.text = "Input values are not numberic"
}
OR
Make your UITextField KeyboardType as DecimalTab from your XIB or storyboard, and remove any if condition for doing any calculation, ie.
var ans = a + b
answerLabel.text = "Answer is \(ans)"
Because keyboard type is DecimalPad there is no chance to enter other 0-9 or .
Hope this help !!
// To convert user input (i.e string) to int for calculation.I did this , and it works.
let num:Int? = Int(firstTextField.text!);
let sum:Int = num!-2
print(sum);
This works for me
var a:Int? = Int(userInput.text!)
for Swift3.x
extension String {
func toInt(defaultValue: Int) -> Int {
if let n = Int(self.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)) {
return n
} else {
return defaultValue
}
}
}
Swift 4, Swift 5
There are different cases to convert from something to something data type, it depends the input.
If the input data type is Any, we have to use as before convert to actual data type, then convert to data type what we want. For example:
func justGetDummyString() -> Any {
return "2000"
}
let dummyString: String = (justGetDummyString() as? String) ?? "" // output = "2000"
let dummyInt: Int = Int(dummyString) ?? 0 // output = 2000
for Alternative solution. You can use extension a native type. You can test with playground.
extension String {
func add(a: Int) -> Int? {
if let b = Int(self) {
return b + a
}
else {
return nil
}
}
}
"2".add(1)
My solution is to have a general extension for string to int conversion.
extension String {
// default: it is a number suitable for your project if the string is not an integer
func toInt(default: Int) -> Int {
if let result = Int(self) {
return result
}
else {
return default
}
}
}
#IBAction func calculateAclr(_ sender: Any) {
if let addition = addition(arrayString: [txtBox1.text, txtBox2.text, txtBox3.text]) {
print("Answer = \(addition)")
lblAnswer.text = "\(addition)"
}
}
func addition(arrayString: [Any?]) -> Int? {
var answer:Int?
for arrayElement in arrayString {
if let stringValue = arrayElement, let intValue = Int(stringValue) {
answer = (answer ?? 0) + intValue
}
}
return answer
}
Question : string "4.0000" can not be convert into integer using Int("4.000")?
Answer : Int() check string is integer or not if yes then give you integer and otherwise nil. but Float or Double can convert any number string to respective Float or Double without giving nil. Example if you have "45" integer string but using Float("45") gives you 45.0 float value or using Double("4567") gives you 45.0.
Solution : NSString(string: "45.000").integerValue or Int(Float("45.000")!)! to get correct result.
An Int in Swift contains an initializer that accepts a String. It returns an optional Int? as the conversion can fail if the string contains not a number.
By using an if let statement you can validate whether the conversion succeeded.
So your code become something like this:
#IBOutlet var txtBox1 : UITextField
#IBOutlet var txtBox2 : UITextField
#IBOutlet var txtBox3 : UITextField
#IBOutlet var lblAnswer : UILabel
#IBAction func btn1(sender : AnyObject) {
let answer1 = "The acceleration is"
var answer2 = txtBox1
var answer3 = txtBox2
var answer4 = txtBox3
if let intAnswer = Int(txtBox1.text) {
// Correctly converted
}
}
Swift 5.0 and Above
Working
In case if you are splitting the String it creates two substrings and not two Strings . This below method will check for Any and convert it t0 NSNumber its easy to convert a NSNumber to Int, Float what ever data type you need.
Actual Code
//Convert Any To Number Object Removing Optional Key Word.
public func getNumber(number: Any) -> NSNumber{
guard let statusNumber:NSNumber = number as? NSNumber else {
guard let statString:String = number as? String else {
guard let statSubStr : Substring = number as? Substring else {
return 0
}
if let myInteger = Int(statSubStr) {
return NSNumber(value:myInteger)
}
else{
return 0
}
}
if let myInteger = Int(statString) {
return NSNumber(value:myInteger)
}
else if let myFloat = Float(statString) {
return NSNumber(value:myFloat)
}else {
return 0
}
}
return statusNumber }
Usage
if let hourVal = getNumber(number: hourStr) as? Int {
}
Passing String to check and convert to Double
Double(getNumber(number: dict["OUT"] ?? 0)
As of swift 3, I have to force my #%#! string & int with a "!" otherwise it just doesn't work.
For example:
let prefs = UserDefaults.standard
var counter: String!
counter = prefs.string(forKey:"counter")
print("counter: \(counter!)")
var counterInt = Int(counter!)
counterInt = counterInt! + 1
print("counterInt: \(counterInt!)")
OUTPUT:
counter: 1
counterInt: 2

Resources