generic function with binding generic variable in Swift - swift

can anyone explain what exactly does below generic class "Active" works with this - bind variable ? Below are 3 examples mentioned also but I'm really not clear how does it work
class Active<T> {
var bind :(T) -> () = { _ in }
var value :T {
didSet {
bind(value)
}
}
init(_ v :T) {
value = v
}
}
Example :
var user = Active("")
var count = Active(64)
var status = Active(true)
Exact example shown in below link
https://levelup.gitconnected.com/2-ways-to-execute-mvvm-ios-5c47d60ebcd0

If you're familiar with completion handlers, then this will make perfect sense to you. Consider a function with a barebones completion handler:
func someFunction(completion: () -> Void) {
completion()
}
someFunction {
print("completion")
}
The completion handler has no parameters and so it is called with completion() and the closure's capture list someFunction { ... } is empty. However, if we were to add a parameter to this completion handler, then it would be called with the parameter completion(true) and the closure would have to define its capture list someFunction { (done) in ... }.
func someFunction(completion: (_ done: Bool) -> Void) {
completion(true)
}
someFunction { (done) in
print(done)
}
And if we didn't care about the boolean in the completion handler then we could ignore it in the closure's capture list:
someFunction { _ in
print("completion")
}
And this is what bind is, a closure with a single parameter with a capture list that doesn't care about the parameter it was passed.
var bind: (T) -> Void = { _ in }
So the idea is to instantiate Active, with a value, and then give bind a closure to execute whenever the value changes. And so when it changes, you have bound some task to the changing of that value.
// instantiate
var count = Active(64)
// bind its change to a closure
count.bind = { _ in
// perhaps update the UI?
}
// later when the value changes, the closure is called and
// whatever task you had in the closure is executed
count.value = 128
And, as a side note, T is just an arbitrary letter (it could be 🌮) used as a placeholder for whatever type will actually be used (i.e. Int, Bool) when this object is instantiated. Whatever T is, it has to be the same type throughout the use of this object.

You give examples where you instantiate Active with different types of values (illustrating the generic behavior). But you are not availing yourself of the “observer” pattern that Active affords.
Let’s see how you would use Active:
let foo = Active(0)
foo.bind = { value in
print(value)
}
foo.value = 1 // the closure will be called, printing the value
foo.value = 42 // the closure will be called again
The idea is that you instantiate the object, replace the bind closure with your own, and then the closure will be called every time you change the value.
The virtue of this “observer” pattern is that Active is providing a mechanism (a simple closure in this primitive example) to allow other objects to observe changes to the value. This is one of the central precepts of MVVM (as that article you quote is attempting to convey), namely, that you can write code that, for example, automatically updates a view based upon changes to a model.

Related

Uncertain of this Swift struct syntax with closure

