解析聊天错误

时间:2014-04-27 18:16:30

标签: ios chat parse-platform

我正在尝试基于Parse进行聊天我遵循本教程http://attila.tumblr.com/post/21180235691/ios-tutorial-creating-a-chat-room-using-parse-com,但当我尝试发送消息时,应用程序崩溃并出现此异常:

'NSInternalInconsistencyException', reason: 'attempt to insert row 0 into section 0, but there are only 0 rows in section 0 after the update'

我一直在努力修复它,但我找不到这个错误的原因,所以现在我正在努力找到帮助。这是我的代码:

#import "DMChatRoomViewController.h"
#import "chatCell.h"
@interface DMChatRoomViewController ()

@end

@implementation DMChatRoomViewController
@synthesize tfEntry;
@synthesize chatTable;
@synthesize chatData;
#define MAX_ENTRIES_LOADED 25


- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
tfEntry.delegate = self;
tfEntry.clearButtonMode = UITextFieldViewModeWhileEditing;
[self registerForKeyboardNotifications];
if (_refreshHeaderView == nil) {

    PF_EGORefreshTableHeaderView *view = [[PF_EGORefreshTableHeaderView alloc]  initWithFrame:CGRectMake(0.0f, 0.0f - chatTable.bounds.size.height, self.view.frame.size.width, chatTable.bounds.size.height)];
    view.delegate = self;
    [chatTable addSubview:view];
    _refreshHeaderView = view;
}
//  update the last update date
[_refreshHeaderView refreshLastUpdatedDate];
}

- (void)viewWillAppear{
className = @"chatroom";
userName = @"John Appleseed";
chatData  = [[NSMutableArray alloc] init];
[self loadLocalChat];
}

- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}

//Chat Room

- (void)viewDidUnload
{
[super viewDidUnload];
[self freeKeyboardNotifications];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
  return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

#pragma mark - Chat textfield

-(IBAction) textFieldDoneEditing : (id) sender
{ 
NSLog(@"the text content%@",tfEntry.text);
[sender resignFirstResponder];
[tfEntry resignFirstResponder];
}

-(IBAction) backgroundTap:(id) sender
{
[self.tfEntry resignFirstResponder];
}

- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
NSLog(@"the text content%@",tfEntry.text);
[textField resignFirstResponder];

if (tfEntry.text.length>0) {
    // updating the table immediately
    NSArray *keys = [NSArray arrayWithObjects:@"text", @"userName", @"date", nil];
    NSArray *objects = [NSArray arrayWithObjects:tfEntry.text, userName, [NSDate date], nil];
    NSDictionary *dictionary = [NSDictionary dictionaryWithObjects:objects forKeys:keys];
    [chatData addObject:dictionary];

    NSMutableArray *insertIndexPaths = [[NSMutableArray alloc] init];
    NSIndexPath *newPath = [NSIndexPath indexPathForRow:0 inSection:0];
    [insertIndexPaths addObject:newPath];
    [chatTable beginUpdates];
    [chatTable insertRowsAtIndexPaths:insertIndexPaths  withRowAnimation:UITableViewRowAnimationTop];
    [chatTable endUpdates];
    [chatTable reloadData];

    // going for the parsing
    PFObject *newMessage = [PFObject objectWithClassName:@"chatroom"];
    [newMessage setObject:tfEntry.text forKey:@"text"];
    [newMessage setObject:userName forKey:@"userName"];
    [newMessage setObject:[NSDate date] forKey:@"date"];
    [newMessage saveInBackground];
    tfEntry.text = @"";
}

// reload the data
[self loadLocalChat];
return NO;
}


-(void) registerForKeyboardNotifications
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWasShown:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
}


