The process flow in Swift {} is unknown.

Asked 2 years ago, Updated 2 years ago, 35 views


in the code below signIn(withEmail:link:) I am not sure how the processing flows in the {} method.
Does self.hideSpinner{} always run?
What is this syntax called?

 iflet email=self.emailField.text{
    showSpinner {
        // [START signin_emaillink]
        Auth.auth().signIn(withEmail:email,link:self.link){(user,error)in
            // [START_EXCLUDE]
            self.hideSpinner{
                iflet error = error {
                    self.showMessagePrompt(error.localizedDescription)
                        return
                }
                self.navigationController!.popViewController(animated:true)
            }
            // [END_EXCLUDE]
        }
        // [END signin_emaillink]
    }
} else{
    self.showMessagePrompt("Email can't be empty")
}

swift

2022-09-30 17:53

2 Answers

The {...} that follows a method call is called a closure.
In addition to signIn(withEmail:link:), {...} attached to showSpinner and hideSpinner are also closures.

A closure is like a function, but you can put the closure itself into a variable, pass it to another method or function, or return it as a return value.

Here's a simple example.

//Closure to print "ABC"
letc1 = {
    print ("ABC")
}
c1()//ABC appears

// a closure that doubles a given integer
letc2 = {
    (a:Int) - > Int in
    return a*2
}
c2(2)//4 is returned

// function that accepts a closure as an argument
// invoke a given closure twice
func f1(close:()->Void){
    close()
    close()
}

// "ABC" is printed twice
f1 (close:c1)

// If the last argument of a function is a closure, you can write {} after the function
f1{
    print("Yeah!")
}

With this in mind,

Does self.hideSpinner{} always run?

signIn(withEmail:link:) by implementation or processing results

is the answer.
From the method name, we expect the closure to be called by putting a value in user upon successful sign-in, or error upon failure, but we are not sure if that is true.
(You'll find out if you check the implementation, API specifications, or actually run it and try it.)

add

From Mr. Forest's past questions, JavaScript is probably more familiar than Swift.
So let's translate the original program into JavaScript style.The following is true:

this.showSpinner(function(){
    // [START signin_emaillink]
    Auth.auth().signInWithEmail(email, this.link, function(user, error){
        // [START_EXCLUDE]
        This.hideSpinner(function(){
            if(error){
                This.showMessagePrompt(error.localizedDescription);
                return;
            }
            This.navigationController.popViewControllerAnimated(true);
        });
        // [END_EXCLUDE]
    });
    // [END signin_emaillink]
});

In other words, Swift's closure {...} is the same as JavaScript's unknown function.
You can also see that unknown functions are passed as arguments to other methods, namely showSpinner, hideSpinner, signIn.It depends on each method how you handle the function passed.


2022-09-30 17:53

signIn(withEmail:link:) I'm not sure how the process flows in the {} method.

{} is a closure.It's a completely practical and meaningless closure, but to give you an example of ease of understanding,

let plus={(a:Int,b:Int)->Int in
    return a+b
}

(a:Int,b:Int) represents the argument portion, ->Int represents the return value, and in is the implementation portion of the closure.In other words, it has the same structure as a function and works almost the same way as a function.The advantage of using a closure instead of a function is that it can be substituted for a variable, as shown in the example.Following the code above,

letc=plus(a:4,b:3)//c=7

You can write to run the closure.It's a function.The main difference between a closure and a function is its persistence.Functions (independent functions) are global and have the same life as programs, and functions that are members of the class, i.e., methods, have the same life as instances.In contrast, a closure, like a typical value variable, has a code block (from { to }).
Closures are called "Ramda" or "Unknown Functions" in other languages, so you should go away from Swift and look it up online.

Closures can be substituted for variables, so they are arguments for functions.Here is an example of a function that takes a closure as an argument:

funchhoge(a:Int,b:Int,operation:(Int,Int)->Int{
    return operation(a,b)
}

The variable that substitutes the closure also has a type, which is written like (Int, Int)->Int.

let m=hoge(a:3, b:4, operation:plus) // m=7

Closure-type arguments can describe direct closure implementations.

let n=hoge(a:8, b:3, operation:{(a, b)->Intin
    return a-b
})
// n = 5

Is this all right?
Swift accepts a special syntax for a function that takes a closure as an argument.You can move the closure out of () on the condition that the closure type argument is at the end.This is how you can rewrite the code above.

let n=hoge(a:8,b:3){(a,b)->Intin
    return a-b
}

Longer implementations of the closure make it difficult to immediately determine what ) means at the end of the function.I think the intention is to ease the difficulty of making such a decision.

What is this syntax called?

Now that we've come this far, we can answer this question.That is, the method of taking the closure as an argument.
It's almost there.(You don't have to read any more if you've solved all the questions here.)
Now let's think about the next two cases.One is the case where only one function argument is taken as a closure type, and the other is the case where there is no argument or return value.This is what happens to the samples that satisfy these two cases.

func fuga(doThis:()->()){
    doThis()
}

Closure types with no arguments or return values are ()->Void or ()->().The latter seems to be recommended.
To run this function, write:

fuga(doThis:{()->()in
    print("Hello")
})
// Egress Hello

(Closures that do not have a return value do not write the return line, as do functions.)
If you write this in an abbreviated syntax, the closure argument is first taken out of the () and the () is not required.The type of closure argument and return value is omitted, and in is also not required.

fuga{
    print("Hello")
}

This solves the self.hideSpinner{} mystery.Thank you for your hard work.


2022-09-30 17:53

If you have any answers or tips


© 2024 OneMinuteCode. All rights reserved.