Passing Parameters to a Method Called by Nstimer in Swift

Passing parameters to the method called by a NSTimer

You need to define the method in the target. Since you set the target as 'self', then yes that same object needs to implement the method. But you could have set the target to anything else you wanted.

userInfo is a pointer that you can set to any object (or collection) you like and that will be passed to the target selector when the timer fires.

Hope that helps.

EDIT: ... Simple Example:

Set up the timer:

    NSTimer* timer = [NSTimer scheduledTimerWithTimeInterval:2.0 
target:self
selector:@selector(handleTimer:)
userInfo:@"someString" repeats:NO];

and implement the handler in the same class (assuming you're setting the target to 'self'):

- (void)handleTimer:(NSTimer*)theTimer {

NSLog (@"Got the string: %@", (NSString*)[theTimer userInfo]);

}

Pass two arguments to NSTimer in Swift

Make a array with your objects and send it to userInfo. Try this:

func someFunc(){
var arr = ["one", "two"]
var timer: NSTimer = NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: Selector("val:"), userInfo: arr, repeats: true)

}


func val(timer: NSTimer){

//You'll get an array in timer.userInfo
// arr = timer.userInfo.
// Now you'll get you data in each index of arr

}

Hope this helps.. :)

How do I pass params on timer selector

For sending the data with Timer you can use the userInfo parameter for pass the data.

Here is the sample by which you can get call of selector method and by that you can pass your location coordinate to it.

Timer.scheduledTimer(timeInterval: 0.5, target: self, selector:#selector(iGotCall(sender:)), userInfo: ["Name": "i am iOS guy"], repeats:true)

For handling that userInfo you need to go according to below.

func iGotCall(sender: Timer) {
print((sender.userInfo)!)
}

for your case make sure your didUpdateLocations is called frequently.

Pass a Swift function to NSTimer

If you are targeting pre-iOS 10, you can't pass a function to NSTimer because no API was introduced at that time to support closure callbacks.

iOS 10 and later Approach

// swift 2.x users should still use NSTimer instead
Timer.scheduledTimer(withTimeInterval: 2.0, repeats: true) { timer in
// ...
}

Generic Approach

You can add this class, and reuse it anytime:

final class TimerInvocation: NSObject {

var callback: () -> ()

init(callback: @escaping () -> ()) {
self.callback = callback
}

func invoke() {
callback()
}
}

extension Timer {

static func scheduleTimer(timeInterval: TimeInterval, repeats: Bool, invocation: TimerInvocation) {

Timer.scheduledTimer(
timeInterval: timeInterval,
target: invocation,
selector: #selector(TimerInvocation.invoke(timer:)),
userInfo: nil,
repeats: repeats)
}
}

With this class, you can simply do this now:

let invocation = TimerInvocation {
/* invocation code here */
}

NSTimer.scheduledTimerWithTimeInterval(1, target: invocation, selector:#selector(TimerInvocation.invoke), userInfo: nil, repeats: false)

You don't have to worry about retaining the invocation variable since it is retained by NSTimer

Use selector to call function with parameters

EDIT: Updating to include pre-iOS 10.0 solution

In this case it'd be better to use the scheduledTimer function that takes a block, as this will allow you to pass arguments to your function:

Timer.scheduledTimer(withTimeInterval: 0.5, repeats: true) { (timer) in
SystemClass().setXYZ(xyz: 1.0)
}

For pre-iOS 10.0:

You can also pass userInfo in, including this default value, and then access that info from your inside your selector, like this:

Timer.scheduledTimer(timeInterval: 0.5, target: self, selector: #selector(SystemClass().setXYZ(_:)), userInfo: 1.0, repeats: true)

To do this you'd also have to modify your setXYZ function signature to look like this:

@objc func setXYZ(_ sender: Timer) {
if let xyz = sender.userInfo as? Float {
print(xyz)
// do something
}
}

Swift Pass parameters in a selector

For that you need to create custom subclass of NSTimer or other way is you can use that userInfo, property of NSTimer like this way.

First change your scheduledTimerWithTimeInterval like this way.

let dic:[String:AnyObject] = ["pdfName" : PDFFile, "pdfData" : data]
NSTimer.scheduledTimerWithTimeInterval(0.4, target: self, selector: #selector(FileBrowser.displayPDF(_:)), userInfo: dic as! AnyObject, repeats: false)

Now change your timer function displayPDF like this.

func displayPDF(timer:NSTimer) {
if let userInfo = timer.userInfo as? [String: AnyObject] {
print(userInfo["pdfName"])
}
}


Related Topics



Leave a reply



Submit