0

I can't get around this error. When I run this function I get a fatal error. fatal error: unexpectedly found nil while unwrapping an Optional value below is the function:

func changeSelectedFontColor(fontColor: UIColor) {

    let selectedRange : NSRange = self.textView.selectedRange

    var currentAttributesDict : NSDictionary = textView.textStorage.attributesAtIndex(selectedRange.location, effectiveRange: nil)

    var currentFont : UIFont = currentAttributesDict.objectForKey(NSFontAttributeName) as UIFont

    let italFont = [NSFontAttributeName:UIFont(name: "Georgia-Italic", size: 18.0)]

    var currentColor : UIColor = currentAttributesDict.objectForKey(NSForegroundColorAttributeName) as UIColor

    var currentBGColor : UIColor = currentAttributesDict.objectForKey(NSBackgroundColorAttributeName) as UIColor

    var currentUnderlinedText : UIFont = currentAttributesDict.objectForKey(NSUnderlineStyleAttributeName) as UIFont

    var currentparagraphStyle : NSMutableParagraphStyle = currentAttributesDict.objectForKey(NSParagraphStyleAttributeName) as NSMutableParagraphStyle
}
Jeffery Thomas
  • 42,202
  • 8
  • 92
  • 117
LearningGuy
  • 191
  • 2
  • 12
  • Possible duplicate of [What does "fatal error: unexpectedly found nil while unwrapping an Optional value" mean?](https://stackoverflow.com/questions/32170456/what-does-fatal-error-unexpectedly-found-nil-while-unwrapping-an-optional-valu) – Cristik Mar 19 '18 at 06:05

3 Answers3

1

In all lines like this:

var currentFont : UIFont = currentAttributesDict.objectForKey(NSFontAttributeName) as UIFont

you are extracting a value from a dictionary and doing an explicit cast (to UIFont in this case). All of these lines can fail for any of the following reasons:

  • the specified key doesn't exist in the dictionary, so objectForKey returns nil, and the cast fails
  • the value exists, but it's not of the type you are casting it to, so the cast fails

I don't how you are going to use all these variables, so I cannot provide a proper answer that best solves your problem.

However, you can get rid of the runtime exception by using an optional cast, replacing as with as?. Note that it will turn all the expression results into optionals, so for example in the line of code above, current font would be of UIFont? type:

var currentFont : UIFont? = currentAttributesDict.objectForKey(NSFontAttributeName) as? UIFont

What to do with all these optional variables is up to you: you can use optional binding (but I expect a large number of nested if), or just use them as optionals, if possible.

Antonio
  • 71,651
  • 11
  • 148
  • 165
  • I am building a Text Editor and am using these variables to check to see if there are already some format changes to the selected text. if there is, I can add them to the current change. for example maybe the selected text is underlined and I later want to change the color of the text. I need to check to see if the Underline property is set and then add it to the attributed string along with the new changes so all changes will persist. I hope I explained the well enough. – LearningGuy Nov 07 '14 at 14:10
  • In that case for each variable you should use [optional binding](https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/TheBasics.html#//apple_ref/doc/uid/TP40014097-CH5-XID_503) to check if a value is not nil, and do whatever you need – Antonio Nov 07 '14 at 14:32
0

ObjectForKey will return an optional, you should use as? to cast it to an optional and check its value.

let value = dict.objectForKey("hello") as? String

value is an optional and you can do

if value == nil {}

Or

if let value = dict.objectForKey("hello") as? String {

}
Shuo
  • 8,447
  • 4
  • 30
  • 36
0

You are not testing for nil. objectForKey(_:) returns an optional which you force unwrap (by using as), so if objectForKey(_:) returns nil, then you crash.

You can either keep the values as optionals using as?

var currentColor: UIColor? currentAttributesDict[NSForegroundColorAttributeName] as? UIColor

or you can provide a default value using the ?? operator.

var currentColor: UIColor currentAttributesDict[NSForegroundColorAttributeName] as? UIColor ?? UIColor.blackColor()

NOTE: instead of using objectForKey(_:), you can use []. I think it reads better.

Jeffery Thomas
  • 42,202
  • 8
  • 92
  • 117