2016-03-10 22 views
7

Sto affrontando un problema molto comune con Parse e iOS.Come impedire a Parse di salvare i figli di PFObject?

Ho una classe POST con la seguente struttura:

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

e se l'utente (già connesso) ha inserito un post. Sto solo incrementando i Mi piace e aggiungo Objectid dell'utente all'array

Ad esempio: Utente 2 piace Post dell'utente 1.

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

Il problema è qui. Non riesco a salvare un l'PostObject fintanto che ha un puntatore ad un altro utente (rispetto al loggato) sto ottenendo l'errore:

utente non può essere salvato se non sono stati autenticati tramite il login o Iscriviti

Quindi, come evitare di salvare il ParseObject Children ("From")

non voglio usare un CloudCode, voglio mantenere le cose semplici e di utilizzare SaveEventually per una migliore esperienza utente .

+0

Se non sbaglio, si tratta di una sorta di problema di autorizzazione che stai affrontando. Dato che hai menzionato iOS, suppongo che tu stia facendo il lato client di aggiornamento. Poiché il post non appartiene all'utente corrente, non sarebbe in grado di salvarlo. Quello che puoi fare è creare una funzione cloudcode e chiamare quel metodo che passa lungo l'utente corrente. – Seeya

+0

Non riesco a fare un salvataggio alla fine da Parse Cloud –

+0

Puoi approfondire il motivo per cui non puoi? Qual è l'errore? – Seeya

risposta

2

Dai forum parse.com:

Quando si salva un oggetto con un puntatore, Parse guarda la totalità dell'oggetto e salva i campi che sono "sporco" (cambiato dall'ultimo salvataggio). Ispeziona anche tutti gli oggetti puntati da puntatori. Se il tuo oggetto ha un puntatore a PFUser e l'istanza di PFUser è "dirty", quindi Parse salverà l'oggetto e quindi tenterà di salvare anche l'istanza di PFUser. La mia ipotesi è che da qualche parte nel codice si imposta un valore su un utente e quindi non si salva l'utente. Questo, sospetto, è la fonte del tuo errore. Passare attraverso il codice e cercare ovunque si imposta un'istanza PFUser e assicurarsi che vi sia un salvataggio corrispondente. Se non riesci a trovarlo a prima vista, assicurati di controllare tutti i blocchi e assicurati di non sporcare in modo asincrono un utente e successivamente di salvarlo.

Stai tentando di apportare modifiche all'utente in base al post?

+0

Ho passato il mio codice e non sto cercando di cambiare il PFUser o di apportare modifiche –

2

Risposta breve:

tenta di impostare from campo come:

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

Questo non è testato.

ma suggerisco di cambiare l'architettura

stavo affrontando lo stesso problema e finalmente deciso di muoversi likes campo per User classe invece e renderlo Relation<Post> tipo. La documentazione di Parse dice che il tipo Relation è migliore per mantenere molti oggetti. Dal momento che LikesUsers è una matrice di oggetti, le prestazioni potrebbero diminuire in modo significativo se un post otterrà molti Mi piace: l'app scaricherà tutti gli utenti ha gradito questo post. Vedere questo per maggiori informazioni: https://parse.com/docs/ios/guide#objects-relational-data

Ecco come la mia struttura di classe sembra (semplificato):

utente:

  • postLikes (Relation)

Messaggio :

  • autore (PFObject)
  • likesCount (Int)

ho anche spostato come la logica/avversione alla funzione 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"); 
     } 
    }); 
}); 

funziona bene.

+0

Grazie per la funzione cloud fornita, ma vorrei usare saveEventually con un'opzione offline –

+0

Bene, hai provato il risposta breve? –

+0

Sì, ho provato la risposta breve –

0

Ho creato un progetto da zero per te. Penso che ti manchi qualcosa quando crei il tuo PFClass. Non lo so. Qualunque aspetto i miei codici,

Questo è il ViewController e contiene come Pulsante Azione;

Nella tua AppDelegateinit tua ParseSDK e Registrati vostre nuove sottoclassi di analisi.

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 
} 

prova sottoclasse;

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 
    } 
} 

Messaggio sottoclasse;

class Post: PFObject, PFSubclassing { 

    // Your Properties 
    @NSManaged var owner: PFUser 
    @NSManaged var likeCount: NSNumber 

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

Nel mio caso funziona correttamente. Se ricevi un errore per favore informami.

Buona codifica.

+0

@Yasser B. hai risolto il tuo problema? – emresancaktar

+0

No, questo non risolve il problema! Penso che tu abbia frainteso la domanda –

Problemi correlati