【问题标题】:How to pass data from one model to another in Swift?如何在 Swift 中将数据从一个模型传递到另一个模型?
【发布时间】:2018-08-22 15:58:54
【问题描述】:

我正在开发一个项目,该项目包含一个“创建新帐户”视图控制器及其附带的名为“CreateNewAccount”的 Swift 类。用户可以将 4 个输入值放入此视图控制器,即名字、姓氏、用户名和密码。单击此 VC 中的“创建帐户”按钮后,4 个输入值被传递到一个名为 UserInfoRetrieveModel 的 Swift 类(我相信是在 MVC 的模型层中),它们应该存储在该类中。

然后我想将这些值传递给另一个名为 UserInfoModel 的 Swift 类(也是一个模型),然后它将名字值委托给位于名为“ThanksForJoining”的 VC 中的 label 的文本值(及其附带的类)。

我已经弄清楚如何将值从 VC 传递到模型(CreateNewAccount 到 UserInfoRetrieveModel)和从模型传递到 VC(UserInfoModel 到ThanksForJoining),但是在我从模型到模型(UserInfoRetrieveModel 到 UserInfoModel)的转移中,最初输入的值我想传递给第二个模型类 UserInfoModel 的“CreateNewAccount”变为 nil。

下面是 CreateNewAccount、UserInfoRetrieve、UserInfo 和ThanksForJoining 的代码:

创建新帐户->

import UIKit

class CreateNewAccount: UIViewController{

@IBOutlet weak var FNInput: UITextField!
@IBOutlet weak var LNInput: UITextField!
@IBOutlet weak var usernameInput: UITextField!
@IBOutlet weak var passwordInput: UITextField!

var uInfoRetrieve = UInfoRetrieveModel()

@IBAction func thanksForJoining(_ sender: Any) {
    uInfoRetrieve.firstName = FNInput.text!
    uInfoRetrieve.lastName = LNInput.text!
    uInfoRetrieve.userName = usernameInput.text!
    uInfoRetrieve.password = passwordInput.text!
    uInfoRetrieve.delegate = self
    uInfoRetrieve.retrieving()
}
override func viewDidLoad() {
    super.viewDidLoad()
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
 }
}

extension CreateNewAccount: UInfoRetrieveModelDelegate{
    func credentialTransfer(data: String) {
      print(data)
  }
}

用户信息检索->

import Foundation

protocol UInfoRetrieveModelDelegate: class {
  func credentialTransfer(data:String)
 }


class UInfoRetrieveModel: NSObject {

   weak var delegate: UInfoRetrieveModelDelegate?

     var firstName: String = ""
     var lastName: String = ""
     var userName: String = ""
     var password: String = ""

func retrieving(){


    delegate?.credentialTransfer(data: firstName)
    delegate?.credentialTransfer(data: lastName)
    delegate?.credentialTransfer(data: userName)
    delegate?.credentialTransfer(data: password)
    }

}

用户信息->

import Foundation

protocol UserInfoModelDelegate: class {
    func didReceiveDataUpdate(data: String)
   }

class UserInfoModel {
   weak var delegate: UserInfoModelDelegate?

   let uInfoRetrieve = UInfoRetrieveModel()

   func requestData() -> Array<String> {

    let firstName = uInfoRetrieve.firstName
    let lastName = uInfoRetrieve.lastName
    let userName = uInfoRetrieve.userName
    let password = uInfoRetrieve.password

    delegate?.didReceiveDataUpdate(data: firstName)
    delegate?.didReceiveDataUpdate(data: lastName)
    delegate?.didReceiveDataUpdate(data: userName)
    delegate?.didReceiveDataUpdate(data: password)
    let credentials = [firstName, lastName, userName, password] as [Any]
    return credentials as! Array<String>
  }
}  

感谢加入 ->

import UIKit

class ThanksForJoining: UIViewController {

   var userInfo = UserInfoModel()


  @IBOutlet weak var firstName: UILabel!

