NEW: My new book Pro SwiftUI is out now – level up your SwiftUI skills today! >>

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 RevenueCat

SPONSORED In-app subscriptions are a pain to implement, hard to test, and full of edge cases. RevenueCat makes it straightforward and reliable so you can get back to building your app. Oh, and it's free if your app makes less than $10k/mo.

Learn 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.