【问题标题】:Retrieve object data from Parse in Swift在 Swift 中从 Parse 中检索对象数据
【发布时间】:2015-09-29 21:12:46
【问题描述】:

我在 Parse 中建立了一个小型测试数据库,您可以在下面看到:

有一个国家'name'、国家'code'和国家'currency'

所以应用的主要上下文是这样的:

  1. 在第一个屏幕上,有一个文本字段,如果他们按下它,它会将他们带到一个 tableview 控制器并填充来自 Parse 的国家/地区列表(您在上面看到的 6 个 - 这一切都很好)
  2. 当他们选择一个国家时,它会将他们带回第一个 VC 并将国家保存到一个字符串类型的变量中。称为“countryChosen”(这很好用)
  3. 当他们按下确认按钮时,它会将他们带到 ResultsVC。它上面有 3 个标签,一个是他们在 tableView 中选择的国家/地区的名称,一个是“代码”,一个是该选定国家/地区的“货币”。请参阅下面的布局:

目前,在这个屏幕上,我已经用国家名称更新了顶部标签,没有问题。我使用了这段代码:

import UIKit
import Parse

class ResultsViewController: UIViewController {

@IBOutlet weak var countryChosenLabel: UILabel!

@IBOutlet weak var countryCodeLabel: UILabel!

@IBOutlet weak var countryCurrencyLabel: UILabel!

override func viewDidLoad() {
    super.viewDidLoad()

    countryChosenLabel.text = countryChosen

}

我正在努力解决的问题

我需要使用 Parse 中的正确数据填充其他 2 个标签。例如,如果用户选择国家英国,那么当他们到达 ResultsVC 时,它可能会显示:英国、GB、GBP。

我不知道如何对 Parse 进行查询以获取此信息。我对使用 Parse 很陌生,所以任何帮助都会有帮助!

非常感谢。

更新 我的 TableViewController.swift 中的代码

import UIKit
import Parse

class TableViewController: UITableViewController {

var country = [String]()

var pickedCountry: String?

override func viewDidLoad() {
    super.viewDidLoad()

    var countryQuery = PFQuery(className: "country")
    countryQuery.orderByAscending("name")
    countryQuery.findObjectsInBackgroundWithBlock {
        (countryName:[AnyObject]?, error: NSError?) -> Void in

        if error == nil {

            for name in countryName! {

                self.country.append(name["name"] as! String)

            }

            self.tableView.reloadData()


        } else {

            print(error)

        }

    }

}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()

}


override func numberOfSectionsInTableView(tableView: UITableView) -> Int {

    return 1
}

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

    return country.count
}


override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath)

    cell.textLabel!.text = country[indexPath.row]

    return cell
}

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

    if segue.identifier == "pickedCountry" {

        let cell = sender as! UITableViewCell
        let index = tableView.indexPathForCell(cell)

        if let indexPath = index?.row {

            pickedCountry = country[indexPath]

        }
    }

}
}

第一个 ViewController.swift

import UIKit
import Parse

var countryChosen: String!

class ViewController: UIViewController, UITextFieldDelegate {

@IBOutlet weak var textfield: UITextField!

@IBOutlet weak var button: UIButton!

@IBAction func TFPressed(sender: AnyObject) {

    performSegueWithIdentifier("toTable", sender: self)

}

@IBAction func buttonPressed(sender: AnyObject) {

    if textfield.text != nil {

        performSegueWithIdentifier("done", sender: self)

    }

    countryChosen = textfield.text!

    print(countryChosen)

}

@IBAction func selectedCountry (segue: UIStoryboardSegue) {

    let countryTableViewController = segue.sourceViewController as! TableViewController

    if let selectedCountry = countryTableViewController.pickedCountry {

        textfield.text = selectedCountry

    }

}
}

