Essa pergunta surge o tempo todo.
Uma sugestão é criar um singleton de contêiner de dados: Um objeto que é criado uma vez e apenas uma vez na vida de seu aplicativo e persiste por toda a vida de seu aplicativo.
Essa abordagem é adequada para uma situação em que você tem dados globais de aplicativo que precisam estar disponíveis / modificáveis em diferentes classes em seu aplicativo.
Outras abordagens, como a configuração de links unilaterais ou bidirecionais entre controladores de visualização, são mais adequadas para situações em que você está passando informações / mensagens diretamente entre controladores de visualização.
(Veja a resposta de nhgrif, abaixo, para outras alternativas.)
Com um singleton de contêiner de dados, você adiciona uma propriedade à sua classe que armazena uma referência ao seu singleton e, em seguida, usa essa propriedade sempre que precisar de acesso.
Você pode configurar seu singleton para que ele salve seu conteúdo em disco para que o estado do seu aplicativo persista entre as inicializações.
Eu criei um projeto de demonstração no GitHub demonstrando como você pode fazer isso. Aqui está o link:
Projeto SwiftDataContainerSingleton no GitHub
Aqui está o README desse projeto:
SwiftDataContainerSingleton
Uma demonstração do uso de um singleton de contêiner de dados para salvar o estado do aplicativo e compartilhá-lo entre objetos.
A DataContainerSingletonclasse é o único singleton real.
Ele usa uma constante estática sharedDataContainerpara salvar uma referência ao singleton.
Para acessar o singleton, use a sintaxe
DataContainerSingleton.sharedDataContainer
O projeto de amostra define 3 propriedades no contêiner de dados:
var someString: String?
var someOtherString: String?
var someInt: Int?
Para carregar a someIntpropriedade do contêiner de dados, você usaria um código como este:
let theInt = DataContainerSingleton.sharedDataContainer.someInt
Para salvar um valor em someInt, você usaria a sintaxe:
DataContainerSingleton.sharedDataContainer.someInt = 3
O initmétodo DataContainerSingleton adiciona um observador para o UIApplicationDidEnterBackgroundNotification. Esse código é parecido com este:
goToBackgroundObserver = NSNotificationCenter.defaultCenter().addObserverForName(
UIApplicationDidEnterBackgroundNotification,
object: nil,
queue: nil)
{
(note: NSNotification!) -> Void in
let defaults = NSUserDefaults.standardUserDefaults()
//-----------------------------------------------------------------------------
//This code saves the singleton's properties to NSUserDefaults.
//edit this code to save your custom properties
defaults.setObject( self.someString, forKey: DefaultsKeys.someString)
defaults.setObject( self.someOtherString, forKey: DefaultsKeys.someOtherString)
defaults.setObject( self.someInt, forKey: DefaultsKeys.someInt)
//-----------------------------------------------------------------------------
//Tell NSUserDefaults to save to disk now.
defaults.synchronize()
}
No código do observador, ele salva as propriedades do contêiner de dados em NSUserDefaults. Você também pode usar NSCodingCore Data ou vários outros métodos para salvar dados de estado.
O initmétodo DataContainerSingleton também tenta carregar valores salvos para suas propriedades.
Essa parte do método init se parece com isto:
let defaults = NSUserDefaults.standardUserDefaults()
//-----------------------------------------------------------------------------
//This code reads the singleton's properties from NSUserDefaults.
//edit this code to load your custom properties
someString = defaults.objectForKey(DefaultsKeys.someString) as! String?
someOtherString = defaults.objectForKey(DefaultsKeys.someOtherString) as! String?
someInt = defaults.objectForKey(DefaultsKeys.someInt) as! Int?
//-----------------------------------------------------------------------------
As chaves para carregar e salvar valores em NSUserDefaults são armazenadas como constantes de string que fazem parte de uma estrutura DefaultsKeys, definidas assim:
struct DefaultsKeys
{
static let someString = "someString"
static let someOtherString = "someOtherString"
static let someInt = "someInt"
}
Você faz referência a uma dessas constantes assim:
DefaultsKeys.someInt
Usando o singleton do contêiner de dados:
Este aplicativo de amostra faz uso triplo do singleton do contêiner de dados.
Existem dois controladores de visualização. A primeira é uma subclasse personalizada de UIViewController ViewControllere a segunda é uma subclasse personalizada de UIViewController SecondVC.
Ambos os controladores de visão têm um campo de texto neles, e ambos carregam um valor da someIntpropriedade de singlelton do contêiner de dados no campo de texto em seu viewWillAppearmétodo, e ambos salvam o valor atual do campo de texto de volta em `someInt 'do contêiner de dados.
O código para carregar o valor no campo de texto está no viewWillAppear:método:
override func viewWillAppear(animated: Bool)
{
//Load the value "someInt" from our shared ata container singleton
let value = DataContainerSingleton.sharedDataContainer.someInt ?? 0
//Install the value into the text field.
textField.text = "\(value)"
}
O código para salvar o valor editado pelo usuário de volta no recipiente de dados está nos textFieldShouldEndEditingmétodos dos controladores de visualização :
func textFieldShouldEndEditing(textField: UITextField) -> Bool
{
//Save the changed value back to our data container singleton
DataContainerSingleton.sharedDataContainer.someInt = textField.text!.toInt()
return true
}
Você deve carregar valores em sua interface com o usuário em viewWillAppear em vez de viewDidLoad para que sua IU seja atualizada cada vez que o controlador de visualização for exibido.