Reputation: 944
Calling parseString
crashes my application. myOptionalString
is getting set from didSelectRowAtIndexPath
in a tableview. The information is definitely get passed to this view controller.
The method also works if called from a button press. But in any life cycle method I try I get unexpectedly found nil while unwrapping an Optional.
override func viewDidLoad() {
super.viewDidLoad()
if let myUnwrappedString = myOptionalString{
print(myUnwrappedString) //<-- prints out string
confidence.text = parseString(myUnwrappedString) //<-- unexpectedly found nil while unwrapping an Optional crash
}
}
//this method works if called on a button press but crashes in viewDidLoad
func parseString(myString: String)->String{
return myString.substringFromIndex(myString.rangeOfString(" ")!.endIndex)
}
Upvotes: 1
Views: 646
Reputation: 23449
Your error come from your function parseString
, let's see why. If you see carefully your function you're make a force-unwrapping of an optional value in your case the myString.rangeOfString(" ")!
. This is not recommended at all.
If we pass the string "Confidence: 63%"
to the function the function works properly and returns "63%"
, but it works because it have the " "
string inside, if for some reason you pass some string that don't have it it will crash (e.g "Confidence:63%"
).
So one of the correct ways of implement this function can be using the guard
statement using optional binding avoiding any force-unwrapping:
func parseString(myString: String) -> String? {
guard let range = myString.rangeOfString(" ") else { return nil }
return myString.substringFromIndex(range.endIndex)
}
In the above function you return nil
in case of not exist the " "
in the string and avoid the runtime error.
I hope this help you.
Upvotes: 3
Reputation: 6876
I'm guessing your problem lies in this line:
myString.rangeOfString(" ")!
rangeOfString
returns an optional Range<Index>?
value, meaning that if the character you are looking for is not present in the string, you will get the value nil
in return. In other words, if there is no space in your string, you get a nil
value for your range.
That value you then force unwrap with !
, and then you use it to call substringFromIndex
. This means that if the range was actually nil
, you use that nil
value to try to create a substring from its endIndex
... which you cannot...so it crashes.
One way of solving this could be to use a guard
to make sure that you actually found a range in your string. If you don't, then you just return an empty String
...or do something else that suits your use case better.
Here is an example:
func parseString(myString: String)->String{
guard let range = myString.rangeOfString(" ") else {
return ""
}
return myString.substringFromIndex(range.endIndex)
}
Hope that helps you.
Upvotes: 0