DotSlash
DotSlash

Reputation: 53

iOS disable UIButton for 30 minutes

I am making an app where people can request two orders per hour maximum. I would like to disable the "Order" UIButton for a full 30 minutes once it is pressed. Can anybody suggest the most efficient way to do this but that fully prevents the user from ordering twice even if the app is killed? Thanks.

Upvotes: 1

Views: 271

Answers (4)

Adrian
Adrian

Reputation: 16725

Here's the approach I thought of earlier to your problem. The three things you'll use are NSDate, NSTimeInterval, and NSUserDefaults

// I threw this in Xcode to aide me in typing this solution.
// You probably dragged a button from storyboard...leave it like that.
let orderButton: UIButton?

// Put toggleOrderButtonAvailability() in viewDidLoad and viewDidAppear

func toggleOrderButtonAvailability() {
    // get current date
    let currentDate = NSDate()

    // we're not sure if there's a value for this, but we're creating a variable for it
    // it will nil if the user hasn't placed an order
    var lastOrderDate: NSDate?

    // we're creating a variable to check
    var timeSinceLastOrder: NSTimeInterval?

    // if a value for the lastOrderDate saved in NSUserDefaults, then...
    if NSUserDefaults.standardUserDefaults().objectForKey("lastOrderDate") != nil {
        lastOrderDate = NSUserDefaults.standardUserDefaults().valueForKey("lastOrderDate") as? NSDate
        // calculate minutes since last order            
        // 1800 seconds = 60 seconds per minute X 30 minutes
        timeSinceLastOrder = (currentDate.timeIntervalSinceDate(lastOrderDate!)) / 1800

        if timeSinceLastOrder < 30 {
            orderButton?.enabled = false
            // Some alert to let the user know they can't order for another X minutes
            // TODO: you could create a class variable like "timeUntilButtonReenabled"
            //       and set it here, then the timer would run and call this method when it's
            //       done to re-enable the button. Set the timer in viewDidAppear()

        } else {
            orderButton?.enabled = true
        }
    }
}

You'll also want to set the lastOrderDate when you place an order and you can call the method we just created to disable the button when you place an order.

@IBAction func orderButtonAction(sender: UIButton) {

    // Whatever you do when you send an order

    // Set the lastOrderDate & disable the button
    let currentDate = NSDate()
    NSUserDefaults.standardUserDefaults().setObject(currentDate, forKey: "lastOrderDate")
    toggleOrderButtonAvailability()
}

Upvotes: 1

BradzTech
BradzTech

Reputation: 2835

When the button is pressed, disable the button and log the current time using an NSDate object. To ensure it persists even if the app is killed, make sure you write it-- if you're app isn't already using a data system, NSUserDefaults is probably the easiest way to get about this.

Next, you need to create a mechanism for the button to enable again. The easiest reliable method to do so is by creating an NSTimer that checks whether or not the logged date is over 30 minutes ago, and if so, enable the button.

Here's an example of how to do this in Swift:

class ViewController: UIViewController {
    @IBOutlet weak var btn: UIButton!
    var enableTimer: NSTimer!
    let defaults = NSUserDefaults.standardUserDefaults()

    //Because this is a computed property, it auto-saves and persists
    var lastPushed: NSDate {
        get {
            if let unwrappedDate = defaults.objectForKey("lastPushed") as? NSDate {
                return unwrappedDate
            } else {    //If date not yet set
                return NSDate(timeIntervalSince1970: 0)
            }
        } set {    //NSDate is already compatible with NSUserDefaults
            defaults.setObject(newValue, forKey: "lastPushed")
        }
    }

    override func viewDidLoad() {
        startTimer()
    }
    func startTimer() {
        enableTimer = NSTimer.scheduledTimerWithTimeInterval(30, self, Selector("enableTim:"), nil, true)
    }
    @IBAction btnPressed() {
        lastPushed = NSDate()     //NSDate with current time
        startTimer()
        btn.enabled = false
    }
    func enableTim(timer: NSTimer) {
        if (lastPushed.timeIntervalSinceNow < -1800) {    //If last pressed more than 30 minutes ago
            btn.enabled = true
            enableTimer.stop()
        }
    }
}

Upvotes: 0

rmaddy
rmaddy

Reputation: 318804

At a high level you need to do two things:

  1. Calculate the NSDate for when the button should be enabled again and store that date in NSUserDefaults.
  2. Start an NSTimer that goes off in 30 minutes. Enable the disabled button when the timer goes off and remove the date from NSUserDefaults.

More than likely the app will go into the background and the timer will stop long before the 30 minutes. This means that your app needs to stop the timer when it goes into the background. And when it returns to the foreground, you look at the date in NSUserDefaults and see how much time is left. If the time is already past, enable the button and delete the date from NSUserDefaults. If not, start another timer to go off after the needed amount of time as in step 2 above.

Upvotes: 4

Lumialxk
Lumialxk

Reputation: 6369

You should save the order date in NSUserdefaults.Once app launched,check the last order date and make an count down timer for that.

Upvotes: 1

Related Questions