ways to call Func delegate inside Func delegate - delegates

I am new Func delegate in my existing code there is one function . can someone explain How to work with Func delegate?
public static ListColumn SetBColorFunction(this ListColumn column, Func<object, Func<object>, Color> colorFunction)
{
column.BackColorFunction = colorFunction;
return column;
}
Now i want to know what are the ways to call this above function?

Your method description:
SetBColorFunction is an extension method so you need not pass the first parameter.
It takes a method which takes a delegate and a Color as parameters and returns an object. The delegate can take a method which returns an object and doesn't take any argument.
So with this understanding try the following solutions.
Solution 1:
Color Callback(object o, Func<object> func)
{
object obj = func();
return new Color();
}
void Consumer()
{
ListColumn listColumn = new ListColumn();
listColumn.SetBColorFunction(Callback)
}
Solution 2:
Using lambda.
void Consumer()
{
ListColumn listColumn = new ListColumn();
listColumn.SetBColorFunction((obj, func) => {// Do your work and return object})
}

Related

RxSwift Delegate Binding isn't Generated?

I am trying to bind a delegate this is what was done
/** Delegate Proxy **/
func castOrThrow<T>(_ resultType: T.Type, _ object:Any) throws -> T {
guard let returnValue = object as? T else {
throw RxCocoaError.castingError(object: object, targetType: resultType)
}
return returnValue
}
#objc
public protocol TestEventGeneratorDelegate:class {
#objc optional func asyncEventResult(int:Int)
}
open class TestEventGenerator {
public var delegate: TestEventGeneratorDelegate?
func asyncCall() {
DispatchQueue.global().asyncAfter(deadline: .now() + .seconds(1)) { [weak self] in
guard let self = self else { return }
self.delegate?.asyncEventResult!(int: 0)
}
}
}
extension TestEventGenerator: HasDelegate {
public typealias Delegate = TestEventGeneratorDelegate
}
open class RxTestDelegateProxy : DelegateProxy<TestEventGenerator,TestEventGeneratorDelegate>,
DelegateProxyType,
TestEventGeneratorDelegate {
public weak private(set) var testGenerator: TestEventGenerator?
public init(testEventGenerator: ParentObject) {
self.testGenerator = testEventGenerator
super.init(parentObject: testEventGenerator, delegateProxy: RxTestDelegateProxy.self)
}
public static func registerKnownImplementations() {
self.register { RxTestDelegateProxy(testEventGenerator: $0) }
}
}
extension Reactive where Base: TestEventGenerator {
public var delegate: DelegateProxy<TestEventGenerator, TestEventGeneratorDelegate> {
return RxTestDelegateProxy.proxy(for: base)
}
public var asyncEventResult: Observable<Int> {
let source = delegate.methodInvoked(#selector(TestEventGeneratorDelegate.asyncEventResult(int:)))
.map { (a) in
return try castOrThrow(Int.self,a[0])
}
return source
}
}
/** Delegate Proxy **/
Then when I use it
let testEventGenerator = TestEventGenerator()
textEventGenerator.rx.asyncEventResult.subscribe.... // subscribe here no rx found?
testEventGenerator.asyncCall() // call and wait for the observable to return to the delegate
It doesn't compile and says there is no such rx
I have to bind it because the person who wrote the API didn't use a callback to return the value but rather a delegate.
This is example of how he wrote the code and how I want to wrap it.
Is there a way to bind a delegate that requires a kick off from asyncCall()?
so I can chain it using flatmapLatest in a promiseLike way?
Thanks let me know!
I followed these tutorial:
How to convert Delegate to Observable RxSwift?
and
https://blog.ippon.fr/2018/11/13/rxswift-how-to-make-your-favorite-delegate-based-apis-reactive/
have conform to TestEventGenerator:ReactiveCompatible and that will fix it.

How to write getter and setter for HasDelegate protocol in RxSwift?

I am implementing HasDelegate protocol to the IWDeviceManager.
In all the posts which I have read, no one has wrote getter & setter for this public var delegate property.
The compiler is explicitly asking me to write getter & setter for public var delegate. Why it's required in my case?
I tried writing but my code crashes when I try to get or set the delegate.
How do I solve this issue?
I have shared the code below
extension IWDeviceManager: HasDelegate {
public typealias Delegate = IWDeviceManagerDelegate
// Compiler explicitly asks to write getter and setter for this.
public var delegate: IWDeviceManagerDelegate? {
get { // Crashes here
return IWDeviceManager.shared()?.delegate
}
set(newValue) { // crashes here
IWDeviceManager.shared()?.delegate = newValue
}
}
}
Below is interface for IWDeviceManager
open class IWDeviceManager : NSObject {
weak open var delegate: IWDeviceManagerDelegate!
open class func shared() -> Self!
open func initMgr()
open func initMgr(with config: IWDeviceManagerConfig!)
}
Instead of using HasDelegate try this:
class IWDeviceManagerDelegateProxy
: DelegateProxy<IWDeviceManager, IWDeviceManagerDelegate>
, DelegateProxyType
, IWDeviceManagerDelegate {
init(parentObject: IWDeviceManager) {
super.init(parentObject: parentObject, delegateProxy: IWDeviceManagerDelegateProxy.self)
}
static func currentDelegate(for object: IWDeviceManager) -> Delegate? {
return object.delegate
}
static func setCurrentDelegate(_ delegate: IWDeviceManagerDelegate?, to object: IWDeviceManager) {
object.delegate = delegate
}
static func registerKnownImplementations() {
self.register { IWDeviceManagerDelegateProxy(parentObject: $0) }
}
}

rxswift bind(onNext: VS subscribe(onNext:

I have 2 questions:
What difference between 'bind(onNext:' and 'subscribe(onNext:'?
struct Info {
var index: Int?
var data: String?
}
let infoData: BehaviorRelay<Info> = BehaviorRelay<Info>(value: Info())
var osInfo: Observable<String> { return self.infoData.map({ return $0.data }).distinctUntilChanged() }
osInfo.bind { (target) in
print("bind!")
}.disposed(by: self.disposeBag)
osInfo.subscribe { (target) in
print("subscribe!")
}
.disposed(by: self.disposeBag)
a has no asObservable(), but well executable. What is difference a and b?
a. var osInfo: Observable<String> { return self.infoData.map({ return $0.data }).distinctUntilChanged() }
b. var osInfo: Observable<String> { return self.infoData.asObservable().map({ return $0.data }).distinctUntilChanged() }
What difference between 'bind(onNext:' and 'subscribe(onNext:'?
If we check out implementation of bind(...) we found that it does nothing else but just uses subscribe(...) underhood and crashes in Debug with error:
/**
Subscribes an element handler to an observable sequence.
In case error occurs in debug mode, `fatalError` will be raised.
In case error occurs in release mode, `error` will be logged.
- parameter onNext: Action to invoke for each element in the observable sequence.
- returns: Subscription object used to unsubscribe from the observable sequence.
*/
public func bind(onNext: #escaping (E) -> Void) -> Disposable {
return subscribe(onNext: onNext, onError: { error in
rxFatalErrorInDebug("Binding error: \(error)")
})
}
By using bind(onNext) you can express that stream should never emit error and you interested only in item events.
So you should use subscribe(onNext:...) when you interested in error / complete / disposed events and bind(onNext...) otherwise. But since it is part of RxCocoa and not RxSwift I usually use subscribe everywhere.
a has no asObservable(), but well executable. What is difference a and b?
map(...) is function declared on ObservableType and returning new Observable
Let's start from ObservableType.
ObservableType is protocol that require only one method: subscribe(...), this allow him to create default implementation of func asObservable().
For you it means that you can create Observable from any type that conform to ObservableType.
/// Represents a push style sequence.
public protocol ObservableType : ObservableConvertibleType {
func subscribe<O: ObserverType>(_ observer: O) -> Disposable where O.E == E
}
extension ObservableType {
/// Default implementation of converting `ObservableType` to `Observable`.
public func asObservable() -> Observable<E> {
// temporary workaround
//return Observable.create(subscribe: self.subscribe)
return Observable.create { o in
return self.subscribe(o)
}
}
}
So each time you call asObservable() underhood RxSwift just creates new Observable wrapper around your stream.
And if you check source of BehaviourRelay you will find that it conform to ObservableType as well. So you can create Observable from it anytime:
public final class BehaviorRelay<Element>: ObservableType { ... }
Now lets check map function:
extension ObservableType {
/**
Projects each element of an observable sequence into a new form.
- seealso: [map operator on reactivex.io](http://reactivex.io/documentation/operators/map.html)
- parameter transform: A transform function to apply to each source element.
- returns: An observable sequence whose elements are the result of invoking the transform function on each element of source.
*/
public func map<R>(_ transform: #escaping (E) throws -> R)
-> Observable<R> {
return self.asObservable().composeMap(transform)
}
}
As expected map just call asObservable() inside and operate on new Observable.
If we "unwrap" map call we will get:
var osInfoA: Observable<String> {
return infoData
.asObservable()
.composeMap { $0.data }
.distinctUntilChanged()
}
var osInfoB: Observable<String> {
return infoData
.asObservable()
.asObservable()
.composeMap { $0.data }
.distinctUntilChanged()
}
Sure it will not compile since composeMap is internal function but you got main idea.
Calling asObservable before other operators is redundant (most operators defined on ObservableType) and just add small overhead.

Can I store methods in an array?

Consider the following code:
class Test {
func func1(arg1: Int) -> Void {
println(arg1)
}
var funcArr: Array< (Int) -> Void > = [func1] // (!) 'Int' is not a subtype of 'Test'
}
I'm trying to store the method func1in an array, but as you can see, this doesn't seem to work because func1supposedly only takes an argument of type Test. I assume this has something to do with methods needing to be associated with an object.
For some more clarification, have a look at the following code where I let swift infer the type of the array:
class Test {
func func1(arg1: Int) -> Void {
println(arg1)
}
var funcArr = [func1]
}
Test().funcArr[0](Test()) // Compiles, but nothing gets printed.
Test().funcArr[0](1) // (!) Type 'Test' does not conform to protocol 'IntegerLiteralConvertible'
Test().func1(1) // Prints '1'
A possible workaround for this problem is moving func1outside of the class like so:
func func1(arg1: Int) -> Void {
println(arg1)
}
class Test {
var funcArr = [func1]
}
Test().funcArr[0](1) // Prints '1'
This works fine for this simple example, but is less than ideal when I actually need to operate on an Object of type Test in the function. I can of course add another parameter to the function to pass an instance of Testto the function, but this seems clunky.
Is there any way I can store methods in an array?
Ultimately, what I want to be able to do is testObject.funcArr[someInt](someParam) and have that function work as a method belonging to testObject. Any clever workarounds are of course also welcome.
Instance methods in swift are just curried functions, and the first argument is implicitly an instance of the class (i.e. self). And that's why these two are equivalent:
Test().func1(0)
Test.func1(Test())(0)
So when you try to put that function in the array, you're reveling its real nature: the method func1 on Test is actually this class method:
class func1(self_: Test)(arg1: Int)
So when you refer to simply func1 (without an "instance context") it has type Test -> Int -> Void, instead of the expected Int -> Void, and that's why you get the error
Int is not a subtype of Test
So the real issue is that when you store the methods in funcArr the instance is not known yet (or if you will, you're referring the function at a class level). You can work around this using a computed property:
var funcArr: [Int -> Void] { return [func1] } // use a computed property
Or another valuable option could be simply to acknowledge the real type of func1 and explicitly passing the instance. E.g.
...
var funcArr = [func1]
...
let test = Test()
let func1 = test.funcArr[0]
func1(test)(0) // prints 0
update
Freely inspired by this other Q/A (Make self weak in methods in Swift) I came up with a similar solution that stores the method references.
func weakRef<T: AnyObject, A, B>(weakSelf: T, method: T -> A -> B) -> A -> B {
return { [unowned weakSelf] in { a in method(weakSelf)(a) } }()
}
class Test {
var methodRefs: [Int -> Void] = []
init() {
methodRefs.append(weakRef(self, Test.func1))
}
func func1(arg1: Int) {
println(arg1)
}
}
In order to store a method, you should remember that the method is invoked on a class instance. What's actually stored in the array is a curried function:
(Test) -> (Int) -> Void
The first function takes a class instance and returns another function, the actual (Int) -> Void method, which is then invoked on that instance.
To make it more explicit, the array type is:
var funcArr: [(Test) -> (Int) -> Void] = [Test.func1]
Then you can invoke the method with code like this:
var test = Test()
var method = test.funcArr[0]
method(test)(1)
Suggested reading: Curried Functions

How to get the correct callback value for NSUndoManager in Swift?

I have an NSDocument subclass, hooked up to an NSArrayController. For reference, I'm trying to translate the example from chapter 9 of Cocoa Programming for Mac OS X Fourth Edition.
It seems that from this question that I asked before, I need to use object-based undo with NSUndoManager. In order to pass two values to the method being invoked, I'm packaging them into an NSObject subclass with two instance variables.
When the KVO methods for inserting and deleting from the employees array are called by clicking on the buttons in my application, they work as expected.
However, when removeObjectFromEmployeesAtIndex is called during an undo operation, the index passed in is wildly out of bounds (for the first row, it always seems to be 55, then after that the index increases into the thousands for the next few rows).
How can I get the correct index to perform the undo action?
class Document: NSDocument {
var employee_list: Array<Person> = []
var employees: Array<Person> {
get {
return self.employee_list
}
set {
if newValue == self.employee_list {
return
}
self.employee_list = newValue
}
}
func insertObject(person: Person, inEmployeesAtIndex index: Int) {
self.undoManager.registerUndoWithTarget(self, selector: Selector("removeObjectFromEmployeesAtIndex:"), object: index)
if (!self.undoManager.undoing) {
self.undoManager.setActionName("Add Person")
}
employees.insert(person, atIndex: index)
}
func removeObjectFromEmployeesAtIndex(index: Int) {
let person = self.employees[index]
let pair = PersonIndexPair(person: person, index: index)
self.undoManager.registerUndoWithTarget(self, selector: Selector("insertPersonIndexPair:"), object: pair)
if (!self.undoManager.undoing) {
self.undoManager.setActionName("Remove Person")
}
employees.removeAtIndex(index)
}
func insertPersonIndexPair(pair: PersonIndexPair) {
insertObject(pair.person, inEmployeesAtIndex: pair.index)
}
}
Edit: I've worked around the issue by passing a string, but this seems pretty obtuse:
self.undoManager.registerUndoWithTarget(self, selector: Selector("removeObjectFromEmployeesAtStringIndex:"), object: String(index))
//...
func removeObjectFromEmployeesAtStringIndex(index: String) {
if let i = index.toInt() {
removeObjectFromEmployeesAtIndex(i)
}
}
Use NSNumber instead of Int.
self.undoManager.registerUndoWithTarget(self, selector:Selector("removeObjectFromEmployeesAtStringIndex:"), object: NSNumber(integer: index))
//...
func removeObjectFromEmployeesAtStringIndex(index: NSNumber) {
removeObjectFromEmployeesAtIndex(index.integerValue)
}
I am reading Cocoa Programming for Mac OS X now. I translate the sample Object-C code as below, only need to append it to class Document:
func insertObject(p: Person, inEmployeesAtIndex index: Int) {
//NSLog("adding %# to %#", p, employees)
let undo = self.undoManager
undo!.prepareWithInvocationTarget(self).removeObjectFromEmployeesAtIndex(index)
if !undo!.undoing {
undo!.setActionName("Add Person")
}
employees.insertObject(p, atIndex: index)
}
func removeObjectFromEmployeesAtIndex(index: Int) {
let p = employees.objectAtIndex(index) as! Person
//NSLog("Removing %# from %#", p, index)
let undo = self.undoManager
undo!.prepareWithInvocationTarget(self).insertObject(p, inEmployeesAtIndex: index)
if !undo!.undoing {
undo!.setActionName("Remove Person")
}
employees.removeObjectAtIndex(index)
}
I think it's cleanest to replace the old-fashioned Objective-C NSUndoManager method entirely:
private class SwiftUndoPerformer: NSObject {
let closure: Void -> Void
init(closure: Void -> Void) {
self.closure = closure
}
#objc func performWithSelf(retainedSelf: SwiftUndoPerformer) {
closure()
}
}
extension NSUndoManager {
func registerUndo(closure: Void -> Void) {
let performer = SwiftUndoPerformer(closure: closure)
registerUndoWithTarget(performer, selector: Selector("performWithSelf:"), object: performer)
//(Passes unnecessary object to get undo manager to retain SwiftUndoPerformer)
}
}
Then you can Swift-ly register any closure, and not worry about wrapping things up to get around an outdated interface:
undoManager.registerUndo {
self.insertObject(person, inEmployeesAtIndex: index)
}

Resources