Удалить PFUser с помощью Cloud Code Parse.com iOS

Мне удалось добавить друга с помощью Cloud Code и Parse.com.

Теперь я хочу удалить дружеские отношения с Cloud Code в didSelectRowAtIndexPath.

Моя ошибка "attempt to insert nil object from objects[0]'"

Но я не знаю, какие параметры мне нужно настроить, я нашел облачный код для main.js:

Parse.Cloud.define("removeFriend", function(request, response) 
{
    // here's how to get the client's user making the request
    var user = request.user;

    // consider checking that user && request.params.friend are valid
    // if not, return response.error("missing user or friend id")

    getUser(request.params.friend).then(function(friend) {
        // your code prematurely called response.success() here, thereby canceling any further steps
        friend.relation("friendsRelation").remove(user);
        // return the promise returned by save() so we can chain the promises
        return friend.save();
    }).then(function(result) {
        // only now that the save is finished, we can claim victory
        response.success(result);
    }, function (error) {
        response.error(result);
    });
});

// EDIT - the OP once referred to a getUser function that we assume to be something like this:
// return a promise to get a user with userId
function getUser(userId) {
    var userQuery = new Parse.Query(Parse.User);
    return userQuery.get(userId);
}

Вот мой код EditFriends.m:

    - (void)viewDidLoad
    {
        [super viewDidLoad];
        PFQuery *query = [PFUser query];
        [query orderByAscending:@"name"];
        [query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
            if (error) {
                NSLog(@"Error: %@ %@", error, [error userInfo]);
            }
            else {
                self.allUsers = objects;
                [self.tableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO];
            }
        }];

        self.currentUser = [PFUser currentUser];
        [self loadFriends];
    }

-(void) loadFriends{
    self.friendsRelation = [[PFUser currentUser] objectForKey:@"friends"];
    PFQuery *query = [self.friendsRelation query];
    [query orderByAscending:@"username"];
    [query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error)
     {
         if (error) {
             NSLog(@"Error %@ %@", error, [error userInfo]);
         }
         else {
             self.friends = objects;

             [self.tableView reloadData];
         }
     }];
}


    - (BOOL)isFriend:(PFUser *)user {
        for(PFUser *friend in self.friends) {
            if ([friend.objectId isEqualToString:user.objectId]) {
                return YES;
            }
        }

        return NO;
    }

CellForRowAtIndexPath:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

    PFUser *user = [self.allUsers objectAtIndex:indexPath.row];

    NSString *name = [[self.allUsers objectAtIndex:indexPath.row] valueForKey:@"username"];
    cell.textLabel.text = name;

    if ([self isFriend:user]) {
        cell.accessoryType = UITableViewCellAccessoryCheckmark;

    } else {

        cell.accessoryType = UITableViewCellAccessoryNone;
    }

    return cell;
}

didSelectRowAtIndexPath :

PFUser *selected = [self.allUsers objectAtIndex:indexPath.row];
    if ([self isFriend:selected]) {
        NSLog(@"déjà amis");
//        PFObject *friendRequest = [self.friendRequests objectAtIndex:indexPath.row];
        [PFCloud callFunctionInBackground:@"removeFriend" withParameters:@{@"friendRequest" : selected.objectId} block:^(id object, NSError *error) {

            if (!error) {
                //add the fromuser to the currentUsers friends

                //save the current user
                [self.currentUser saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {

                    if (succeeded) {



                    } else {

                    }

                }];

            }
            else {

            }


        }];

    }
else{
    PFUser *selectedUser = [self.allUsers objectAtIndex:indexPath.row];
    //request them
    PFObject *friendRequest = [PFObject objectWithClassName:@"FriendRequest"];
    friendRequest[@"from"] = self.currentUser;
    friendRequest[@"fromUsername"] = [[PFUser currentUser] objectForKey:@"username"];
    //selected user is the user at the cell that was selected
    friendRequest[@"to"] = selectedUser;
    // set the initial status to pending
    friendRequest[@"status"] = @"pending";
    [friendRequest saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {

        if (succeeded) {


            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Yay" message:@"Friend request sent" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
            [alert show];



        } else {

            // error occurred
        }
    }];
}

введите здесь описание изображения


person xcode_Dev    schedule 11.05.2015    source источник


Ответы (1)


Код iOS выглядит нормально, и нужно только убедиться, что он отправляет правильный идентификатор объекта пользователя.

Облачный код близок, но его нужно немного улучшить:

