WWDC22 SALE: Save 50% on all my Swift books and bundles! >>

Fatal error when converting user provided String to Integer

Forums > Swift

Hi everybody

In my custom NumberTextField I'm currently writing, I'm trying to generically convert Strings to the corresponding BinaryInteger (e.g. Int16 or Int) using the newly introduced initializer: init(String, format: IntegerFormatStyle<Self>, lenient: Bool)

https://developer.apple.com/documentation/swift/binaryinteger/3869983-init

(Yes, currently there is no documentation available @Apple :-))

I hit the following roadblock: the function is defined as throwing, and I am trying to catch the exception. But the function is causing a fatal error in the application:

Fatal error: Not enough bits to represent the passed value

You can try it yourself in a playground with the following code:

import Foundation

var tooBig = "32800"
if let value = try? Int16(tooBig, format: IntegerFormatStyle.number) {
    print("valid number", value)
} else {
    print("conversion issue")
}

What methods are you using to convert a (user provided) string to a number in Swift?

PS: Note, I'm using this under macOS, but I suppose the problem is the same on iOS

   

I think this is not an issue in the Swift language but in the Foundation framework using the wrong initializer of BinaryInteger (not a failable one). I know, it's not of any help to anybody but I filed a bug: FB9968041

My current workaround is now something I've found on HWS (where else ;-)):

var tooBig = "32800"
if var value = Int16(exactly: (tooBig as NSString).integerValue) {
    print("valid number", value)
} else {
    print("conversion issue")
}

This is rather ugly because we need the bridge to Objective-C world NSString first, converting to NSInteger, bridging back to Int and then converting to the desired type (here Int16).

I explored this new way of parsing just because I wanted to get rid of NSNumberFormatter and do it more "Swifty" 🙈. Mission failed...

   

What methods are you using to convert a (user provided) string to a number in Swift?

Why couldn't you do something like this?

import Foundation

var tooBig = "65000"

let value = Int16(tooBig)
if let value = value {
    print(value)
} else {
    print("Not a valid Int16")
}

let value2 = Int(tooBig)
if let value2 = value2 {
    print(value2)
} else {
    print("Not a valid integer.")
}

   

Hi @pd95

Why are you converting to Int16? The reason you getting error that it can not convert the number into Int16 that size number would require Int32 or higher.

You would be better convert to Int (unless you saving to iCloud or CoreData, then you can use a alert to user that it invalid number as @vtabmow did in example).

   

The thing is a bit more complicated then what I've explained above.

My target is to write a NumberTextField (used mainly on macOS), allowing to enter BinaryInteger based numbers. So it is generic... see my current implementation

In advance, I do not know if the "user" (=programmer) is using Int, Int32, Int16, UInt, ... we basically have to rely on what is given by BinaryInteger protocol. Luckily, the initializer below is definied on this protocol:

init(String, format: IntegerFormatStyle<Self>, lenient: Bool)

(see Apple Documentation)

So it would be possible to let the user of this NumberTextField use the format option...

Why to I write this NumberTextField at all? TextField already has this format initializer! Yes, but it does not allow you to properly restrict the the values entered by the user.

   

Hacking with Swift is sponsored by Emerge

SPONSORED Why are Swift reference types bad for app startup time, and what’s the performance cost of protocol conformances? That’s just a couple of the topics you can learn about on the Emerge blog — written by the app performance experts behind Emerge’s advanced app optimization and monitoring tools, based on their experience of working at companies like Apple, Airbnb, Snap, and Spotify.

Find out more

Sponsor Hacking with Swift and reach the world's largest Swift community!

Reply to this topic…

You need to create an account or log in to reply.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.