Esta pregunta surge todo el tiempo.
Una sugerencia es crear un contenedor de datos singleton: un objeto que se crea una y solo una vez en la vida de su aplicación, y persiste durante la vida de su aplicación.
Este enfoque es adecuado para una situación en la que tiene datos de aplicaciones globales que deben estar disponibles / modificables en diferentes clases de su aplicación.
Otros enfoques, como la configuración de enlaces unidireccionales o bidireccionales entre controladores de vista, se adaptan mejor a situaciones en las que está pasando información / mensajes directamente entre controladores de vista.
(Consulte la respuesta de nhgrif, a continuación, para ver otras alternativas).
Con un contenedor de datos singleton, agrega una propiedad a su clase que almacena una referencia a su singleton y luego usa esa propiedad cada vez que necesite acceso.
Puede configurar su singleton para que guarde su contenido en el disco para que el estado de su aplicación persista entre lanzamientos.
Creé un proyecto de demostración en GitHub que demuestra cómo puede hacer esto. Aqui esta el link:
Proyecto SwiftDataContainerSingleton en GitHub
Aquí está el archivo README de ese proyecto:
SwiftDataContainerSingleton
Una demostración del uso de un contenedor de datos singleton para guardar el estado de la aplicación y compartirlo entre objetos.
La DataContainerSingleton
clase es el singleton real.
Utiliza una constante estática sharedDataContainer
para guardar una referencia al singleton.
Para acceder al singleton, use la sintaxis
DataContainerSingleton.sharedDataContainer
El proyecto de muestra define 3 propiedades en el contenedor de datos:
var someString: String?
var someOtherString: String?
var someInt: Int?
Para cargar la someInt
propiedad desde el contenedor de datos, usaría un código como este:
let theInt = DataContainerSingleton.sharedDataContainer.someInt
Para guardar un valor en someInt, usaría la sintaxis:
DataContainerSingleton.sharedDataContainer.someInt = 3
El init
método de DataContainerSingleton agrega un observador para UIApplicationDidEnterBackgroundNotification
. Ese código se ve así:
goToBackgroundObserver = NSNotificationCenter.defaultCenter().addObserverForName(
UIApplicationDidEnterBackgroundNotification,
object: nil,
queue: nil)
{
(note: NSNotification!) -> Void in
let defaults = NSUserDefaults.standardUserDefaults()
defaults.setObject( self.someString, forKey: DefaultsKeys.someString)
defaults.setObject( self.someOtherString, forKey: DefaultsKeys.someOtherString)
defaults.setObject( self.someInt, forKey: DefaultsKeys.someInt)
defaults.synchronize()
}
En el código del observador, guarda las propiedades del contenedor de datos en NSUserDefaults
. También puede utilizar NSCoding
Core Data o varios otros métodos para guardar datos estatales.
El init
método de DataContainerSingleton también intenta cargar valores guardados para sus propiedades.
Esa parte del método init se ve así:
let defaults = NSUserDefaults.standardUserDefaults()
someString = defaults.objectForKey(DefaultsKeys.someString) as! String?
someOtherString = defaults.objectForKey(DefaultsKeys.someOtherString) as! String?
someInt = defaults.objectForKey(DefaultsKeys.someInt) as! Int?
Las claves para cargar y guardar valores en NSUserDefaults se almacenan como constantes de cadena que forman parte de una estructura DefaultsKeys
, definida así:
struct DefaultsKeys
{
static let someString = "someString"
static let someOtherString = "someOtherString"
static let someInt = "someInt"
}
Hace referencia a una de estas constantes de esta manera:
DefaultsKeys.someInt
Usando el contenedor de datos singleton:
Esta aplicación de muestra hace un uso trival del contenedor de datos singleton.
Hay dos controladores de vista. La primera es una subclase personalizada de UIViewController ViewController
y la segunda es una subclase personalizada de UIViewController SecondVC
.
Ambos controladores de vista tienen un campo de texto, y ambos cargan un valor de la someInt
propiedad singlelton del contenedor de datos en el campo de texto de su viewWillAppear
método, y ambos guardan el valor actual del campo de texto en el 'someInt' del contenedor de datos.
El código para cargar el valor en el campo de texto está en el viewWillAppear:
método:
override func viewWillAppear(animated: Bool)
{
let value = DataContainerSingleton.sharedDataContainer.someInt ?? 0
textField.text = "\(value)"
}
El código para guardar el valor editado por el usuario en el contenedor de datos está en los textFieldShouldEndEditing
métodos de los controladores de vista :
func textFieldShouldEndEditing(textField: UITextField) -> Bool
{
DataContainerSingleton.sharedDataContainer.someInt = textField.text!.toInt()
return true
}
Debe cargar valores en su interfaz de usuario en viewWillAppear en lugar de viewDidLoad para que su interfaz de usuario se actualice cada vez que se muestre el controlador de vista.