【问题讨论】:

  • 您不需要再次查询 Parse,因为您已经拥有 Parse 中的数据。不返回字符串变量,而是返回整个 PFObject。然后,您可以在需要值时访问列
  • @Paulw11 嗨,Paul,所以在用户从 TableViewVC 中选择了他们的国家并将其传递回第一个 VC 之后,我将 textField 文本分配给“chosenCountry”变量。这就是我目前在 ResultsVC 上填充第一个标签的方式。正如你所提到的,我不确定如何返回整个对象 - 这就是我正在努力解决的问题。你能用一些代码告诉我怎么做吗?
  • 你能否更新你的问题以显示你传回字符串的代码,我会告诉你如何传回对象
  • @Paulw11 代码已添加,非常感谢!

标签: ios swift parse-platform


【解决方案1】:

第一步是保留您检索到的PFObjects,而不是简单地提取国家名称并将对象扔掉,因为您稍后会需要它。

import UIKit
import Parse

class TableViewController: UITableViewController {

var country = [PFObject]()

var pickedCountry: PFObject?

override func viewDidLoad() {
    super.viewDidLoad()

    var countryQuery = PFQuery(className: "country")
    countryQuery.orderByAscending("name")
    countryQuery.findObjectsInBackgroundWithBlock {
        (countries:[AnyObject]?, error: NSError?) -> Void in

        if error == nil {
            self.country=countries as! [PFObject]
            self.tableView.reloadData()
        } else {
            print(error)
        }
    }
}

这意味着您将需要更改访问数据的方法 - cellForRowAtIndexPath

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath)
    let rowCountry = country[indexPath.row]
    cell.textLabel!.text = rowCountry["name"]

    return cell
}

现在在您的原始视图控制器中,当您访问 pickedCountry 时,它将是 PFObject,您可以访问各个字段 -

import UIKit
import Parse

class ResultsViewController: UIViewController {

@IBOutlet weak var countryChosenLabel: UILabel!

@IBOutlet weak var countryCodeLabel: UILabel!

@IBOutlet weak var countryCurrencyLabel: UILabel!

override func viewDidLoad() {
    super.viewDidLoad()

    countryChosenLabel.text = countryChosen["name"]
    countryCodeLabel.text = countryChosen["code"]
    countryCurrencyLabel.text = countryChosen["currency"]

}

您需要在第一个视图控制器中进行类似的更改 - 将字符串变量更改为 PFObject 并访问国家/地区名称字段

import UIKit
import Parse

var countryChosen: PFObject!

@IBAction func buttonPressed(sender: AnyObject) {

    if textfield.text != nil {
        performSegueWithIdentifier("done", sender: self)   
    }

    // countryChosen = textfield.text!  // You can't do this any more because you need a PFObject, not text.  I am not sure you would want to anyway, because they may have typed an invalid country.  Probably use a label instead of a text field
     print(countryChosen)
}

@IBAction func selectedCountry (segue: UIStoryboardSegue) {

    let countryTableViewController = segue.sourceViewController as! TableViewController

    if let selectedCountry = countryTableViewController.pickedCountry {
        textfield.text = selectedCountry["name"]
    }
}

【讨论】:

  • @Paulw11 谢谢保罗,我在问题中添加了第一个 VC 代码。
  • @Paulw11 嗨,Paul,我在 cellForRowAtIndexPath 方法中的一行文本中遇到错误。它违反了这条线:cell.textLabel!.text = rowCountry["name"],错误是:无法分配“AnyObject?”类型的值到“字符串”类型的值。有什么想法吗?
  • 你需要向下转型加as! string到最后
  • @Paulw11 谢谢保罗,我已经添加了它,它消除了错误。但是,当我运行应用程序时,当我按下文本字段并加载表格视图时,应用程序崩溃并针对该行显示 EXC_BAD_INSTRUCTION cell.textLabel!.text = rowCountry["name"] 并在日志中显示:致命错误:打开包装时意外发现 nil可选值。
  • 好的,我给了你基本的解决方案,但是你需要让它更强大。如果有可能某些东西可能为零,那么您需要有条件地解开它,而不是像我一样强制解开它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-09
  • 1970-01-01
  • 2015-08-09
  • 2014-12-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多