-(void) freeKeyboardNotifications
{
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
}
-(void) keyboardWasShown:(NSNotification*)aNotification
{
NSLog(@"Keyboard was shown");
NSDictionary* info = [aNotification userInfo];

NSTimeInterval animationDuration;
UIViewAnimationCurve animationCurve;
CGRect keyboardFrame;
[[info objectForKey:UIKeyboardAnimationCurveUserInfoKey] getValue:&animationCurve];
[[info objectForKey:UIKeyboardAnimationDurationUserInfoKey] getValue:&animationDuration];
[[info objectForKey:UIKeyboardFrameBeginUserInfoKey] getValue:&keyboardFrame];

[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:animationDuration];
[UIView setAnimationCurve:animationCurve];
[self.view setFrame:CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y- keyboardFrame.size.height+49, self.view.frame.size.width, self.view.frame.size.height)];

[UIView commitAnimations];

}

-(void) keyboardWillHide:(NSNotification*)aNotification
{
NSLog(@"Keyboard will hide");
NSDictionary* info = [aNotification userInfo];

NSTimeInterval animationDuration;
UIViewAnimationCurve animationCurve;
CGRect keyboardFrame;
[[info objectForKey:UIKeyboardAnimationCurveUserInfoKey] getValue:&animationCurve];
[[info objectForKey:UIKeyboardAnimationDurationUserInfoKey] getValue:&animationDuration];
[[info objectForKey:UIKeyboardFrameBeginUserInfoKey] getValue:&keyboardFrame];

[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:animationDuration];
[UIView setAnimationCurve:animationCurve];
[self.view setFrame:CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y + keyboardFrame.size.height-49, self.view.frame.size.width, self.view.frame.size.height)];

[UIView commitAnimations];
}
#pragma mark -
#pragma mark Data Source Loading / Reloading Methods

- (void)reloadTableViewDataSource{

//  should be calling your tableviews data source model to reload
//  put here just for demo
_reloading = YES;
[self loadLocalChat];
[chatTable reloadData];
}

- (void)doneLoadingTableViewData{

//  model should call this when its done loading
_reloading = NO;
[_refreshHeaderView egoRefreshScrollViewDataSourceDidFinishedLoading:chatTable];

}


#pragma mark -
#pragma mark UIScrollViewDelegate Methods

- (void)scrollViewDidScroll:(UIScrollView *)scrollView{

[_refreshHeaderView egoRefreshScrollViewDidScroll:scrollView];

}

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{

[_refreshHeaderView egoRefreshScrollViewDidEndDragging:scrollView];

}
#pragma mark - Parse

- (void)loadLocalChat
{
PFQuery *query = [PFQuery queryWithClassName:className];


// If no objects are loaded in memory, we look to the cache first to fill the table
// and then subsequently do a query against the network.
if ([chatData count] == 0) {
    query.cachePolicy = kPFCachePolicyCacheThenNetwork;
    [query orderByAscending:@"createdAt"];
    NSLog(@"Trying to retrieve from cache");
    [query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
        if (!error) {
            // The find succeeded.
            NSLog(@"Successfully retrieved %lu chats from cache.", (unsigned long)objects.count);
            [chatData removeAllObjects];
            [chatData addObjectsFromArray:objects];
            [chatTable reloadData];
        } else {
            // Log details of the failure
            NSLog(@"Error: %@ %@", error, [error userInfo]);
        }
    }];
}
__block int totalNumberOfEntries = 0;
[query orderByAscending:@"createdAt"];
[query countObjectsInBackgroundWithBlock:^(int number, NSError *error) {
    if (!error) {
        // The count request succeeded. Log the count
        NSLog(@"There are currently %d entries", number);
        totalNumberOfEntries = number;
        if (totalNumberOfEntries > [chatData count]) {
            NSLog(@"Retrieving data");
            int theLimit;
            if (totalNumberOfEntries-[chatData count]>MAX_ENTRIES_LOADED) {
                theLimit = MAX_ENTRIES_LOADED;
            }
            else {
                theLimit = totalNumberOfEntries-[chatData count];
            }
            query.limit = [NSNumber numberWithInt:theLimit];
            [query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
                if (!error) {
                    // The find succeeded.
                    NSLog(@"Successfully retrieved %lu chats.", (unsigned long)objects.count);
                    [chatData addObjectsFromArray:objects];
                    NSMutableArray *insertIndexPaths = [[NSMutableArray alloc] init];
                    for (int ind = 0; ind < objects.count; ind++) {
                        NSIndexPath *newPath = [NSIndexPath indexPathForRow:ind inSection:0];
                        [insertIndexPaths addObject:newPath];
                    }
                    [chatTable beginUpdates];
                    [chatTable insertRowsAtIndexPaths:insertIndexPaths withRowAnimation:UITableViewRowAnimationTop];
                    [chatTable endUpdates];
                    [chatTable reloadData];
                    [chatTable scrollsToTop];
                } else {
                    // Log details of the failure
                    NSLog(@"Error: %@ %@", error, [error userInfo]);
                }
            }];
        }

    } else {
        // The request failed, we'll keep the chatData count?
        number = [chatData count];
    }
}];
}


