Swift 2 for Loop Low and High Date Between

All dates between two Date objects (Swift)

Just add one day unit to the date until it reaches
the current date (Swift 2 code):

var date = startDateNSDate // first date
let endDate = NSDate() // last date

// Formatter for printing the date, adjust it according to your needs:
let fmt = NSDateFormatter()
fmt.dateFormat = "dd/MM/yyyy"

// While date <= endDate ...
while date.compare(endDate) != .OrderedDescending {
print(fmt.stringFromDate(date))
// Advance by one day:
date = calendar.dateByAddingUnit(.Day, value: 1, toDate: date, options: [])!
}

Update for Swift 3:

var date = startDate // first date
let endDate = Date() // last date

// Formatter for printing the date, adjust it according to your needs:
let fmt = DateFormatter()
fmt.dateFormat = "dd/MM/yyyy"

while date <= endDate {
print(fmt.string(from: date))
date = Calendar.current.date(byAdding: .day, value: 1, to: date)!
}

Getting dates between startdate and enddate from array in swift

You can do it this way:

import Foundation

let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "dd/MM/yyyy"
dateFormatter.timeZone = TimeZone(abbreviation: "GMT")

let dateArray = ["12/01/1996","13/01/1996","15/01/1996","17/01/1996"]
let startdate = dateFormatter.date(from: "13/01/1996")!
let enddate = dateFormatter.date(from: "17/01/1996")!

let output = dateArray
// Map your strings to Date objects excluding nils.
.compactMap { dateFormatter.date(from: $0) }
// Filter the mapped array by your condition.
.filter { $0 >= startdate && $0 <= enddate }

How to iterate for loop in reverse order in swift?

Xcode 6 beta 4 added two functions to iterate on ranges with a step other than one:
stride(from: to: by:), which is used with exclusive ranges and stride(from: through: by:), which is used with inclusive ranges.

To iterate on a range in reverse order, they can be used as below:

for index in stride(from: 5, to: 1, by: -1) {
print(index)
}
//prints 5, 4, 3, 2

for index in stride(from: 5, through: 1, by: -1) {
print(index)
}
//prints 5, 4, 3, 2, 1

Note that neither of those is a Range member function. They are global functions that return either a StrideTo or a StrideThrough struct, which are defined differently from the Range struct.

A previous version of this answer used the by() member function of the Range struct, which was removed in beta 4. If you want to see how that worked, check the edit history.

How to add a delay between loops when playing a tone in AVAudioPlayer?

Unfortunately there is no simple way of doing this. You should use AVAudioPlayerDelegate. Please find some example below:

class ViewController: UIViewController, AVAudioPlayerDelegate
{
private var player: AVAudioPlayer!

@objc private func startPlaying()
{
self.player = try? AVAudioPlayer(contentsOf: url)
self.player.delegate = self
self.player.play()
}

func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool)
{
self.perform(#selector(startPlaying), with: nil, afterDelay: 5)
}
}

Don't forget to stop selector whenever you want stop the continuation of the audio:

NSObject.cancelPreviousPerformRequests(withTarget: self)

Swift performance: map() and reduce() vs for loops

Shouldn't the built-in Array methods be faster than the naive approach
for performing such operations? Maybe somebody with more low-level knowledge than I can shed some light on the situation.

I just want to attempt to address this part of the question and more from the conceptual level (with little understanding of the nature of Swift's optimizer on my part) with a "not necessarily". It's coming more from a background in compiler design and computer architecture than deep-rooted knowledge of the nature of Swift's optimizer.

Calling Overhead

With functions like map and reduce accepting functions as inputs, it places a greater strain on the optimizer to put it one way. The natural temptation in such a case short of some very aggressive optimization is to constantly branch back and forth between the implementation of, say, map, and the closure you provided, and likewise transmit data across these disparate branches of code (through registers and stack, typically).

That kind of branching/calling overhead is very difficult for the optimizer to eliminate, especially given the flexibility of Swift's closures (not impossible but conceptually quite difficult). C++ optimizers can inline function object calls but with far more restrictions and code generation techniques required to do it where the compiler would effectively have to generate a whole new set of instructions for map for each type of function object you pass in (and with explicit aid of the programmer indicating a function template used for the code generation).

So it shouldn't be of great surprise to find that your hand-rolled loops can perform faster -- they put a great deal of less strain on the optimizer. I have seen some people cite that these higher-order functions should be able to go faster as a result of the vendor being able to do things like parallelize the loop, but to effectively parallelize the loop would first require the kind of information that would typically allow the optimizer to inline the nested function calls within to a point where they become as cheap as the hand-rolled loops. Otherwise the function/closure implementation you pass in is going to be effectively opaque to functions like map/reduce: they can only call it and pay the overhead of doing so, and cannot parallelize it since they cannot assume anything about the nature of the side effects and thread-safety in doing so.

Of course this is all conceptual -- Swift may be able to optimize these cases in the future, or it may already be able to do so now (see -Ofast as a commonly-cited way to make Swift go faster at the cost of some safety). But it does place a heavier strain on the optimizer, at the very least, to use these kinds of functions over the hand-rolled loops, and the time differences you're seeing in the first benchmark seem to reflect the kind of differences one might expect with this additional calling overhead. Best way to find out is to look at the assembly and try various optimization flags.

Standard Functions

That's not to discourage the use of such functions. They do more concisely express intent, they can boost productivity. And relying on them could allow your codebase to get faster in future versions of Swift without any involvement on your part. But they aren't necessarily always going to be faster -- it is a good general rule to think that a higher-level library function that more directly expresses what you want to do is going to be faster, but there are always exceptions to the rule (but best discovered in hindsight with a profiler in hand since it's far better to err on the side of trust than distrust here).

Artificial Benchmarks

As for your second benchmark, it is almost certainly a result of the compiler optimizing away code that has no side effects that affect user output. Artificial benchmarks have a tendency to be notoriously misleading as a result of what optimizers do to eliminate irrelevant side effects (side effects that don't affect user output, essentially). So you have to be careful there when constructing benchmarks with times that seem too good to be true that they aren't the result of the optimizer merely skipping all the work you actually wanted to benchmark. At the very least, you want your tests to output some final result gathered from the computation.

Wait until swift for loop with asynchronous network requests finishes executing

You can use dispatch groups to fire an asynchronous callback when all your requests finish.

Here's an example using dispatch groups to execute a callback asynchronously when multiple networking requests have all finished.

override func viewDidLoad() {
super.viewDidLoad()

let myGroup = DispatchGroup()

for i in 0 ..< 5 {
myGroup.enter()

Alamofire.request("https://httpbin.org/get", parameters: ["foo": "bar"]).responseJSON { response in
print("Finished request \(i)")
myGroup.leave()
}
}

myGroup.notify(queue: .main) {
print("Finished all requests.")
}
}

Output

Finished request 1
Finished request 0
Finished request 2
Finished request 3
Finished request 4
Finished all requests.


Related Topics



Leave a reply



Submit