Parse.Cloud.define("removeFriend", function(request, response) 
{
    // here's how to get the client's user making the request
    var user = request.user;

    // consider checking that user && request.params.friend are valid
    // if not, return response.error("missing user or friend id")

    getUser(request.params.friendRequest).then(function(friend) {
        // your code prematurely called response.success() here, thereby canceling any further steps
        console.log("relation is:" + JSON.stringify(friend.relation("friends")));
        friend.relation("friends").remove(user);
        // return the promise returned by save() so we can chain the promises
        return friend.save();
    }).then(function(friend) {
        // friendship goes both ways, so remove the friend from user's friends
        user.relation("friends").remove(friend);
        return user.save();
    }).then(function(result) {
        // only now that the save is finished, we can claim victory
        console.log("relation is:" + JSON.stringify(result.relation("friends")));
        response.success(result);
    }, function (error) {
        response.error(error);
    });
});

// EDIT - the OP once referred to a getUser function that we assume to be something like this:
// return a promise to get a user with userId
function getUser(userId) {
    var userQuery = new Parse.Query(Parse.User);
    return userQuery.get(userId);
}

РЕДАКТИРОВАТЬ - чтобы позвонить:

PFUser *selected = [self.allUsers objectAtIndex:indexPath.row];
if ([self isFriend:selected]) {
    NSLog(@"déjà amis");
    [PFCloud callFunctionInBackground:@"removeFriend" withParameters:@{@"friendRequest" : selected.objectId} block:^(id object, NSError *error) {
    // etc.
person danh    schedule 11.05.2015
comment
Эй, спасибо за ответ, чувак! Я думаю, что не отправляю правильный идентификатор объекта пользователя, потому что мое приложение снова дает сбой: [__NSPlaceholderDictionary initWithObjects: forKeys: count:]: попытка вставить нулевой объект из объектов [0] '... Итак, какой-то объект равен нулю, я не не знаю, что я делаю неправильно, я не менял свой код iOS. - person xcode_Dev; 12.05.2015
comment
Мне удалось получить идентификатор объекта пользователя в didSelectRowAtIndexPath с помощью этого кода: PFUser *user = [self.allUsers objectAtIndex:indexPath.row]; NSString *objectId = [user objectId]; Но что мне делать дальше? Большое спасибо! - person xcode_Dev; 12.05.2015
comment
Это потому, что friendRequest равен нулю, но я не знаю, как это исправить, какие параметры мне нужны ... Я обновил свой пост скриншотом из Parse - person xcode_Dev; 12.05.2015
comment
Облачный код ожидает текущего пользователя и идентификатор другого пользователя, у которого есть текущий пользователь внутри его friendsRelation. Когда пользователь выбран, где isFriend == YES, я думаю, вам следует пропустить весь этот код и просто вызвать облако с идентификатором объекта выбранного пользователя. - person danh; 12.05.2015
comment
Хорошо, я понимаю процесс, я отредактировал свой код в didSelect... Итак, у меня есть текущий пользователь в viewDidLoad : self.currentUser, выбранный идентификатор пользователя находится в didSelect с selected.objectId. Я пытался запустить свое приложение, и оно не вылетает, но пишет: [Ошибка]: ReferenceError: getUser не определен в main.js:81:5 (Код: 141, Версия: 1.7.2) - person xcode_Dev; 12.05.2015
comment
Нет, я обновил свой код полным облачным кодом, и editUser() не появляется. - person xcode_Dev; 12.05.2015
comment
Извините, я имел в виду getUser(), функция, указанная при разборе как отсутствующая. В вашем исходном сообщении указывалось, что у вас есть эта функция возврата обещания, чтобы получить пользователю идентификатор пользователя. Ты не? Это очень простая функция для написания, почти слишком простая, чтобы даже возиться с ней. Просто добавьте запрос для пользователя. Я отредактирую, чтобы проиллюстрировать. - person danh; 12.05.2015
comment
Большое спасибо, но у меня последняя проблема: [Ошибка]: ReferenceError: результат не определен в main.js:90:24 в f (Parse.js:3:9004) в Parse.js:3:8496 в Array.forEach (собственный) в Object.x.each.x.forEach [как _arrayEach] (Parse.js:1:661) в c.extend.reject (Parse.js:3:8449) в f (Parse. js:3:9199) в Parse.js:3:8496 в Array.forEach (собственный) в Object.x.each.x.forEach [как _arrayEach] (Parse.js:1:661) (Код: 141, версия : 1.7.2) - person xcode_Dev; 12.05.2015
comment
Давайте продолжим это обсуждение в чате. - person xcode_Dev; 12.05.2015