0

I can't find a way to implement a wait function, I'm using swiftforwindows and no examples online have been able to solve it so far. It's Swift 4.2

The class is basically an array that when a function is called each index on the array gets a constant value deducted. the tick function is what is being called. I'm new to Swift.

class resProj {

var list = [1,1,1,1]
var projReq = [100,200,300,50]
var completed = false

func tick(){
    for count in 0..<projReq.count{
        if projReq[count] <= list[count]{
            projReq[count] = 0
        }
        else if projReq[count] > list[count]{
            projReq[count] -= list[count]
        }
    }
    print(projReq)
}


init(
    mathsP      mathsIn:    Int,
    scienceP    sciecnceIn: Int,
    enginerP    enginerIn:  Int,
    businessP   businessIn: Int) {

    self.list [0] = mathsIn
    self.list [1] = sciecnceIn
    self.list [2] = enginerIn
    self.list [3] = businessIn

    }
 }

var spaceElev = resProj(
mathsP:     10,
scienceP:   20,
enginerP:   30,
businessP:  5)

var x = false

while x == false{
//wait function here pls//
print("tick", terminator:"?")
let y = readLine()
if y == "y"{
    spaceElev.tick()
}
else{
    print("gotta put y")
    }
var templist = spaceElev.projReq
var templistcount = 0
templistcount = templist.count
for loop in 0..<templistcount{
    if templist[loop] == 0{
        templistcount -= 1
    }
}
if templistcount == 0 {
    x = true
    print("project completed")
}
}
     }

Where it says //wait function here pls// I would like to make the program wait for 1 second.

halfer
  • 19,824
  • 17
  • 99
  • 186
biddls
  • 31
  • 1
  • 9
  • Try `sleep(1)`. Is that what you want? – Sweeper Feb 09 '19 at 16:06
  • 3
    Basically, you should never try to make your app stop for some time. What you really need is to schedule code to be executed after 1 second. For example using a `Timer`. – Sulthan Feb 09 '19 at 16:08
  • 1
    Possible duplicate: https://stackoverflow.com/questions/27517632/how-to-create-a-delay-in-swift – Tieda Wei Feb 09 '19 at 16:10

4 Answers4

1

There are a lot of way to do this but most common way is create a completion function. For example:

func doSth(_ someParameter: String, _ completion: ()->()) {
    print(someParameter)
    //  After your code is finish call completion
    completion()
}

And when you call (there is two way to call):

doSth("Done") {
    print("You can be sure that this block will work after your func finish")
}

or you can simply create another func and send it as a parameter.

You can also use DispatchQueue:

DispatchQueue.main.asyncAfter(deadline: .now()+1) {
    // put your func here...
}
Paulo Mattos
  • 18,845
  • 10
  • 77
  • 85
Said Alır
  • 170
  • 2
  • 15
  • I got the first 2 code snippets to work but it did not add a delay. this is swift for windows not Xcode swift. idk if that makes a diffrence – biddls Feb 09 '19 at 17:19
0

You can simple use the UNIX-Functin func sleep(_: UInt32) -> UInt32. In your case use sleep(1) to wait one second.

Christian
  • 75
  • 10
0

You could use Grand Central Dispatch or perform.

GCD solution:

let delayInSeconds = 1
DispatchQueue.main.asyncAfter(deadline: .now() + delayInSeconds) {
print("tick", terminator:"?")
}

If you want to learn more about Grand Central Dispatch (GCD) I suggest you read through this: Grand Central Dispatch - Wikipedia

Grand Central Dispatch Tutorial - Ray Wenderlich

Perform solution:

Create a function like this:

@objc func delayedFunc() {
//write the code here that you want to execute with a one second delay
}

Then call this where you want the delayed function to execute:

let delayInSeconds = 1
perform(#selector(delayedFunc), with: nil, afterDelay: delayInSeconds)
lajosdeme
  • 2,189
  • 1
  • 11
  • 20
  • suing these game me:error: use of unresolved identifier 'DispatchQueue' DispatchQueue.main.asyncAfter(deadline: .now() + delayInSeconds) { – biddls Feb 09 '19 at 17:16
  • oh yes I only see now that you are using Swift on Windows. GCD is Apple technology so you can't find it on Windows I suppose. Have you tried the perform method? I think that should still work. – lajosdeme Feb 09 '19 at 17:24
  • I don't know what that is I have 1 day EXP of this, do you have a link to a page so I can learn about it? – biddls Feb 09 '19 at 17:36
  • I updated my answer! Try the "perform solution" and let me know if it worked. – lajosdeme Feb 09 '19 at 17:47
  • it game me this:C:\Users\thoma\Desktop\1984\Swift\GAME\Swift\Game\test.swift:3:7: error: objc can only be used with members of classes, objc protocols, and concrete extensions of classes objc func delayedFunc() { ~~~~~~^ C:\Users\thoma\Desktop\1984\Swift\GAME\Swift\Game\test.swift:8:1: error: use of unresolved identifier 'perform' perform(#selector(delayedFunc), with: nil, afterDelay: delayInSeconds) ^~~~~~~ SwiftMinGWCrt.perror:1:13: note: did you mean 'perror'? public func perror(_ _ErrMsg: UnsafePointer!) ^ Compilation Failed. – biddls Feb 09 '19 at 17:53
  • had to remove the "at" because stack overflow but its there. the code was:import Foundation @objc func delayedFunc() { print("oh hi Idem") } let delayInSeconds = 1 perform(#selector(delayedFunc), with: nil, afterDelay: delayInSeconds) – biddls Feb 09 '19 at 17:53
0

You can use the RunLoop class:

func wait(for interval: TimeInterval) {
    RunLoop.current.run(until: Date() + interval)
}
Cristik
  • 30,989
  • 25
  • 91
  • 127