#pragma mark -
#pragma mark EGORefreshTableHeaderDelegate Methods

- (void)egoRefreshTableHeaderDidTriggerRefresh:(PF_EGORefreshTableHeaderView*)view{

[self reloadTableViewDataSource];
[self performSelector:@selector(doneLoadingTableViewData) withObject:nil afterDelay:3.0];

}

- (BOOL)egoRefreshTableHeaderDataSourceIsLoading:(PF_EGORefreshTableHeaderView*)view{

return _reloading; // should return if data source model is reloading

}

- (NSDate*)egoRefreshTableHeaderDataSourceLastUpdated:(PF_EGORefreshTableHeaderView*)view{

return [NSDate date]; // should return date data source was last changed

 }
#pragma mark - Table view delegate
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
return [chatData count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
chatCell *cell = (chatCell *)[tableView dequeueReusableCellWithIdentifier: @"chatCellIdentifier"];
NSUInteger row = [chatData count]-[indexPath row]-1;


if (row < chatData.count){
    NSString *chatText = [[chatData objectAtIndex:row] objectForKey:@"text"];
    cell.textLabel.lineBreakMode = UILineBreakModeWordWrap;
    UIFont *font = [UIFont systemFontOfSize:14];
    CGSize size = [chatText sizeWithFont:font constrainedToSize:CGSizeMake(225.0f, 1000.0f) lineBreakMode:UILineBreakModeCharacterWrap];
    cell.textString.frame = CGRectMake(75, 14, size.width +20, size.height + 20);
    cell.textString.font = [UIFont fontWithName:@"Helvetica" size:14.0];
    cell.textString.text = chatText;
    [cell.textString sizeToFit];

    NSDate *theDate = [[chatData objectAtIndex:row] objectForKey:@"date"];
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"HH:mm a"];
    NSString *timeString = [formatter stringFromDate:theDate];
    cell.timeLabel.text = timeString;

    cell.userLabel.text = [[chatData objectAtIndex:row] objectForKey:@"userName"];
}
return cell;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *cellText = [[chatData objectAtIndex:chatData.count-indexPath.row-1] objectForKey:@"text"];
UIFont *cellFont = [UIFont fontWithName:@"Helvetica" size:14.0];
CGSize constraintSize = CGSizeMake(225.0f, MAXFLOAT);
CGSize labelSize = [cellText sizeWithFont:cellFont constrainedToSize:constraintSize lineBreakMode:UILineBreakModeWordWrap];

return labelSize.height + 40;
}

-(void)presentChatNameDialog
{
UIAlertView *message = [[UIAlertView alloc] initWithTitle:@"Chat Name"
                                                  message:@"Choose a chat name, it can be changed later in the Options panel"
                                                 delegate:self
                                        cancelButtonTitle:@"Cancel"
                                        otherButtonTitles:@"Continue", nil];

[message setAlertViewStyle:UIAlertViewStylePlainTextInput];
//    [message setBackgroundColor:[UIColor colorWithRed:0.7765f green:0.1725f blue:0.1451f  alpha:1.0f]];
//    [message setAlpha:0.8f];
[message show];
}

@end

0 个答案:

没有答案