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

Posted

技术标签:

【中文标题】Swift - Parse.com - 为啥这个闭包是错误的?【英文标题】:Swift - Parse.com - Why this closures are wrong?Swift - Parse.com - 为什么这个闭包是错误的? 【发布时间】:2015-07-15 15:31:03 【问题描述】:

实验一个名为 sweeter 的类似 Twitter 的应用程序的教程。一切正常,但登录和注册闭包不接受我的论点:

错误信息:

无法使用类型为“(String!,密码: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 错误消息“字符串不能转换为 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! 【参考方案1】:
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 ...

【讨论】:

这是您要找的吗? 是的!这非常有帮助,我也将您的回答标记为有帮助:) 哈哈好吧!一切顺利。 ;) 我编辑了这个问题,你能看看 EDIT 2.0 吗?不明白重点! 查看我现在发布的答案【参考方案2】:
 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()
       

【讨论】:

在括号中丢失!,无法理解部分 EDIT 2.0 应该切换到您的代码?我一定是错的,因为我有很多错误 复制粘贴并尝试一下。如果您再次发现错误,请告诉我 我已经删除了 tableview.reloadData() 之前的最后两行代码,因为它没有任何意义。没用的 改成这个var timeLineData : [PFObject] = [] 开头 你为 tableView 制作了@IBOutlet 吗??【参考方案3】:

我猜你应该用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

【讨论】:

@biggreentree 扔了哪些线? 42 - if (PFUser) println("login success!") else println()("login failed!") and 66 - else let errorString = error!.userInfo [“错误”]作为!字符串 println(errorString) if I modify in if PFUser() != nil Xcode 告诉二进制运算符“!=”不能应用于 PFUser 和 nil 编辑了答案,看看 很好!登录有效!你知道为什么解析控制台会话不断增长吗?

以上是关于Swift - Parse.com - 为啥这个闭包是错误的?的主要内容,如果未能解决你的问题,请参考以下文章

从 Parse.com (Swift) 检索数据

与 parse.com 的 signUpInBackgroundWithBlock:() 等效的 Swift 2.0 是啥?

Parse.com 多用户访问数据 - Swift

Swift 无法从 parse.com 检索图像

在 Swift (iOS) 中使用水平滑动浏览 Parse.com 中的数据

为啥从 parse.com 推送只能到达一台设备?