  override func viewDidLoad() {
    super.viewDidLoad()
    userInfo.delegate = self
    firstName.text = userInfo.requestData()[0]
    print("yo")
    print(userInfo.requestData()[0])
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
  }
}

extension ThanksForJoining: UserInfoModelDelegate {

   func didReceiveDataUpdate(data: String) {
      print(data)
   }
}

【问题讨论】:

    标签: swift model-view-controller uiviewcontroller model


    【解决方案1】:

    UserInfoModelCreateNewAccount 都会创建UInfoRetrieveModel 的新实例。您必须正确连接它们才能传递信息。

    正确连接意味着(以最简单的形式)一个构造另一个并将自己设置为另一个的委托,因此UInfoRetrieveModel 可以传递数据。子模型的构建通常通过computed property 完成。

    示例

    struct Account {
        let firstName: String, lastName: String
        let userName: String, password: String
    }
    
    extension UInfoRetrieveModelDelegate: class {
        createAccount(_ account: Account): Bool
    }
    
    extension UserInfoModel: UInfoRetrieveModelDelegate{
        func createAccount(_ account: Account) -> Bool {
            // Handling creation of account.
            return success == true
        }
        var newUInfoRetrieveModel: UInfoRetrieveModel {
            let helperModel = UInfoRetrieveModel(parent: self)
            helperModel.delegate = self
            return helperModel
        }
    }
    

    说明

    是的。你通常有一个Model,你的数据,然后有一些东西可以控制对它的访问以对你的模型进行更改,管理模型的存储方式,可能与云服务同步,这就是你传递的ModelControllerViewControllers、更多/其他controllers 之间,您通常使用incase 使事情变得更简单。在您的情况下,您可能会将createAccount(调用)传递给controller/viewController,该controller/viewController 负责告诉modelController 创建帐户,然后告诉其中一个views/viewControllers 显示模式/任何内容。

    将数据传递到更高级别的常用方法是为viewController/controller 设置一个委托来与更高级别进行通信,该委托“负责ViewController/controller 无法自行执行的操作”,例如推送数据up(创建调用,修改调用,删除调用)如果给它一个 modelController 没有意义,因为它不能控制应用程序的那部分,等等。在你的情况下,你当然可以将一个 modelController 传递给每个小viewController/view,但通常更实用/更简单,只将其交给控制该部分的人,并让其他人与当前控制该部分的controller/viewController进行通信。

    这里更具体意味着您可能不希望 CreateAccountViewController 显示成功对话框,而是另一个,然后 CreateAccountViewController 自己不能这样做,因为它不再在堆栈上。

    【讨论】:

    • 感谢您的洞察,我应该把它放在哪个类中,还是放在它自己的 swift 文件中?
    • @ElanKainen 这通常取决于你如何做事。管理它的最简单方法是在您的控制器或您正在创建CreateNewAccount-vc 的视图控制器中手头有一个modelController。在创建之后或在 prepareForSegue 中设置 CreateNewAccount userInfoRetrieveModel 您从 UserInfoModel.newInfoRetrieveModel 获得,将 CreateNewAccountViewController 推入堆栈等。我通常有一个 modelController 所以这只是一个想法与它一起工作,使事情变得简单易用。
    • 我是 Swift 和 Xcode 的新手,所以感谢您对我的支持……关于您刚才描述的步骤和您对单个 modelController 的引用,您基本上是说我可以将在 CreateNewAccount 中创建的信息传递给一个模型,然后从那里将该模型的信息发送给其他 VC,而不是在两个模型之间传递数据,一个接收模型到一个输出模型?
    • @ElanKainen 它有点长,所以我编辑了答案而不是在这里写。我使用的不一定是 MVC,因为我不知道这到底是什么意思。如果您想使用规范 MVC,您可以阅读 How should a Model be structured in MVC,尽管它与语言无关,因此您可能需要根据您的需要调整它并填写未编写的内容。
    猜你喜欢
    • 2021-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-09
    • 1970-01-01
    • 1970-01-01
    • 2021-02-20
    • 2018-01-18
    相关资源
    最近更新 更多