antonyraja antonyraja - 1 year ago 94
Swift Question

How to call timer one time in application using swift?

Hi all am developing a app using swift 2 in my app am updating current location for every x minutes so am using NSTimer am able to update location and everything works fine.In my app(first view controller) when a user successfully logged in and moves to second view controller in(second view controller) i wrote the function for updating location using NSTimer it works fine but when the user moves to third view controller and return to second view controller it again start updating location so i cant able to stop the timer twice it invalidate timer one time only other one keep on updating the location even after the users logged please someone help me out to solve this problem.

my second view controller:

class secondviewcontroller:UIViewController{

in view did load method:

var appDelegate:AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
appDelegate.timer = NSTimer.scheduledTimerWithTimeInterval(10.0, target: self, selector: #selector(timeToMoveOn), userInfo: nil, repeats: true)

//i declared var timer:nstimer! in appdelegate.swift and i performed some function using nstimer

my third view controller:

I created a button action for logout code is:

var appDelegate:AppDelegate = (UIApplication.sharedApplication().delegate as?

Thanks in advance

Answer Source

I would suggest to do this:

this singleton to wrap location.

Sorry, for swift3 but it have look something like this:

class LM: NSObject, CLLocationManagerDelegate {
    //MARK: Public Variable

    var lat = 0.0
    var lon = 0.0
    var CAST = "location_cast"
    public static let i : LM = {
        let instance = LM()
        return instance

    //MARK: Local Variable

    fileprivate var locationManager: CLLocationManager?

    //MARK: Init
    public override init() {
        locationManager = CLLocationManager()
        locationManager?.delegate = self
    internal func start() {
    internal func stop() {
    func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
//        print("\(locations)")
        if let loc = locations.last {
//simple store to retrieve it later
            lat = loc.coordinate.latitude
            lon = loc.coordinate.longitude

                //cast here notification
       NSNotification.Name(rawValue: CAST), object: ["lat": lat, "lon": lon])

    func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
        switch status {
        case .notDetermined:
        case .authorizedWhenInUse:
        case .authorizedAlways:
        case .restricted:
            // restricted by e.g. parental controls. User can't enable Location Services
        case .denied:
            // user denied your app access to Location Services, but can grant access from

to start and stop this locationmanager use this:

class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool {
// Override point for customization after application launch.
        _  = LM.i
        return true

func applicationWillResignActive(_ application: UIApplication) {
        // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.


 func applicationDidBecomeActive(_ application: UIApplication) {
        // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.


You can add inside AppDelegate your custom timer with casting variables each 1 second

let CASTTOVIEWCONTROLLER = "CASTTOVIEWCONTROLLER" NSNotification.Name(rawValue: CASTTOVIEWCONTROLLER), object: ["lat":, "lon": LM.i.lon])

or even simple


to catch a new data from casted values use something like this:

If you will not manage .start() and .stop() iOS will kick your background timer application each in several minutes if your will press 'home' button.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download