如何防止Parse保存PFObject孩子的?

时间:2016-03-10 15:43:33

标签: ios swift parse-platform pfobject

我正面临着Parse和iOS的一个非常普遍的问题。

我的课程 POST ,结构如下:

  • text(String)
  • Image (PFFile)
  • LikesUsers (Array of String)
  • LikesCount (Int)
  • From (Pointer to User who posted it)

如果用户(已登录)喜欢帖子。我只是递增喜欢并将用户的Objectid添加到数组

例如:User-2喜欢User-1的帖子。

PostObject.incrementKey("Likes")
PostObject.addObject((PFUser.currentUser()?.objectId)!, forKey: "LikesUsers")
PostObject.saveEventually()

问题在这里。我不能保存PostObject,只要它有一个指向另一个用户的指针(比登录)我收到错误:

  

除非已通过logIn或身份验证,否则无法保存用户   注册

那么如何防止保存ParseObject Children(“From”)

我不想使用CloudCode,我希望保持简单,并使用SaveEventually来获得更好的用户体验。

3 个答案:

答案 0 :(得分:2)

来自parse.com论坛:

  

当您使用指针保存对象时,Parse会查看整个对象并保存“脏”字段(自上次保存后更改)。它还检查指针指向的所有对象。如果您的对象具有指向PFUser的指针并且PFUser的实例为“脏”,则Parse将保存该对象,然后也尝试保存PFUser的实例。我的假设是,在代码中的某个位置,您正在为用户设置值,然后不保存用户。我怀疑这是你错误的根源。浏览代码并查找设置PFUser实例的任何位置,并确保有相应的保存。如果您一眼就看不到它,请务必检查所有块并确保您不会异步弄脏用户并随后尝试保存它。

您是否尝试对发布帖子的用户进行任何更改?

答案 1 :(得分:2)

简答:

尝试将from字段设置为:

let author = PostObject["from"] as! PFObject
PostObject["from"] = PFObject(withoutDataWithClassName: "_User", 
    objectId: author.objectId)

未经测试。

但我建议您更改架构

我遇到了同样的问题,最后决定将likes字段移到User类,然后将其设为Relation<Post>类型。解析文档说Relation类型更适合保留许多对象。由于LikesUsers是一个对象数组,如果帖子会有很多喜欢,性能可能会大幅下降:该应用将下载所有喜欢此帖子的用户。有关详情,请参阅此处:https://parse.com/docs/ios/guide#objects-relational-data

以下是我的类结构的样子(简化):

用户

  • postLikes(Relation)

发布

  • 作者(PFObject)
  • likesCount(Int)

我也喜欢/不喜欢逻辑到CloudCode函数:

/// The user liked or disliked the post.
Parse.Cloud.define("likeDislikePost", function(request, response) {
    var userProfileId = request.params.userProfileId
    var postId = request.params.postId
    // Shows whether the user liked or disliked the post. Bool value
    var like = request.params.like
    var query = new Parse.Query("_User");
    query.equalTo("objectId", userProfileId);
    query.first({
      success: function(userProfile) {
            if (userProfile) {
              var postQuery = new Parse.Query("Post");
              postQuery.equalTo("objectId", postId);
              postQuery.first({
                  success: function(post) {
                        if (post) {
                            var relation = userProfile.relation("postLikes");
                            if (like) {
                              relation.add(post);
                              post.increment("likesCount");
                            }
                            else {
                              relation.remove(post)
                              post.increment("likesCount", -1);
                            }
                            post.save();
                            userProfile.save();

                            console.log("The user with user profile id " + userProfileId + " " + (like ? "liked" : "disliked") + " the post with id " + postId);
                            response.success();
                        }
                        else {
                            response.error("Unable to find a post with such ID");
                        }         
                  },
                  error: function() {
                    response.error("Unable to like the post");
                  }
              });
            }
            else {
                response.error("Unable to find a user profile with such ID");
            }         
      },
      error: function() {
        response.error("Unable to like the post");
      }
  });
});

工作得很好。

答案 2 :(得分:0)

我从头开始为你创建了一些项目。我认为你在创建PFClass时会遗漏一些东西。我不知道。不管我的代码是什么,

这是ViewController,它包含类似按钮操作;

    import UIKit

    class ViewController: UIViewController {

    private let test = Test() // PFObject SubClass
    private let post = Post() // PFObject SubClass

    @IBAction func likeButton() {

        self.test.fromUser = PFUser.currentUser() // Current User
        self.test.likedUsers.append(Post().user  // In there your post should be a Subclass of PFObject too like your this Test class and it should be contains Owner property. So you can grab the Post owner PFUser or User Object ID.)
        self.test.saveEventually() {
            (let success, error) in
            if error == nil {
                // Success
            } else {
                print(error?.localizedDescription)
            }
        }
    }
}

在您的{{1>} 初始 ParseSDK 注册您的新Parse子类。

AppDelegate

测试子类;

   func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    // Override point for customization after application launch.
    Parse.setApplicationId("YOUR_API_KEY", clientKey: "YOUR_CLIENT_KEY")
    Test.registerSubclass()
    Post.registerSubclass()

    return true
}

发布子类;

import Foundation
import Parse

class Test: PFObject, PFSubclassing {

    // Your Properties
    @NSManaged var likedUsers: [PFUser]
    @NSManaged var fromUser: PFUser

    static func parseClassName() -> String {
        return "Test" // Your Class Name
    }
}

在我的情况下,它工作正常。如果您收到错误,请通知我。

有一个很好的编码。