I'm stumped by a bit of Swift struct syntax.
For a regular struct, I understand how to define and initialize it.
struct Thing {
let name: String
}
let aThing = Thing(name: "The Name")
But I was reading a bit about functional programming and came across this syntax and what stumped me most was the initialization.
struct Effect<T> {
let run: (#escaping (T) -> Void) -> Void
}
// What is "callback" here? How does this work?
let anIntInTwoSeconds = Effect<Int> { callback in
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
callback(42)
}
}
anIntInTwoSeconds.run { theInt in
print(theInt)
}
If I were to see that with a "normal" initializer, I would understand it, but what is happening on this line? What is this syntax called so I can research it further?
let anIntInTwoSeconds = Effect<Int> { callback in
The declaration for the Effect type
struct Effect<T> {
Defines Effect as using a Generic type T. So you can create Effect objects that work on different types.
The line
let anIntInTwoSeconds = Effect<Int> { callback in
Creates an Effect object that operates on Ints, and assigns it to the variable anIntInTwoSeconds.
The { callback in part defines the closure for the Effect object. That declaration could be rewritten like this:
let anIntInTwoSeconds = Effect<Int>(run: { callback in
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
callback(42)
}
}
)
You can interpret as:
'Create an instance of the Effect struct, with a run property that contains the closure that begins with "{ callback in"...'
(It's confusing because the run property is, itself, a closure. So we create an instance of Effect, and pass it a "run" value that's a closure.)
The "callback in" part, specifically, tells the compiler that, inside that closure, the parameter to the closure should be named "callback".

What's the difference between the two closure

I tried comment and uncomment the activity() in the following code. I found when I commented the activity() the result in playground would just show "play tennis" once. However it would show twice if I uncommented activity(). What's the difference between the two statements?
class Baby {
var name = "peter"
var favoriteActivity: (() -> ())!
func outsideActivity(activity: #escaping () -> ()) {
//activity()
favoriteActivity = activity
}
}
var cuteBaby = Baby()
cuteBaby.outsideActivity {
print("play tennis")
}
cuteBaby.favoriteActivity()
This is what’s going on:
Consider this method:
func outsideActivity(activity: #escaping () -> ()) {
//activity()
favoriteActivity = activity
}
All that does is save the closure in the favoriteActivity property
Thus, when you do:
// create `Baby` instance
var cuteBaby = Baby()
// this method saves closure in `favoriteActivity`, but doesn’t call it
cuteBaby.outsideActivity {
print("play tennis")
}
// this now calls the closure
cuteBaby.favoriteActivity()
All the outsideActivity method does is save the closure in a property called favoriteActivity.
Thus you see one print statement.
However, now consider this method:
func outsideActivity(activity: #escaping () -> ()) {
activity()
favoriteActivity = activity
}
This actually calls the closure before saving it in the property.
So, when you do:
// create `Baby` instance
var cuteBaby = Baby()
// this method both calls the closure and then also saves it in `favoriteActivity`
cuteBaby.outsideActivity {
print("play tennis")
}
// this now calls the saved closure a second time
cuteBaby.favoriteActivity()
In this case, you’ll see your print statement being called twice.
That’s why the first rendition calls the closure only once, whereas the second calls the closure twice.
Usually when you pass a closure to a method, you either (a) call the closure from within the method (perhaps in some completion handler or the like); or (b) save the closure in some property so you can call it later.
So, this second example is very unusual, where outsideActivity both calls the closure itself and saves that closure in some property so you can call it again later. You usually do one or the other, but not both.

Difference between Closure Functions and Functions

I'm trying to learn swift and came across closures got the hang of it but still I have a question to ask, couldn't find any answers on the internet and I'm not sure if it's appropriate to ask here but I really need an answer on this.
say we have the following class
class Human{
var gender:String?
private func fCheckGender(pGender:String?){
guard pGender != nil else {
print("Gender not specified")
return
}
if pGender == "M"{
print("Male")
}
else if pGender == "F"{
print("Female")
}
else{
print("gender Unknown")
}
}
private func cCheckGender( pGender:#autoclosure ()->(String?)){
guard pGender() != nil else {
print("Gender not specified")
return
}
if pGender() == "M"{
print("Male")
}
else if pGender() == "F"{
print("Female")
}
else{
print("gender Unknown")
}
}
func MyCheckGender(){
fCheckGender(pGender: gender)
cCheckGender(pGender: gender)
}
}
var myHuman:Human = Human()
myHuman.gender = "M"
myHuman.MyCheckGender()
I would like to know the difference of
fCheckGender and cCheckGender when and where should I use the closures
Thanks in advance!
P.S I have intentionally used void->String ()->(String?)
I only want to learn the difference in this scenario. I'm sorry for my bad english
Closure:
Closure is a block of code, treat it like an unnamed function.
When a closure is passed as an argument, the closure is not evaluated till the code inside the function invokes the argument.
Auto closure:
Auto closure is just a closure which packages the parameter values along with it.
When you define an autoclosure, there would be no parameters to the closure.
Difference between fCheckGender and cCheckGender:
fCheckGender takes a String value as an argument.
cCheckGender takes closure as an argument.
When cCheckGender is invoked, the closure is passed an argument, at this point, the closure is only passed as an argument, the closure is not executed. Only when the closure parameter is used inside the function, the closure gets executed.
The example you have stated might not be the best one to demonstrate the difference.
Let's consider a different example:
Example:
func add(a: Int, b: Int) -> Int {
print("add")
return a + b
}
func f1(pValue: Int) {
print("f1")
print("value = \(pValue)")
}
func f2(pClosure: (Int, Int) -> Int, pA: Int, pB: Int) {
print("f2")
let value = pClosure(pA, pB)
print("value = \(value)")
}
//In autoclosure the closure always takes no parameters, because the closure is packaged with parameter values while invoking
func f3(pClosure: #autoclosure () -> Int) {
print("f3")
let value = pClosure()
print("value = \(value)")
}
f1(pValue: add(a: 10, b: 20))
print("=====================\n")
f2(pClosure: add, pA: 10, pB: 20)
print("=====================\n")
f3(pClosure: add(a: 10, b: 20))
print("=====================\n")
Output:
add
f1
value = 30
=====================
f2
add
value = 30
=====================
f3
add
value = 30
=====================
Explanation of example:
In the function f1 pValue is an Int value.
So when f1 is invoked, the add is evaluated
In the functions f2 and f3 pClosure is a closure.
pClosure (closure) is not evaluated till it is invoked inside the function.
Note:
Focus on f3 first which accepts a closure as the argument.
Once you fully understand f3, then examine f2.
Auto closure captures the parameter values when it is invoked and later uses it.
Why and when do we need to pass a closure instead of a value:
There might be a scenario, where you would like to defer the execution of add till the time the function f2 invokes it.
There might be a scenario, where you make an asynchronous request and you want a piece of code to execute when the request completes. In this case you might pass a closure. (Closure need not always return a value, it is an unnamed function, so it can accept parameters)
Why and when do we need to an autoclosure:
When you want to defer the execution of add and also capture the value of it's parameters.
Suggestion:
Though time consuming, it is best for you to go through the Swift documentation from the beginning to fully understand it.
Reference:
As Hamish has pointed please read about closures, then auto closures from https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Closures.html
Function
In the function createUser the firebase runs background of the app so when the user enters button of the login app the function "RegisteredButtonPressed" is trigged.
Inside the registeredButtonPressed function the username & password are given by the user if its correct then "completion" function is trigerred. After that "completed" function will be activated the it prints into console.
same code concept I have written in closure.
class Firebase {
func createUser (username: String, password: String, completion: (Bool, Int) -> Void) {
let isSuccess = true
let userID = 123
completion(isSuccess, userID)
}
}
class MYApp {
func registerButtonPressed () {
let firebase = Firebase()
firebase.createUser(username: "Gullu", password: "123456", completion: completed(isSuccess:userID:))
}
func completed (isSuccess: Bool, userID: Int) {
print("Registration id is success \(isSuccess)")
print("User id is \(userID)")
}
}
Closure
Converting func keyword to closure
remove the func keyword & name of function
Bring the starting curly bracket after func starts in the beginning (in "func completed" after userid: Int a curly bracket is there , so bring it before the second bracket starts).
Replace it with "in" keyword
instead of calling the completed function cut paste the 3rd point above code & paste it to completion inside firebase.creativeUser
Delete the completion parameter to make it trailing closure
class MYApp {
func registerButtonPressed () {
let firebase = Firebase()
firebase.createUser(username: "Gullu", password: "123456") {
(isSuccess: Bool, userID: Int) in
print("Registration id is success \(isSuccess)")
print("User id is \(userID)")
}
}
}

"Closure cannot implicitly capture a mutating self parameter" - after updating to Swift 3 [duplicate]

I am using Firebase to observe event and then setting an image inside completion handler
FirebaseRef.observeSingleEvent(of: .value, with: { (snapshot) in
if let _ = snapshot.value as? NSNull {
self.img = UIImage(named:"Some-image")!
} else {
self.img = UIImage(named: "some-other-image")!
}
})
However I am getting this error
Closure cannot implicitly capture a mutating self parameter
I am not sure what this error is about and searching for solutions hasn't helped
The short version
The type owning your call to FirebaseRef.observeSingleEvent(of:with:) is most likely a value type (a struct?), in which case a mutating context may not explicitly capture self in an #escaping closure.
The simple solution is to update your owning type to a reference once (class).
The longer version
The observeSingleEvent(of:with:) method of Firebase is declared as follows
func observeSingleEvent(of eventType: FIRDataEventType,
with block: #escaping (FIRDataSnapshot) -> Void)
The block closure is marked with the #escaping parameter attribute, which means it may escape the body of its function, and even the lifetime of self (in your context). Using this knowledge, we construct a more minimal example which we may analyze:
struct Foo {
private func bar(with block: #escaping () -> ()) { block() }
mutating func bax() {
bar { print(self) } // this closure may outlive 'self'
/* error: closure cannot implicitly capture a
mutating self parameter */
}
}
Now, the error message becomes more telling, and we turn to the following evolution proposal was implemented in Swift 3:
SE-0035: Limiting inout capture to #noescape contexts
Stating [emphasis mine]:
Capturing an inout parameter, including self in a mutating
method, becomes an error in an escapable closure literal, unless the
capture is made explicit (and thereby immutable).
Now, this is a key point. For a value type (e.g. struct), which I believe is also the case for the type that owns the call to observeSingleEvent(...) in your example, such an explicit capture is not possible, afaik (since we are working with a value type, and not a reference one).
The simplest solution to this issue would be making the type owning the observeSingleEvent(...) a reference type, e.g. a class, rather than a struct:
class Foo {
init() {}
private func bar(with block: #escaping () -> ()) { block() }
func bax() {
bar { print(self) }
}
}
Just beware that this will capture self by a strong reference; depending on your context (I haven't used Firebase myself, so I wouldn't know), you might want to explicitly capture self weakly, e.g.
FirebaseRef.observeSingleEvent(of: .value, with: { [weak self] (snapshot) in ...
Sync Solution
If you need to mutate a value type (struct) in a closure, that may only work synchronously, but not for async calls, if you write it like this:
struct Banana {
var isPeeled = false
mutating func peel() {
var result = self
SomeService.synchronousClosure { foo in
result.isPeeled = foo.peelingSuccess
}
self = result
}
}
You cannot otherwise capture a "mutating self" with value types except by providing a mutable (hence var) copy.
Why not Async?
The reason this does not work in async contexts is: you can still mutate result without compiler error, but you cannot assign the mutated result back to self. Still, there'll be no error, but self will never change because the method (peel()) exits before the closure is even dispatched.
To circumvent this, you may try to change your code to change the async call to synchronous execution by waiting for it to finish. While technically possible, this probably defeats the purpose of the async API you're interacting with, and you'd be better off changing your approach.
Changing struct to class is a technically sound option, but doesn't address the real problem. In our example, now being a class Banana, its property can be changed asynchronously who-knows-when. That will cause trouble because it's hard to understand. You're better off writing an API handler outside the model itself and upon finished execution fetch and change the model object. Without more context, it is hard to give a fitting example. (I assume this is model code because self.img is mutated in the OP's code.)
Adding "async anti-corruption" objects may help
I'm thinking about something among the lines of this:
a BananaNetworkRequestHandler executes requests asynchronously and then reports the resulting BananaPeelingResult back to a BananaStore
The BananaStore then takes the appropriate Banana from its inside by looking for peelingResult.bananaID
Having found an object with banana.bananaID == peelingResult.bananaID, it then sets banana.isPeeled = peelingResult.isPeeled,
finally replacing the original object with the mutated instance.
You see, from the quest to find a simple fix it can become quite involved easily, especially if the necessary changes include changing the architecture of the app.
If someone is stumbling upon this page (from search) and you are defining a protocol / protocol extension, then it might help if you declare your protocol as class bound. Like this:
protocol MyProtocol: class {
...
}
You can try this! I hope to help you.
struct Mutating {
var name = "Sen Wang"
mutating func changeName(com : #escaping () -> Void) {
var muating = self {
didSet {
print("didSet")
self = muating
}
}
execute {
DispatchQueue.global(qos: .background).asyncAfter(deadline: .now() + 15, execute: {
muating.name = "Wang Sen"
com()
})
}
}
func execute(with closure: #escaping () -> ()) { closure() }
}
var m = Mutating()
print(m.name) /// Sen Wang
m.changeName {
print(m.name) /// Wang Sen
}
Another solution is to explicitly capture self (since in my case, I was in a mutating function of a protocol extension so I couldn't easily specify that this was a reference type).
So instead of this:
functionWithClosure(completion: { _ in
self.property = newValue
})
I have this:
var closureSelf = self
functionWithClosure(completion: { _ in
closureSelf.property = newValue
})
Which seems to have silenced the warning.
Note this does not work for value types so if self is a value type you need to be using a reference type wrapper in order for this solution to work.

Swift: Protocol Based Type Construction

I'm trying to create a protocol in Swift I can use for object construction. The problem I'm running into is that I need to store the type information so the type can be constructed later and returned in a callback. I can't seem to find a way to store it without either crashing the compiler or creating build errors. Here's the basics (a contrived, but working example):
protocol Model {
init(values: [String])
func printValues()
}
struct Request<T:Model> {
let returnType:T.Type
let callback:T -> ()
}
We have a simple protocol that declares a init (for construction) and another func printValues() (for testing). We also define a struct we can use to store the type information and a callback to return the new type when its constructed.
Next we create a constructor:
class Constructor {
var callbacks: [Request<Model>] = []
func construct<T:Model>(type:T.Type, callback: T -> ()) {
callback(type(values: ["value1", "value2"]))
}
func queueRequest<T:Model>(request: Request<T>) {
callbacks.append(request)
}
func next() {
if let request = callbacks.first {
let model = request.returnType(values: ["value1", "value2"])
request.callback(model)
}
}
}
A couple things to note: This causes a compiler crash. It can't figure this out for some reason. The problem appears to be var callbacks: [Request<Model>] = []. If I comment out everything else, the compiler still crashes. Commenting out the var callbacks and the compiler stops crashing.
Also, the func construct works fine. But it doesn't store the type information so it's not so useful to me. I put in there for demonstration.
I found I could prevent the compiler from crashing if I remove the protocol requirement from the Request struct: struct Request<T>. In this case everything works and compiles but I still need to comment out let model = request.returnType(values: ["value1", "value2"]) in func next(). That is also causing a compiler crash.
Here's a usage example:
func construct() {
let constructor = Constructor()
let request = Request(returnType: TypeA.self) { req in req.printValues() }
//This works fine
constructor.construct(TypeA.self) { a in
a.printValues()
}
//This is what I want
constructor.queueRequest(request)
constructor.next() //The callback in the request object should be called and the values should print
}
Does anyone know how I can store type information restricted to a specific protocol to the type can later be constructed dynamically and returned in a callback?
If you want the exact same behavior of next I would suggest to do this:
class Constructor {
// store closures
var callbacks: [[String] -> ()] = []
func construct<T:Model>(type:T.Type, callback: T -> ()) {
callback(type(values: ["value1", "value2"]))
}
func queueRequest<T:Model>(request: Request<T>) {
// some code from the next function so you don't need to store the generic type itself
// **EDIT** changed closure to type [String] -> () in order to call it with different values
callbacks.append({ values in
let model = request.returnType(values: values)
request.callback(model)
})
}
func next(values: [String]) {
callbacks.first?(values)
}
}
Now you can call next with your values. Hopefully this works for you.
EDIT: Made some changes to the closure type and the next function
Unfortunately there is no way to save specific generic types in an array and dynamically call their methods because Swift is a static typed language (and Array has to have unambiguous types).
But hopefully we can express something like this in the future like so:
var callbacks: [Request<T: Model>] = []
Where T could be anything but has to conform to Model for example.
Your queueRequest method shouldn't have to know the generic type the Request it's being passed. Since callbacks is an array of Request<Model> types, the method just needs to know that the request being queued is of the type Request<Model>. It doesn't matter what the generic type is.
This code builds for me in a Playground:
class Constructor {
var callbacks: [Request<Model>] = []
func construct<T:Model>(type:T.Type, callback: T -> ()) {
callback(type(values: ["value1", "value2"]))
}
func queueRequest(request: Request<Model>) {
callbacks.append(request)
}
func next() {
if let request = callbacks.first {
let model = request.returnType(values: ["value1", "value2"])
request.callback(model)
}
}
}
So I found an answer that seems to do exactly what I want. I haven't confirmed this works yet in live code, but it does compile without any errors. Turns out, I needed to add one more level of redirection:
I create another protocol explicitly for object construction:
protocol ModelConstructor {
func constructWith(values:[String])
}
In my Request struct, I conform to this protocol:
struct Request<T:Model> : ModelConstructor {
let returnType:T.Type
let callback:T -> ()
func constructWith(values:[String]) {
let model = returnType(values: values)
callback(model)
}
}
Notice the actual construction is moved into the Request struct. Technically, the Constructor is no longer constructing, but for now I leave its name alone. I can now store the Request struct as ModelConstructor and correctly queue Requests:
class Constructor {
var callbacks: [ModelConstructor] = []
func queueRequest(request: Request<Model>) {
queueRequest(request)
}
func queueRequest(request: ModelConstructor) {
callbacks.append(request)
}
func next() {
if let request = callbacks.first {
request.constructWith(["value1", "value2"])
callbacks.removeAtIndex(0)
}
}
}
Note something special here: I can now successfully "queue" (or store in an array) Request<Model>, but I must do so indirectly by calling queueRequest(request: ModelConstructor). In this case, I'm overloading but that's not necessary. What matters here is that if I try to call callbacks.append(request) in the queueRequest(request: Request<Model>) function, the Swift compiler crashes. Apparently we need to hold the compiler's hand here a little so it can understand what exactly we want.
What I've found is that you cannot separate Type information from Type Construction. It needs to be all in the same place (in this case it's the Request struct). But so long as you keep construction coupled with the Type information, you're free to delay/store the construction until you have the information you need to actually construct the object.