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
Swiftycam Capture Session Is Not Running
Sizing a UIpickerview Inside a UIalertview
How Is Commoncrypto Used in Swift3
Crash Casting Wknsurlrequest As? Other Type
Xcode - Upgrade to Swift 4 Manually
How to Mirror The Design of The Codable/Codablekeys Protocols
Finding The First Non-Repeating Character in a String Using Swift
Why This Line Is Not Covered? Xcode Code Coverage
Nscalendar in Swift - Init Can Return Nil, But Isn't Optional
Table View Cells Changing Colors When Scrolling Swift
Is The for Loop Condition Evaluated Each Loop in Swift
Type 'Int' Does Not Conform to Protocol 'Booleantype'
iOS App Extension - Action - Custom Data
Apple Turicreate Always Return The Same Label
Using Index from Foreach in Other Array
Swift Codable: Decode Dictionary with Unknown Keys
Cocoapods Framework with Dependencies - Include of Non-Modular Header Inside Framework Module