Brian
Brian

Reputation: 944

calling function in viewDidLoad crash

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

Answers (2)

Victor Sigler
Victor Sigler

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

pbodsk
pbodsk

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 guardto 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

Related Questions