Swift - Parse.com - 为什么这个闭包是错误的?

Swift - Parse.com - Why this closures are wrong?

体验名为 sweeter 的类似 Twitter 应用程序的教程。一切正常,但登录和注册关闭不接受我的参数:

错误信息:

无法使用类型为“(String!, password: String!, (PFUser!, NSError!) -> Void)”的参数列表调用 'logInWithUsernameInBackground'

提前致谢

import UIKit
import Parse

class TimelineTableViewController: UITableViewController {

//    MARK: Parse
    override func viewDidAppear(animated: Bool) {

        if PFUser.currentUser() == nil {
        var loginAlertController = UIAlertController(title: "Sign up / login", message: "please sign up or login", preferredStyle: UIAlertControllerStyle.Alert)

            loginAlertController.addTextFieldWithConfigurationHandler({
                textfField in
                textfField.placeholder = "Your username"
            })

            loginAlertController.addTextFieldWithConfigurationHandler({
                textfField in
                textfField.placeholder = "Your password"
                textfField.secureTextEntry = true
            })

//            MARK: login action in the array
            loginAlertController.addAction(UIAlertAction(title: "Login Action", style: UIAlertActionStyle.Default, handler: {
                alertAction in
                let textFields : NSArray = loginAlertController.textFields!
                let usernameTextField : UITextField = textFields[0] as! UITextField
                let passwordTextField : UITextField = textFields[1] as! UITextField

                //MARK: Parse login problem - 15:39
                PFUser.logInWithUsernameInBackground(usernameTextField.text, password: passwordTextField.text){
                    (user: PFUser?, error: NSError?) -> Void in

                    if (PFUser) {
                        println("login success!")
                    } else {
                        println()("login failed!")
                    }
                }
            }))

//            MARK: sign up action in the array
            loginAlertController.addAction(UIAlertAction(title: "Sign up", style: UIAlertActionStyle.Default, handler: {
                alertAction in
                let textFields : NSArray = loginAlertController.textFields!
                let usernameTextField : UITextField = textFields[0] as! UITextField
                let passwordTextField : UITextField = textFields[1] as! UITextField

                var sweeter = PFUser() //16:42
                sweeter.username = usernameTextField.text
                sweeter.password = passwordTextField.text

                sweeter.signUpInBackgroundWithBlock({
                    (success: Bool, error: NSError?) -> Void in
                    if error == nil {
                        println("sign up successful")
                    } else {
                        let errorString = error!.userInfo["error"] as! String
                        println(errorString)
                    }
                })

            }))


            self.presentViewController(loginAlertController, animated: true, completion: nil)


        }
    }

编辑 2.0:

import UIKit
import Parse

class TimelineTableViewController: UITableViewController {


    var timeLineData : [String] = []

    func loadData() {
        timeLineData.removeAll(keepCapacity: true)

        var findTimelineData = PFQuery(className: "Sweeters")

        findTimelineData.findObjectsInBackgroundWithBlock({
            (objects : [AnyObject]?, error : NSError?) -> Void in

            if error == nil {
                for object in objects! {
                    self.timeLineData.append(object as! String)
                }
                let array : Array = self.timeLineData.reverse()
                self.timeLineData = array as Array

                self.tableView.reloadData()
            }
        })
    }





