Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom NSFormatter returning nil in swift

I have an NSFormatter in Swift, which is attached to an NSTextField. It prevents illegal characters from being entered, but when I try to access the value of the next field it gives a nil value.

Below is the class:

class PSEntryNameFormatter : NSFormatter {
    override func stringForObjectValue(obj: AnyObject?) -> String? {

        if obj == nil {
            println("stringForObjectValue: obj is nil, returning nil")
            return nil
        }
        if let o = obj as? String {
                println("stringForObjectValue:  obj is string, returning \(o)")
                return o
            }

        println("stringForObjectValue: obj is not string, returning nil")
        return nil
    }

    override func getObjectValue(obj: AutoreleasingUnsafeMutablePointer<AnyObject?>, forString string: String, errorDescription error: AutoreleasingUnsafeMutablePointer<NSString?>) -> Bool {
        println("getObjectValue: \(string)")
        let obj = string
        return true
    }

    override func isPartialStringValid(partialString: String?, newEditingString newString: AutoreleasingUnsafeMutablePointer<NSString?>, errorDescription error: AutoreleasingUnsafeMutablePointer<NSString?>) -> Bool {
        if let s = partialString {
            var illegals : String = join("",s.componentsSeparatedByCharactersInSet(PSEntryNameFormatterCharacterSet))
            var goods = s.componentsSeparatedByCharactersInSet(NSCharacterSet(charactersInString: illegals))
            let newString : NSString = join("", goods)

            if String(newString) == s {
                println("isPartialStringValid: partial string ok")
                return true
            }
        }

        println("isPartialStringValid: partial string bad")
        return false
    }
}

And here is how I try to access:

func control(control: NSControl, textShouldEndEditing fieldEditor: NSText) -> Bool {
    println("Text should end editing")
    if (control == nameTextField) {
        var name = nameTextField.objectValue as String
        setObjectName(name)
    }
    return true
}

For debugging I add the println statements, and here is what happens when the textfield is set to 'Template' and then I delete two characters:

stringForObjectValue:  obj is string, returning Template
stringForObjectValue:  obj is string, returning Template
isPartialStringValid: partial string ok
getObjectValue: Templat
isPartialStringValid: partial string ok
getObjectValue: Templa

Then I press enter:

getObjectValue: Templa
Text should end editing 
getObjectValue: Templa
stringForObjectValue: obj is nil, returning nil
getObjectValue:
stringForObjectValue: obj is nil, returning nil
stringForObjectValue: obj is nil, returning nil
fatal error: unexpectedly found nil while unwrapping an Optional value

And then it crashes on the line when I cast to string. Obviously I can prevent the crash, but first I want to find out why it is returning nil. Any help very much appreciated!

like image 400
James Alvarez Avatar asked Oct 27 '14 15:10

James Alvarez


1 Answers

The problem is in your getObjectValue function.

You should be assigning the value in this manner:

obj.memory = string

instead of

let obj = string
like image 68
Kevin Avatar answered Sep 18 '22 12:09

Kevin