使用委托将值保存到核心数据

时间:2017-02-21 19:55:18

标签: ios swift delegates

初学者,这是我第一次使用委托,我很困惑 - 我正试图在两个控制器之间传递数据,第一个是显示某些产品的tableview,另一个是模态允许用户输入要在该tableview上显示的新产品的视图。当用户在模态视图中点击“保存”时,我想将新产品保存到核心数据中并将其显示在tableview上。

用户在AddProductController(模态视图)的三个文本字段中输入信息,然后点击保存调用handleSave

func handleSave() {

    guard let newProductUrl = self.urlTextField.text else {
        print("error getting text from product url field")
        return
    }
    guard let newProductName = self.nameTextField.text else {
        print("error getting text from product name field")
        return
    }
    guard let newProductImage = self.logoTextField.text else {
        print("error getting text from product logo field")
        return
    }

    DispatchQueue.main.async {
        self.productSaveDelegate?.save(name: newProductName, url: newProductUrl, image: newProductImage)

        let companyController = CompanyController()
        self.navigationController?.pushViewController(companyController, animated: true)
    }

}

反过来调用save中的ProductController(表格视图):

func save(name: String, url: String, image: String) {

    guard let appDelegate =
        UIApplication.shared.delegate as? AppDelegate else {
            return
    }

    let managedContext =
        appDelegate.persistentContainer.viewContext

    let entity =
        NSEntityDescription.entity(forEntityName: "Product",
                                   in: managedContext)!

    let product = NSManagedObject(entity: entity,
                                  insertInto: managedContext)


    product.setValue(name, forKey: "name")
    product.setValue(url, forKey: "url")
    product.setValue(image, forKey: "image")


    do {
        try managedContext.save()
        products.append(product)
    } catch let error as NSError {
        print("Could not save. \(error), \(error.userInfo)")
    }
    tableView.reloadData()
}

如果我理解正确,我使用委托作为两者之间的一种链接,以便我可以将用户输入的值直接传递到我的save函数中?如果我错了,请纠正我,我很新。但是我在ProductController(tableview控制器)的顶部创建了类范围之外的委托,如下所示:

protocol ProductSaveDelegate {
    func save(name: String, url: String, image: String)
}

然后在AddProductController(用户输入新产品信息的模态视图)中,我初始化了类顶部附近的委托:

var productSaveDelegate: ProductSaveDelegate?

然后使用它来调用save中的handleSave()函数,如上所示。

当我尝试将ProductSaveDelegate添加到AddProductController的类定义时,我收到错误消息,指出AddProductController不符合协议。

我可以在此处更改以使用户输入的产品正确保存到核心数据?在此先感谢您的帮助!

2 个答案:

答案 0 :(得分:0)

代表们真的很酷很强大,但有时,是的,他们可能会让人感到困惑。您需要在ProductController内初始化委托,而不是AddProductController

这是一张很棒的图片,展示了委托和协议设置的工作原理:

enter image description here

图片来自Andrew Bancroft的website

在这种情况下,您的代表是您的ProductController,而您的代表是AddProductController

答案 1 :(得分:0)

请确认您已签署代理

不要忘记 -

classObject.delegate = self

我想你已经熟悉代表了,

您收到此错误的原因是,您not implemented the delegate method中有AddProductController(在您的情况下是假的,因为我可以看到它已实现),或者您忘记订阅该代表,这样做你需要确保 -

  
      
  1. 订阅代理,即在转换到下一个控制器之前,将代表设置为自我 -
  2.   
  // addProductController is the AddProductController Class's Object 

  addProductController.productSaveDelegate = self  
  self.navigationController?.present(addProductController, animated: true, completion: nil) 

同样在同一个类中你需要实现协议中定义的方法,例如你的func save(name: String, url: String, image: String)(已经实现)

您还可以查看small demo,我已在此处实施协议。