How to implement NSTextFinderClient protocol in NSTextView in Swift?

I am trying to remove the visual feedback from previous searches through find-bar on an NSTextView when its contents change programatically. I need to get acces to the NSTextView's NSTextFinder so I can send it a notification of 'noteClientStringWillChange()`. For that to happen I am making the NSTextView subclass implement the NSTextFinderClient protocol, but I am getting an error saying "Type of 'string' has different optionality than required by protocol 'NSTextFinderClient'". Does anyone know how to implement the NSTextFinderClient protocol in NSTextView in swift?

Can you show us the code that causes "Type of 'string' has different optionality than required by protocol 'NSTextFinderClient'" ?

In swift the error is caused by just creating an extension of NSTextView that implements the NSTextFinderClient protocol method.

extension TextView: NSTextFinderClient {
}

This code gives the above mentioned compiler error.

Thanks. With showing some code, someone without experience of using NSTextFinderClient would help solving the issue.


As you already know, NSTextView inherits this property from NSText:

    public var string: String?

And in NSTextFinderClient, a property of the same name `string` is declared as:

    optional public var string: String { get }

An optional property with non-optional type... So confusing, but it actually has different optionality.


I'm not sure this is sort of a mistake and should-be-fixed issue, but one sure thing is that you cannot make NSTextView conform to NSTextFinderClient with the current SDK in Swift.

I couldn't find a quick workaround and you may need to make some other class conforming the needed protocol:

class MyTextFinderClient: NSObject, NSTextFinderClient {
    weak var textView: NSTextView?
    init(textView: NSTextView) {
        self.textView = textView
    }
    var string: String {return textView?.string ?? ""}
    //...
}

Thanks for confirming that the task is impossible as of right now in siwft.

I have also tried a variant of code that you have suggested. I have used the ViewController responsible for controlling the editor as the NSTextFinder's Client, but none of the protocol methods implemented in ViewController are invoked. The string property is never being fetched.

I found the solution to my problem.

Replace this


    class TextView: NSTextView, NSTextFinderClient {
        var textFinder: NSTextFinder!
    }


By


    class TextView: NSTextView {
        @IBOutlet weak var textFinder: NSTextFinder!
    }


drag and drop a TexTFinder Object into the scene that contains the TextView outlet. Link the TextView's textFinder to the TextFinderObject, and make the TextView the Outlet's client. After this you'll be able to send notifications to the FindBar like `textFinder.noteClientStringWillChange()`

or `textFinder.performAction(.HideFindInterface)`. In doing this we do not need to make TextView object confirm to the NSTextFinderClient protocol programatically.

How to implement NSTextFinderClient protocol in NSTextView in Swift?
 
 
Q