Swift Short Syntax of Execution

Swift short syntax of execution

As mentioned by other contributors, Swift emphasizes readability and thus, explicit syntax. It would be sacrilege for the Swift standard library to support Python-style truth value testing.

That being said, Swift’s extensibility allows us to implement such functionality ourselves—if we really want to.

prefix func !<T>(value: T) -> Bool {
switch T.self {
case is Bool.Type:
return value as! Bool
default:
guard Double(String(describing: value)) != 0
else { return false }

return true
}
}

prefix func !<T>(value: T?) -> Bool {
guard let unwrappedValue = value
else { return false }

return !unwrappedValue
}

var a = 1

func foo() -> Void { }

!a && !foo()

Or even define our own custom operator:

prefix operator ✋

prefix func ✋<T>(value: T) -> Bool {
/// Same body as the previous example.
}

prefix func ✋<T>(value: T?) -> Bool {
guard let unwrappedValue = value
else { return false }

return ✋unwrappedValue
}

var a = 1

func foo() -> Void { }

✋a && ✋foo()

What is the shortest way to run same code n times in Swift?

Sticking with a for loop - you could extend Int to conform to SequenceType to be able to write:

for i in 5 { /* Repeated five times */ }

To make Int conform to SequenceType you'll could do the following:

extension Int : SequenceType {
public func generate() -> RangeGenerator<Int> {
return (0..<self).generate()
}
}

How to correct the order of execution of code in Swift 5?

Completion Handlers is your friend

The moment your code runs task.resume(), it will run your uploadTask and only when that function is finished running it will run the code where you change your login variable.

With That said: That piece of code is running asynchronously. That means your return login line of code won't wait for your network request to come back before it runs.

Your code is actually running in the order it should. But i myself wrote my first network call like that and had the same problem. Completion Handles is how i fixed it


Here is a very nice tutorial on Completion Handlers or you might know it as Callbacks :

Link To Completion Handlers Tutorial


If i can give you a little hint - You will have to change your function so it looks something like this: func loginRequest (name: String, pwd: String, completionHandler: @escaping (Bool) -> Void)

And replace this login = true with completionHandler(true)

Wherever it is you call your function it will look something like this:

loginRequest(name: String, pwd: String) {didLogIn in
print("Logged In : \(didLogIn)")
}

One last thing... You're actually already using Completion Handlers in your code.
let task = session.uploadTask(with: request, from: jsonData) { data, response, error in
...
... But hopefully now you understand a little bit better, and will use a completion handler approach when making network calls.

GOOD LUCK !

Swift Closures and order of execution

Your implementation of load(onFinish:) is very surprising and over-complicated. Luckily, though, that helps demonstrate the point you were asking about.

A closure is executed when something calls it. So in your case, onFinish is called at the end of the method, which makes it synchronous. Nothing about being "a closure" makes anything asynchronous. It's just the same as calling a function. It is completely normal to call a closure multiple times (map does this for instance). Or it might never be called. Or it might be called asynchronously. Fundamentally, it's just like passing a function.

When I say "it's slightly different than an anonymous function," I'm just referring to the "close" part of "closure." A closure "closes over" the current environment. That means it captures variables in the local scope that are referenced inside the closure. This is slightly different than a function (though it's more about syntax than anything really deep; functions can actually become closures in some cases).

The better implementation would just return the array in this case.

How to create a delay in Swift?

Instead of a sleep, which will lock up your program if called from the UI thread, consider using NSTimer or a dispatch timer.

But, if you really need a delay in the current thread:

do {
sleep(4)
}

This uses the sleep function from UNIX.

Swift short-circuiting with logical operators not working as expected

Short circuiting means that the next part of the expression is not evaluated only if the result is already clear. If the part before && is true then the result can still be both false and true and the next part has to be evaluated.

The cases are:

1. true && true => true
2. true && false => false
3. false && false => false
4. false && true => false

And after evaluating the left operand we have:

true && ??

which can end either in case 1 or 2, which have different results.

On the other hand, if we had:

false && ??

Then the result would be either case 3 or 4, which are both false and the expression will short-circuit.

How could I create a function with a completion handler in Swift?

Say you have a download function to download a file from network, and want to be notified when download task has finished.

typealias CompletionHandler = (success:Bool) -> Void

func downloadFileFromURL(url: NSURL,completionHandler: CompletionHandler) {

// download code.

let flag = true // true if download succeed,false otherwise

completionHandler(success: flag)
}

// How to use it.

downloadFileFromURL(NSURL(string: "url_str")!, { (success) -> Void in

// When download completes,control flow goes here.
if success {
// download success
} else {
// download fail
}
})

Adding delay between execution of two following lines

You can use gcd to do this without having to create another method

// ObjC

NSTimeInterval delayInSeconds = 2.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
NSLog(@"Do some work");
});

// Swift

DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
print("Do some work)
}

You should still ask yourself "do I really need to add a delay" as it can often complicate code and cause race conditions

Swift Dictionary.reduce() - different number of iterations reported using full vs. short syntax

Playgrounds use the "n times" notation whenever a line of code is "visited" more than once during execution. This happens in lieu of showing a result because a line that has executed more than once — or a line that has executed more than one statement — can have more than one result.

When the closure body is on its own line, the playground reports that said line executed 3 times. When the closure body is in the same line as the reduce call to which it's passed, it says "4 times" because that line of code was "visited" 4 times during execution — once for the reduce call itself, and three more times for the closure body.

Note this happens regardless of which closure syntax you use — it's entirely a matter of where you put line breaks.

chocolates.reduce("", combine: {
$0 + "\($1.0), " // (3 times)
})

chocolates.reduce("") { (var sum: String, keyValue: (String, Int)) -> String in
return sum + "\(keyValue.0), " // (3 times)
}

chocolates.reduce("", combine: {$0 + "\($1.0), "})
// (4 times)

chocolates.reduce("") { (var sum: String, keyValue: (String, Int)) -> String in return sum + "\(keyValue.0), "}
// (4 times)

I don't have Xcode in front of me, but IIRC you'll see this even when you put multiple statements on one line with ;. It has nothing to do with closure syntax and everything to do with line breaks vs statements:

let a = 1 // 1
let b = a + 1 // 2

let a = 1; let b = a + 1 // (2 times)


Related Topics



Leave a reply



Submit