Trouble with Parse Relations - ios

// Posts a message to the backend database
- (void)postMessage:(NSString *)message
{
// return right away if message is nil or all whitespace
if (!message || ![[message stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] length]) {
return;
}
// Create new Message object and set relationships
PFObject *postedMessage = [PFObject objectWithClassName:#"Message"];
postedMessage[#"text"] = message;
PFRelation *tagRelation = [postedMessage relationForKey:#"tags"];
NSMutableArray *tags = [self generateTagsFromMessage:message];
NSLog(#"Number of Tags Found: %lu", (unsigned long)[tags count]);
[PFObject saveAllInBackground:tags block:^(BOOL succeeded, NSError *error) {
for (PFObject *tag in tags) {
// [tagRelation addObject:tag];
NSLog(#"%#", tag[#"text"]);
[tag setObject:postedMessage forKey:#"message"];
}
}];
[postedMessage saveInBackground]
}
I am using Parse as the back end for my application, but am having inexplicable difficulty creating a one-to-many relationship.
The idea is to make it so that users can post messages to the database with a tag on them, and the database stores Messages as one class, and Tags as another. The Message class has a "tags" field intended to store all tags in the message, and the Tag class has a "message" field intended to store the parent message of the tag. I thought I followed the tutorial of how to create a One-to-many relationship in Parse very well, but no matter what I cannot see the relationship on the Data Browser in Parse.
I have tried getting the relation to work by both simply setting the postedMessage as the newTag's message field, and also by creating a PFRelation * for the tags field of the message and adding tags to that. None of it works.
Does anybody know what my problem might be?
Thank you!
Edit
Specifically, the problem is that no relation is formed between the objects. By inspecting the data browser I can see that both the "tags" relational field of Message and "message" relational field of Tag remain blank after running this code.

An issue with your above code is that you're creating two new objects at once and triggering background saves on both at once.
For this to work, you need to save one side of the relationship first, then create the new objects, relate them and save them (in the block).
In your case you have a single message from multiple tags, so create the message and save it, then in the save block create the tags, add them to the message and re-save the message (it'll walk the tree looking for changes and save the new tags).
// Create new Message object
PFObject *postedMessage = [PFObject objectWithClassName:#"Message"];
postedMessage[#"text"] = message;
[postedMessage saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
// message saved, now create tags with link to message
PFRelation *tagRelation = [postedMessage relationForKey:#"tags"];
NSMutableArray *tags = [self generateTagsFromMessage:message];
NSLog(#"Number of Tags Found: %lu", (unsigned long)[tags count]);
for (PFObject *tag in tags) {
NSLog(#"%#", tag[#"text"]);
[tag setObject:postedMessage forKey:#"message"];
}
// now save the tags
[PFObject saveAllInBackground:tags block:^(BOOL succeeded, NSError *error) {
// now add the relationships
for (PFObject *tag in tags) {
[tagRelation addObject:tag];
}
// and save
[postedMessage saveInBackground];
}];
}];

Your code is almost correct, but you missed a few details. See my working version of your code re-written below. But first, read through the examples from Parse.
Take a look at this example from the Parse iOS documentation where they are setting the pointer relationship between two objects; a One-to-One relationship.
Neither object must have an objectId before creating the relationship.
// Create the post
PFObject *myPost = [PFObject objectWithClassName:#"Post"];
myPost[#"title"] = #"I'm Hungry";
myPost[#"content"] = #"Where should we go for lunch?";
// Create the comment
PFObject *myComment = [PFObject objectWithClassName:#"Comment"];
myComment[#"content"] = #"Let's do Sushirrito.";
// Add a relation between the Post and Comment
myComment[#"parent"] = myPost;
// This will save both myPost and myComment
[myComment saveInBackground];
What you are looking for is either a One-to-Many relationship array of pointers, which is outlined here and copied below for easy reference.
One object must have an objectId before creating the relationship
// Create Post
PFObject *newPost = [PFObject objectWithClassName:#"Post"];
// Set text content
[newPost setObject:[textView text] forKey:#"textContent"];
// Create relationship
[newPost setObject:[PFUser currentUser] forKey:#"author"];
// Save the new post
[newPost saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (!error) {
// Dismiss the NewPostViewController and show the BlogTableViewController
[self dismissModalViewControllerAnimated:YES];
}
}];
OR you are looking for a One-to-Many relationship using the PFRelation object because; "you don't need to download all the Objects in a relation at once. This allows PFRelation to scale to many more objects than the NSArray of PFObject approach" . If this approach is what you are looking for, your re-written code below will work.
One object must have on objectId before creating the relationship
// Create new Message object and set relationships
PFObject *postedMessage = [PFObject objectWithClassName:#"TestClass"];
postedMessage[#"text"] = #"Hello World";
//example tags into array
PFObject *tag1 = [PFObject objectWithClassName:#"Tag"];
PFObject *tag2 = [PFObject objectWithClassName:#"Tag"];
PFObject *tag3 = [PFObject objectWithClassName:#"Tag"];
PFObject *tag4 = [PFObject objectWithClassName:#"Tag"];
NSArray *tags = [NSArray arrayWithObjects:tag1, tag2, tag3, tag4, nil];
//iterate the tags, add pointer for each
for (PFObject *tag in tags) {
//create a new tag-to-message pointer
[tag setObject:postedMessage forKey:#"message"];
}
//save all the tags and save the postedMessage
[PFObject saveAllInBackground:tags block:^(BOOL succeeded, NSError *error) {
if (!error) {
NSLog(#"created new postedMessage w/o relations :%#", postedMessage);
NSLog(#"saved tags with pointers :%#", tags);
PFRelation *tagRelation = [postedMessage relationForKey:#"tags"];
//iterate the tags, add relation for each
for (PFObject *tag in tags) {
//create a new postedMessage-to-tag relationship
[tagRelation addObject:tag];
}
//update the postedMessage
[postedMessage saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (!error) {
NSLog(#"updated postedMessage with relations :%#", postedMessage);
}
}];
}
}];
Edit: Adding the code I wrote; which works as you would expect. Once you get your relationships working there is one thing you will encounter using the Browser and that is an "object not found" error when you click on an object relationship from an object that is not directly related. A better way to explain that is to refer you to my example below.
I created a Message-to-Notification-to-User relationship -- think of it in any direction you prefer. When I access this relationship data using the Browser in CoreData and I click on the Users notifications relations column, I am directed to the users notifications. However; when I click on any of the message relations column, I received the, "object not found" error message. This is expected behavior and logically it makes sense. The User object doesn't care what messages its notifications contain, much like how the messages don't care who the user is. When the User object calls delete on a notification, auto-cleanup removes the messages without the User object needing to worry about them. When an object has no reference pointers and auto-cleanup is called, the object will be removed.
- (void)addNotificationWithData:(NSDictionary*)userInfo withCompletionHandler:(void(^)(BOOL isFinished))completionHandler {
PFObject *notification = [PFObject objectWithClassName:#"Notification"];
PFObject *msg = [PFObject objectWithClassName:#"Message"];
[msg saveEventually:^(BOOL succeeded, NSError *error) {
if (!error) {
PFRelation *notification_to_message = [notification relationForKey:#"messages"];
[notification_to_message addObject:msg];
[notification saveEventually:^(BOOL succeeded, NSError *error) {
if (!error) {
PFRelation *user_to_notification = [[PFUser currentUser]relationForKey:#"notifications"];
[user_to_notification addObject:notification];
[[PFUser currentUser]saveEventually:^(BOOL succeeded, NSError *error) {
if (!error) {
//add the notication to the notification(s)
[notifications addObject:notification];
NSLog(#"the current notifications are :%#", notifications);
//call the completion handler
if (completionHandler) {
completionHandler(YES);
}
}
}];
}
}];
}
}];
}

You've commented out the addObject call to add the object to the relation. You'll need to uncomment that line in order to actually add the object to the relation.

Related

Save data at parse.com it gives error "P_ID must be objectId not an NSString type"

I have two tables at my parse account "Products" and "Orders". When I save data in "Orders" table I need "P_ID" which is the objectId of "Products" table. Can anybody tell me how I get this id using object.
I have no issue fetching the products but when I set order objects it gives error see the below code :
PFObject *orders = [PFObject objectWithClassName:#"Orders"]; [orders setObject: object.productID objectForKey:#"P_ID"]; [order setObject:object.quantity objectForKey:#"Qty"];
and then 'saveInBackgroundWithBlock' block code.
I suggest you read the documentation on Parse.com about saving and querying objects, they have really good tutorials/examples/explanations.
Also, your statement is wrong :
When I save data in "Orders" table I need "P_ID" which is the objectId of "Products" table.
It's not the object ID of the table, I think you meant the object ID of your product object. But that's not the question.
Now you need to fetch all your products, I'm guessing.
PFQuery *query = [PFQuery queryWithClassName:#"Products"];
//You can filter the query, to only get some of the products
//[query whereKey:#"Type" equalTo:#"Vegetable"];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
// The find succeeded.
NSLog(#"Successfully retrieved %d products.", objects.count);
// Do something with the found objects
//These are all your products.
//You can store in an array, a database, anything.
//Here we simply log all the objectIds in the console,
//you could manipulate them as you wish.
for (PFObject *product in objects) {
NSLog(#"%#", product.objectId);
}
} else {
// Log details of the failure
NSLog(#"Error: %# %#", error, [error userInfo]);
}
}];
We assume you have product(s) now, lets say it's a PFObject named theProduct.
Now, you want an new Order object that needs to be saved :
PFObject *order = [PFObject objectWithClassName:#"Order"];
order[#"totalPrice"] = #1337;
order[#"P_ID"] = theProduct.objectId;
[order saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (succeeded) {
// The object has been saved.
} else {
// There was a problem, check error.description
}
}];
Finally I've got answer of my question. For saving data in "Orders" I need object of "Products" class which I got from below code:
PFObject * products = [PFObject objectWithoutDataWithClassName:#"Products" objectId:productObj.productID];
In above code 'productObj.productID' is objectId of products in NSString type. then I simply set object in orders like below.
PFObject *orders = [PFObject objectWithClassName:#"Orders"];
[orders setObject: products objectForKey:#"P_ID"];
[order setObject:#(object.quantity) objectForKey:#"Qty"];
'#(object.quantity)' is an integer value which I saved in orders table.

Parse - Using Local Datastore with Relations

My situation includes having PFObjects that are connected with relations and I want to add to the relation using the local datastore.
So, I have a screen that creates a main object and saves it to the data store and server properly like so:
// Save User
PFObject *parseUser = [PFObject objectWithClassName:#"Users"];
parseUser[#"name"] = name;
parseUser[#"uuid"] = userUuid;
[parseUser saveEventually];
// Save List
PFObject *parseList = [PFObject objectWithClassName:#"Lists"];
parseList[#"name"] = newList.listName;
parseList[#"uuid"] = newList.listUuid;
[parseList saveEventually];
[parseUser pinInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (succeeded) {
// Create relation
PFRelation *relation = [parseUser relationForKey:#"listAccess"];
[relation addObject:parseList];
[parseUser saveEventually];
}
}];
[parseList pinInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (succeeded) {
// Create relation
PFRelation *relation = [parseList relationForKey:#"sharedWith"];
[relation addObject:parseUser];
[parseList saveEventually];
}
}];
So this part works. This took me a bit to figure out as well, but it works. Creates the User and List. Sets the relations of both then saves. Easy.
On to the problem area:
// Save List
PFObject *parseList = [PFObject objectWithClassName:#"Lists"];
parseList[#"name"] = newList.listName;
parseList[#"uuid"] = newList.listUuid;
[parseList saveEventually];
PFQuery *query = [PFQuery queryWithClassName:#"Users"];
[query fromLocalDatastore];
[query whereKey:#"uuid" equalTo:[User instance].userUuid];
[[query findObjectsInBackground] continueWithBlock:^id(BFTask *task) {
if (task.error) {
NSLog(#"Error: %#", task.error);
return task;
}
PFObject *user = [task.result objectAtIndex:0];
// Create relation
PFRelation *relation = [user relationForKey:#"listAccess"];
[relation addObject:parseList];
[user saveEventually];
PFQuery *relationQuery = [relation query];
[[relationQuery findObjectsInBackground] continueWithBlock:^id(BFTask *task) {
NSLog(#"resutls: %#", task.result);
return task;
}];
[parseList pinInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (succeeded) {
// Create relation
PFRelation *relation = [parseList relationForKey:#"sharedWith"];
[relation addObject:user];
[parseList saveEventually];
}
}];
return task;
}];
So what I am thinking I am doing here is grabbing the user from the local data store and adding another relation to it. But in reality, this actually is only saving the parseList to user relation. User doesn't get changed in the datastore or the server.
Other things I've tried:
Querying just the server
Pinning the User object with a name
EDIT: includeKey (This doesn't work as the include isn't a PFObject.)
Thanks for the help in advance.
Edit:
Looking through the query and relation grabs I get some weird data information.
So, first off, the relation is empty when searching through it like so:
estimatedData
0 - name - Bill Nye
1 - listAcces - no summary
value - PFRelation
knownObjects - 0 objects
2 - uuid - long string that is uuid
So this matches the server stuff, all besides the relation. But, when I query the relation and log it, I get this:
resutls: (
" {\n name = Okkkkk;\n sharedWith = \" Users>\";\n uuid = \"D8174D80-4F08-4B25-9B72-F8E00CF19DDB\";\n}"
)
So querying it, it is there, but it doesn't exist to the relation?

Parse.com returns empty objects

I have an NSArray called "malls" that contains a large number of NSDictionaries (each a specific mall) that I uploaded to Parse.com. I want my users to be able to access this information to create map annotations.
I've tried to do this in 2 different ways:
I tried uploading the entire array as a property of a single object:
this is the upload:
in the dataBank.h file:
#property (strong, nonatomic) NSMutableArray* malls;
in the .m file
PFObject *obj = [PFObject objectWithClassName:#"malls"];
obj[#"mallsData"] = self.malls;
[obj saveInBackground];
I try to get the data from parse:
-(NSMutableArray *)createAnnotationsFromParse
{
__block NSMutableArray* data = [[NSMutableArray alloc]init];
__block NSMutableArray* annots = [[NSMutableArray alloc]init];
PFQuery* query = [PFQuery queryWithClassName:#"malls"];
[query getObjectInBackgroundWithId:#"Eaib9yfTRe" block:^(PFObject *object, NSError *error) {
data = [object objectForKey:#"mallsData"];
annots = [self createAnnotations:data];
}];
return annots;
}
The problem is getObjectInBackground is asynchronous and always returns before getting the data from the server. I tried moving the "return annots" inside the code block but that gives the following error: "incompatible block pointer types".
I uploaded 5 "mall" objects to class "malls2". Each object has 2 properties- name and address:
for(int i = 0; i < 5; i++)
{
PFObject *mallsObj = [PFObject objectWithClassName:#"malls2"];
mallsObj[name] = [[self.malls objectAtIndex:i]objectForKey:name];
mallsObj[address] = [[self.malls objectAtIndex:i]objectForKey:address];
[mallsObj saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if(succeeded)
NSLog(#"yay");
else
NSLog(#"%#", error.description);
}];
}
then I try to get it back:
-(NSMutableArray *)createAnnotationsFromParse
{
__block Annotation* anno = [[Annotation alloc]init];
__block NSMutableArray* annots = [[NSMutableArray alloc]init];
PFQuery* query = [PFQuery queryWithClassName:#"malls2"];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if(error)
NSLog(#"%#", error.description);
else
{
for(int i = 0; i < [objects count]; i++)
{
//createAnnotationWithTitle is a func in a different class that creates the annotation
anno = [anno createAnnotationWithTitle:[[objects objectAtIndex:i] objectForKey:name] andAddress:[[objects objectAtIndex:i]objectForKey:address]];
}
[annots addObject:anno];
}
}];
return annots;
}
I get 5 objects but they're all empty.
It's a basic misunderstanding about asynchronous methods with block parameters. The trick is to get out of the habit of thinking that code that appears later in a source file runs later. The assumption works in this function:
- (void)regularFunction {
// these NSLogs run top to bottom
NSLog(#"first");
NSLog(#"second");
NSLog(#"third");
}
This will generate logs: first, second, third. Top to bottom, but not in this one:
- (void)functionThatMakesAsynchCall {
// these NSLogs do not run top to bottom
NSLog(#"first");
[someObject doSomeAsynchThing:^{
NSLog(#"second");
}];
NSLog(#"third");
}
That function will generate logs - first, third, second. The "second" NSLog will run well after the "third" one.
So what should you do? Don't try to update the UI with results of a parse call until after it completes, like this:
// declared void because we can't return anything useful
- (void)doSomeParseThing {
// if you change the UI here, change it to say: "we're busy calling parse"
PFQuery* query = [PFQuery queryWithClassName:#"malls2"];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if(!error) {
// change the UI here, say by setting the datasource to a UITableView
// equal to the objects block parameter
}
}];
// don't bother changing the UI here
// don't bother returning anything here
// we just started the request
}
But what if doSomeParseThing is really a model function, whose only job is to fetch from parse, not to know anything about UI? That's a very reasonable idea. To solve it, you need to build your model method the way parse built their's, with block parameter:
// in MyModel.m
// declared void because we can't return anything useful
+ (void)doSomeParseThing:(void (^)(NSArray *, NSError *))block {
PFQuery* query = [PFQuery queryWithClassName:#"malls2"];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
block(objects, error);
}];
}
Now your view controller can call, leave the query work to your model and the UI work to the vc:
// change UI to 'busy' here
[MyModel doSomeParseThing:^(NSArray *objects, NSError *error) {
// update UI with objects or error here
}];
Figured it out. It looked like I was getting "empty objects" (can be seen here postimg.org/image/ot7ehn29b ) but once I tried to access data from the objects I saw there was no problem. Basiclly I was tricked by the PFObjects in the array showing "0 objects" and assumed it meant they came back from Parse.com empty. Here's how I checked, just for reference:
PFQuery *query = [PFQuery queryWithClassName:#"malls2"];
NSArray *array = [query findObjects];
NSLog(#"%#", [[array objectAtIndex:0] objectForKey:#"name"]; // I have a string property called "name" in my Parse object.

Parse Custom cell show image according to boolean

I want to set ImageView hidden or not according to the boolean value true x false, which is located in Parse database. Could you give me some ideas how to do that? Got problems because of having property ImageView in my CustomCell.h
EDIT:
PFObject *yes = [PFObject objectWithClassName:#"MyClass"];
cell.discounts.hidden = [yes[#"yesnocolumn"] boolValue];
I just don`t understand to usage of PFObject, myclass returning (null) value.
EDIT2:
PFQuery *query = [PFQuery queryWithClassName:#"Classname"];
[query whereKey:#"yesnocolumn" equalTo:#1];
[query findObjectsInBackgroundWithBlock:^(NSArray *results, NSError *error) {
if (!error) {
cell.discounts.hidden = YES;
}else{
cell.discounts.hidden = NO;
}}];
The boolean from the service will look like either #0 or #1, so you can't just test for truthiness, because:
if (#0) {
// this condition is true. that's surprising!
}
So the safe way to test is to say:
cell.imageView.hidden = [myParseObject[#"hidden"] boolValue];
EDIT - Now I understand the misunderstanding. Here's how parse works:
1) Create an object locally:
PFObject *yes = [PFObject objectWithClassName:#"MyClass"];
This object won't have any values initialized. So any bools it contains will be 0, or NO.
2) Set some value locally:
yes[#"yesnocolumn"] = #1; // makes it true
// or = [NSNumber numberWithBool:YES];
3) Save it. (you can also use the data browser to initialize objects manually).
[yes saveInBackground];
4) Get an object. I think this is the part that's giving you trouble... just creating a local object doesn't really do much. The idea of parse is that objects are stored in the cloud. To get them, you need a PFQuery.
PFQuery *query = [PFQuery queryWithClassName:#"MyClass"];
[query findObjectsInBackgroundWithBlock:^(NSArray *results, NSError *error) {
// this will return all (up to 100 by default, MyClass objects that are
// saved in the cloud
if (!error && results.count) {
NSLog(#"the first object is %#", results[0]);
NSLog(#"the bool is %d", [results[0][#"yesnocolumn"] boolValue];
}
}];
Does this make sense? You can't expect the object to have any values initialized until you either set them locally, or retrieve already initialized remote copies. Also note, if you run the query on the next source line after saveInBackground, you won't get the saved result, since the save won't have finished. Start out saving in one run of your app, then reviewing in the data browser, then do a query.
It's worth doing a thorough review of their docs here.

parse.com trying to get a value from a User class once i have queried another class

i'm trying to post the users location with his display name in the Table View. but all I'm getting in the data browser is the correct post but the display name is blank
I'm trying to query the location Class and also the User Class which has the display name for the user
// Configure the new event with information from the location.
CLLocationCoordinate2D coordinate = [location coordinate];
PFGeoPoint *geoPoint = [PFGeoPoint geoPointWithLatitude:coordinate.latitude longitude:coordinate.longitude];
PFObject *object = [PFObject objectWithClassName:#"Location"];
[object setObject:geoPoint forKey:#"location"];
PFObject *UserObject = [PFObject objectWithClassName:#"_User"];
[[UserObject objectForKey:#"postedUser"] objectForKey:#"displayName"];
// Create relationship
[object setObject:[PFUser currentUser] forKey:#"postedUser"];
[UserObject setObject:[PFUser currentUser] forKey:#"displayName"];
PFACL *locatinACL = [PFACL ACLWithUser:[PFUser currentUser]];
[locatinACL setPublicReadAccess:YES];
[object saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (succeeded) {
}
}];
anyone know what I'm doing wrong. the display name is in the user class under displayName and i need it in the new post under displayName
the user save details saved under a form where the set has to fill in extra details after sign up
NSString *saveName = UserNameText.text;
NSString *saveEmail = EmailAddressText.text;
NSString *saveMobile = MobileText.text;
NSString *saveAdd1 = Address1Text.text;
NSString *saveAdd2 = Address2Text.text;
NSString *savePostCode = PostCodeText.text;
NSString *saveCustTax = TaxiOrCust.text;
currentUserSave[#"displayName"] = saveName;
currentUserSave[#"email"] = saveEmail;
currentUserSave[#"mobile"] = saveMobile;
currentUserSave[#"address1"] = saveAdd1;
currentUserSave[#"address2"] = saveAdd2;
currentUserSave[#"postCode"] = savePostCode;
currentUserSave[#"customer"] = saveCustTax;
Forgive the long answer... I think I'm still slightly unclear about your data structure and what you're trying to achieve, so it seems to make the most sense if I clarify what your existing code is actually doing. Hopefully this will help you make any necessary adjustments.
What you're currently doing
PFObject *object = [PFObject objectWithClassName:#"Location"];
[object setObject:geoPoint forKey:#"location"];
Here you're creating a new Location object, and setting the geopoint you've created as its location. If you have an existing Location object you want to update, you'll have to fetch that from Parse (unless you already have a variable / property for it).
PFObject *UserObject = [PFObject objectWithClassName:#"_User"];
Here you're creating a new User object. I suspect you want to use the current user, rather than create a new one, however. There's also a specific Parse object for users: PFUser - which you are using later on.
[[UserObject objectForKey:#"postedUser"] objectForKey:#"displayName"];
This line does nothing. You're fetching UserObject's postedUser property, and then fetching that user's displayName property. I don't think this is what you were intending.
[object setObject:[PFUser currentUser] forKey:#"postedUser"];
[UserObject setObject:[PFUser currentUser] forKey:#"displayName"];
This then updates the two new objects you created (your location and user objects), by setting two of their attributes to point to the current user.
PFACL *locatinACL = [PFACL ACLWithUser:[PFUser currentUser]];
[locatinACL setPublicReadAccess:YES];
These two lines create a new ACL which gives the current user write access, and everybody else read access. However, you're not applying this to your new location object.
[object saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (succeeded) {
}
}];
Finally, this will save your new Location object. However, the new User object you created will not be saved, as nothing else has a reference to it, and you're not calling save on it.
What you might be trying to do
I think the code you're writing can probably be cut down to something along these lines:
// Create a new location object
PFObject *parseLocation = [PFObject objectWithClassName:#"Location"];
// Create a new PFGeopoint, and store it as the location's location.
CLLocationCoordinate2D coordinate = [location coordinate];
PFGeoPoint *geoPoint = [PFGeoPoint geoPointWithLatitude:coordinate.latitude longitude:coordinate.longitude];
[parseLocation setObject:geoPoint forKey:#"location"];
// Store the current user and their display name as part of the location object
[parseLocation setObject:[PFUser currentUser] forKey:#"postedUser"];
[parseLocation setObject:[[PFUser currentUser] objectForKey:#"displayName"] forKey:#"displayName"];
// Create ACL and save it to the location object
PFACL *locationACL = [PFACL ACLWithUser:[PFUser currentUser]];
[locationACL setPublicReadAccess:YES];
[parseLocation setACL:locationACL];
// Save the location object
[object saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (succeeded) {
}
}];
Is this closer to what you wanted?

Resources