Трудно сказать, какое решение подходит для каждого отдельного случая. Это действительно зависит от того, насколько широко данные используются в вашем приложении. Это общее для каждой части или только для некоторых конкретных ViewController? Сколько раз он извлекается и обновляется? Также это зависит от используемого вами архитектурного шаблона и многих других факторов. Короче говоря, ваше решение с использованием одноэлементного шаблона может быть действительным, но вы не можете сказать наверняка, не внимательно изучив ваш проект. Если вы решите придерживаться своего решения, вы можете опустить класс AppSession
и получить прямой доступ к вашему Patient
.
class Patient {
static let shared = Patient()
var name: String? = ""
var weight: Double = 0.0
}
И обновите его:
Patient.shared.name = ""
Несмотря на то, что ваше решение с использованием одноэлементного шаблона может быть правильным, как упоминалось выше, вы также должны учитывать точку зрения пользователя: хотите ли вы, чтобы пользователь мог продолжить поток даже после того, как приложение было уничтожено? Если да, то вам следует сохранять данные после каждого шага (так что, возможно, KeyChain
, поскольку то, что вы описываете, является конфиденциальными данными). Или лучшим решением является хранение данных на стороне сервера, что дает пользователю возможность продолжать работу даже на другом устройстве (возможно, Android).
Но вы можете сказать, что вы действительно не заботитесь ни о KeyChain, ни об общении с сервером, и хотите делать это локально. В этом случае лично я бы передал данные между контроллерами и избегал синглтонов. Давайте возьмем ваш объект Patient
и создадим протокол, который потребует, чтобы каждый UIViewController
, соответствующий ему, имел сохраненное свойство Patient
.
struct Patient {
var name: String? = ""
var weight: Double = 0.0
}
protocol MyOnboardingProtocol: class {
var data: Patient { get set }
}
С помощью MyOnboardingProtocol
вы отметите каждый контроллер, который потребует хранения данных Patient
. Таким образом, вы заставите ViewControllers удерживать объект Patient
и с первого взгляда будете знать, принадлежит ли ваш ViewController потоку Onboarding.
В вашем первом UIViewController
, где начинается ваш поток, вы инициализируете свой объект Patient
(возможно, также сделаете некоторые обновления на основе пользовательского ввода) и пройдете для следующего UIViewController
:
class MyFirstViewController: UIViewController, MyOnboardingProtocol {
var data: Patient = Patient()
func nextViewController() {
let viewController = MySecondViewController(data: data)
navigationController?.pushViewController(viewController, animated: true)
}
}
Для каждого другого UIViewController
в будущем вы будете передавать обновленный объект в инициализацию:
class MySecondViewController: UIViewController, MyOnboardingProtocol {
var data: Patient
init(data: Patient) {
self.data = data
super.init(nibName: nil, bundle: nil)
}
required init?(coder: NSCoder) {
super.init(coder: coder)
}
}
Но, как я уже упоминал ранее, то, что я описал, является лишь одним из способов сделать это. Это действительно будет зависеть от вашего индивидуального случая и бизнес-логики. Поскольку я хочу, чтобы мой ответ был кратким, я призываю вас немного больше узнать об этой теме, на эту тему было много замечательных статей.
person
πter
schedule
08.03.2021