https://kotlinlang.org logo
#multiplatform
Title
# multiplatform
v

vanniktech

04/16/2020, 4:37 PM
Has anyone written an
apply
method on iOS that’s behaving similar to Kotlin’s apply?
s

Sam

04/16/2020, 5:33 PM
As in a Swift extension?
v

vanniktech

04/16/2020, 5:52 PM
Yeah
s

Sam

04/16/2020, 7:12 PM
I’ve never been able to figure out a good way to do it. You can’t add extensions to
Any
or
AnyObject
. You can do something like this:
Copy code
protocol Applier {
    associatedtype Applying
    func apply(_ fn: (Applying) -> Void) -> Applying
}

extension Applier {
    func apply(_ fn: (Applying) -> Void) -> Applying{
        fn(self as! Self.Applying)
        return self as! Self.Applying
    }
}

class Foo {
    var bar = "baz"
}

extension Foo: Applier {
    typealias Applying = Foo
}


let foo = Foo().apply { `self` in
    self.bar = "baz2"
}

print(foo.bar)

class Foo2: Foo {
    var baz = "foo"
}

let foo2 = Foo2().apply { `self` in
    self.bar = "baz2"
    //self.baz = "Does not work.  Self is of type Foo"
}
It isn’t very useful though as you have to declare the conformance of the type to the
Applier
protocol for each class you want to use it on. The other caveat is the subclass issue. If you make
UIView
conform to the protocol and try to use it on a subclass such as
UILabel
, the type of the argument passed into your apply function is
UIView
which is only minimally useful. Also there should be a way to do the above without the force casts. I’m just too tired to parse through all of the protocol associated type nuances right now.
I do have a decent version of
let
for Swift. It can only be used on optionals which is about 99% of when I use a
let
function anyway.
Copy code
extension Optional {
    /// Function similar to Kotlin let that executes a block of code on an optional if the optional has a value.
    ///
    /// - Parameter execute: The block to be executed.
    func `let`(_ execute: (Wrapped) -> Void) {
        if let wrapped = self {
            execute(wrapped)
        }
    }
}
v

vanniktech

04/16/2020, 7:20 PM
Argh. That
apply
looks really distasteful. That
let
function should come handy though, thanks
s

Sam

04/16/2020, 8:08 PM
Yeah, I don’t use it nor recommend it. I did ask on Stackoverflow how to improve it. Maybe someone there has an idea. https://stackoverflow.com/questions/61259143/implementing-kotlin-apply-function-in-swift
So my mistake was in specifying the function in the protocol. Have a look at this gist that is linked in one of the SO articles from my question. https://gist.github.com/kakajika/0bb3fd14f4afd5e5c2ec You still have to add the protocol conformance for every swift object you would want to add apply to. However adding it to
NSObject
will make it apply to every object in
UIKit
and any other Swift object that has the
@objc
attribute.
v

vanniktech

04/17/2020, 7:29 AM
That’s neat
2 Views