user2698617 user2698617 - 26 days ago 14
iOS Question

Allow User Input Before App Enters Background

I have a CoreData app with a fairly long list of data fields. When a user edits the fields but attempts to exit the DetailViewController without saving the edits, I put up an alert asking if they really want to discard the changes. This works fine, but if the user taps the home key, the edits are lost. I've tried to present an alert before the app enters the background but have been unable to delay entry into background to allow for user input. Is it possible to delay app entry into the background while waiting for user input?

Here's what I tried:

func applicationWillResignActive(_ notification : Notification) {
//this does not work - alert is too late
cancelUnsavedEdits()
//try above
}//applicationWillResignActive


The canelUnsavedEdits method is fairly straight forward:

func cancelUnsavedEdits() {

if hasChanged {

let ac = UIAlertController(title: nil, message: nil, preferredStyle: .alert)
ac.addAction(UIAlertAction(title: "Delete Edits", style: .default, handler: { (action : UIAlertAction!) -> Void in

self.codeDismissTheKeyboard()
self.performSegue(withIdentifier: "unwindToMasterViewController", sender: self)

let editRecordButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.edit, target: self, action: #selector(DetailViewController.editThisRecord))
self.navigationItem.rightBarButtonItem = editRecordButton

self.navigationItem.leftBarButtonItem = nil
self.navigationItem.hidesBackButton = false

//need to remove the edits - refresh the original page
self.configureView()

}))//addAction block

ac.addAction(UIAlertAction(title: "Save Edits", style: .default, handler: { (action : UIAlertAction!) -> Void in

self.codeDismissTheKeyboard()
self.saveTheEditedRecord()
self.performSegue(withIdentifier: "unwindToMasterViewController", sender: self)

}))//addAction block

//for -ipad add code in handler to reopen the fields for editing if the cancel of the cancel is chosed
ac.addAction(UIAlertAction(title: "Cancel", style: .default, handler: { (whatever) in
//print("makeEntryFieldsEnabledYES for ipad")
self.makeEntryFieldsEnabledYES()
}))
//above for ipad

self.present(ac, animated: true, completion: nil)

} else {
self.codeDismissTheKeyboard()

//add this for ipad
self.navigationItem.rightBarButtonItem = nil
//add above for ipad

self.performSegue(withIdentifier: "unwindToMasterViewController", sender: self)
}//if hasChanged

//this for ipad
navigationItem.leftBarButtonItem = nil
//above for iPad

}//cancelUnsavedEdits


Any guidance on a strategy to accomplish this idea would be appreciated. iOS 10, Xcode 8.1

Answer

No. Not possible.

iOS does give your app some time to clean up or save data, but not enough time for user interaction. The reasoning is that the user DID interact and wants to exit your app. Maybe save the data the user entered and present it when they return, but do not try to prevent the user from exiting.