    //    MARK: Parse
    override func viewDidAppear(animated: Bool) {

        if PFUser.currentUser() == nil {
            var loginAlertController = UIAlertController(title: "Sign up / login", message: "please sign up or login", preferredStyle: UIAlertControllerStyle.Alert)

            loginAlertController.addTextFieldWithConfigurationHandler({
                textfField in
                textfField.placeholder = "Your username"
            })

            loginAlertController.addTextFieldWithConfigurationHandler({
                textfField in
                textfField.placeholder = "Your password"
                textfField.secureTextEntry = true
            })

            //            MARK: login action in the array
            loginAlertController.addAction(UIAlertAction(title: "Login Action", style: UIAlertActionStyle.Default, handler: {
                alertAction in
                let textFields : NSArray = loginAlertController.textFields!
                let usernameTextField : UITextField = textFields[0] as! UITextField
                let passwordTextField : UITextField = textFields[1] as! UITextField

                //MARK: Parse login problem - 15:39
                PFUser.logInWithUsernameInBackground(usernameTextField.text, password: passwordTextField.text){
                    (user: PFUser?, error: NSError?) -> Void in

                    if user != nil {
                        println("login success!")
                    } else {
                        println("login failed!")
                    }
                }
            }))

            //            MARK: sign up action in the array
            loginAlertController.addAction(UIAlertAction(title: "Sign up", style: UIAlertActionStyle.Default, handler: {
                alertAction in
                let textFields : NSArray = loginAlertController.textFields!
                let usernameTextField : UITextField = textFields[0] as! UITextField
                let passwordTextField : UITextField = textFields[1] as! UITextField

                var sweeter = PFUser() //16:42
                sweeter.username = usernameTextField.text
                sweeter.password = passwordTextField.text

                sweeter.signUpInBackgroundWithBlock({
                    (success: Bool, error: NSError?) -> Void in
                    if error == nil {
                        println("sign up successful")
                    } else {
                        //                        let errorString = error!.userInfo["error"] as! String
                        let errorString = error!.localizedDescription
                        println(errorString)
                    }
                })

            }))


            self.presentViewController(loginAlertController, animated: true, completion: nil)


        }
    }


    override func viewDidLoad() {
        super.viewDidLoad()

        // Uncomment the following line to preserve selection between presentations
        // self.clearsSelectionOnViewWillAppear = false

        // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
        // self.navigationItem.rightBarButtonItem = self.editButtonItem()
    }

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

    // MARK: - Table view data source

    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        // #warning Potentially incomplete method implementation.
        // Return the number of sections.
        return 1
    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // #warning Incomplete method implementation.
        // Return the number of rows in the section.
        return timeLineData.count
    }


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

        // Configure the cell...

        return cell
    }

截图

编辑 3.0 错误信息 "string is not convertible to PFObject"

 override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCellWithIdentifier("cellReuseID", forIndexPath: indexPath) as! SweetTableViewCell

        // Configure the cell...

        let sweet : PFObject = self.timeLineData[indexPath.row] as PFObject

        cell.sweetTextView.text = sweet.objectForKey("content") as! String

        return cell
    }

我想你应该用 PFUser?NSError?

替换 PFUser!NSError!

另外,仔细看看这个闭包:

sweeter.signUpInBackgroundWithBlock({
                    (success: Bool(), error: NSError()) -> Void in
                    if error == nil {
                        println("sign up successful")
                    } else {
                        let errorString = error.userInfo["error"] as String
                        println(errorString)
                    }
                })

我猜闭包参数应该是(success: Bool, error: NSError?) -> Void

编辑: 第一个错误是因为你不能在 Swift

中那样做
 if (PFUser) {

应该是user != nil

这一行有多余的()对println()("login failed!")

第二个错误已通过替换

修复
let errorString = error.userInfo["error"] as String

let errorString = error!.localizedDescription

PFUser.logInWithUsernameInBackground("myname", password:"mypass") {
  (user: PFUser?, error: NSError?) -> Void in
  if user != nil {
    // Do stuff after successful login.
  } else {
    // The login failed. Check error to see why.
  }
}

在你使用的块中 if(PFUser){ } 它应该是 if user {...}

 var timeLineData : [String] = []

    func loadData() {
        timeLineData.removeAll(keepCapacity: false)

        var findTimelineData = PFQuery(className: "Sweeters")

        findTimelineData.findObjectsInBackgroundWithBlock({
            (objects : [AnyObject]?, error : NSError?) -> Void in
            if error == nil {
                  // The find succeeded.
               println("Successfully retrieved \(objects!.count) objects.")
              // Do something with the found objects
             if let objects = objects as? [PFObject] {
                   for object in objects {
                     self.timeLineData.append(object as! String)
                  }
                }
               } else {
                  // Log details of the failure
                   println("Error: \(error!) \(error!.userInfo!)")
                  }
             })

      self.tableview.reloadData()
       }