在保存之前通过不同的控制器存储来自用户的临时数据

storing temporary data from user through different controllers before saving them

在会话期间存储临时数据的最佳做法?我有一个应用程序,允许我在医疗服务中注册客户,插入生物识别和个人数据(姓名、体重、个人措施等)。保存数据后,您转到其他页面,您可以在其中执行一些操作数据。仅在这条路径的最后(在 3-4 个控制器之后),我通过 Realm 将客户保存在本地数据库中。

在注册阶段,我需要存储这个“TempUser”的数据,可以从多个控制器访问。

我想我可以使用单例,但不确定是否和如何

我投资 但不确定哪种解决方案更合适。

我的想法:

class AppSession {
    
    static var shared = AppSession()
    
    private init() {}
    
    var currentPatient: Patient?
    
}

class Patient {
    
    let shared = Patient()
    
    private init() {}
    
    var name: String? = ""
    var weight: Double = 0.0
}

在我的文本字段委托中:

AppSession.shared.currentPatient?.name = data //text from textfield

否则,使用 Patient 作为结构,而不是 class

很难说出哪种解决方案适合每种情况。这实际上取决于数据在您的应用中的使用范围。它是每个部分都通用还是只是某些特定的 ViewControllers ?它被检索和更新了多少次?它还取决于您使用的架构模式以及更多因素。所以简而言之,您使用单例模式的解决方案可能是有效的,但如果不深入了解您的项目就无法确定。如果您决定坚持使用您的解决方案,您可以省略 AppSession class 并直接访问您的 Patient.

class Patient {
    static let shared = Patient()

    var name: String? = ""
    var weight: Double = 0.0
}

并更新它:

Patient.shared.name = ""

即使您使用单例模式的解决方案如上所述可能有效,您也应该考虑用户的观点:您是否希望用户即使在应用程序被终止后也能够继续流程?如果是,那么你应该在每一步之后保存数据(所以可能 KeyChain 因为你描述的是一种敏感数据)。或者更好的解决方案是将数据存储在服务器端,这使用户可以灵活地在其他设备上继续操作(可能 android)。

但是你可以说,你真的不关心 KeyChain 既不与服务器通信,又想在本地进行。在这种情况下,我个人会在控制器之间传递数据,并避免单例。让我们使用您的 Patient 对象并创建一个协议,该协议将要求每个符合它的 UIViewController 存储 属性 of Patient.

struct Patient {
    var name: String? = ""
    var weight: Double = 0.0
}

protocol MyOnboardingProtocol: class {
    var data: Patient { get set }
}

使用 MyOnboardingProtocol 您将标记每个需要保存 Patient 数据的控制器。通过这种方式,您将强制 ViewController 持有 Patient 对象,并且第一眼就会知道您的 ViewController 是否属于“入职”流程。

在您的第一个 UIViewController 流程开始的地方,您将初始化您的 Patient 对象(也许还根据用户输入对其进行一些更新),并传递给下一个 UIViewController:

class MyFirstViewController: UIViewController, MyOnboardingProtocol {
    var data: Patient = Patient()

    func nextViewController() {
        let viewController = MySecondViewController(data: data)
        navigationController?.pushViewController(viewController, animated: true)
    }
}

以后每隔 UIViewController,您将把更新后的对象传递给 init:

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)
    }
}

但正如我之前提到的,我所描述的只是一种实现方式。这实际上取决于您的个案和业务逻辑。由于我想保持简短的回答,我鼓励您更多地发现这个话题,关于这个话题有很多很棒的文章。