ios - PubNub 本地消息重复?

标签 ios objective-c duplicates real-time pubnub

对于我的 pubnub 聊天应用程序,我在本地存储了一些消息,以防止它使用大量的 wifi/数据。它似乎工作正常,但有时最后一条消息会重复。这是我的保存、加载、重新加载代码。

#pragma mark - PubNub manager methods

- (NSString *)parseMessage:(id)message
{
    if ([message isKindOfClass:[NSDictionary class]]) {

        NSDictionary *messageAsDict = message;

        if ([[messageAsDict objectForKey:@"text"] isKindOfClass:[NSString class]]) {
            NSString *messageString = [messageAsDict objectForKey:@"text"];

            if (messageString || messageString.length > 0) {
                return messageString;
            } else {
                return @"Unable To Parse Message";
            }
        } else {
            return @"Unable To Parse Message";
        }
    } else if ([message isKindOfClass:[NSString class]]) {

        NSString *messageString = message;

        if (messageString.length > 0) {
            return messageString;
        } else {
            return @"Unable To Parse Message";
        }
    } else {
        return @"Unable To Parse Message";
    }
}

- (void)saveObjects
{
    NSError *error;

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *docDir = [paths objectAtIndex:0];

    NSString *messagesDirectoryPath = [docDir stringByAppendingPathComponent:@"Messaging"];

    if (![[NSFileManager defaultManager] fileExistsAtPath:messagesDirectoryPath]) {
        [[NSFileManager defaultManager] createDirectoryAtPath:messagesDirectoryPath withIntermediateDirectories:YES attributes:nil error:&error];
    }

    NSString *messagesPath = [messagesDirectoryPath stringByAppendingPathComponent:messageFile];
    NSString *timeTokenPath = [messagesDirectoryPath stringByAppendingPathComponent:timeTokenFile];

    NSString *timeTokenString = [NSString stringWithFormat:@"%ld", (long)lastTimeToken];

    [messagesArray writeToFile:messagesPath atomically:YES];
    [timeTokenString writeToFile:timeTokenPath atomically:YES encoding:NSUTF8StringEncoding error:&error];
}

- (void)loadObjects
{
    NSError *error;

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *docDir = [paths objectAtIndex:0];

    NSString *messagesDirectoryPath = [docDir stringByAppendingPathComponent:@"Messaging"];

    NSString *messagesPath = [messagesDirectoryPath stringByAppendingPathComponent:messageFile];
    NSString *timeTokenPath = [messagesDirectoryPath stringByAppendingPathComponent:timeTokenFile];

    messagesArray = [NSMutableArray arrayWithContentsOfFile:messagesPath];

    if (!messagesArray) {
        messagesArray = [[NSMutableArray alloc] init];
        [self saveObjects];
    }

    NSString *timeTokenString = [NSString stringWithContentsOfFile:timeTokenPath encoding:NSUTF8StringEncoding error:&error];

    if (![timeTokenString isEqualToString:@""]) {
        lastTimeToken = [timeTokenString integerValue];
    } else {
        lastTimeToken = [self currentTimeToken];
        [self saveObjects];
    }
}

- (void)reloadMessages
{
    messagesArray = [[NSMutableArray alloc] init];

    //Get all the chats you missed
    [self.pnClient historyForChannel:kCHAT_CHANNEL withCompletion:^(PNHistoryResult *result, PNErrorStatus *status) {

        // Check whether request successfully completed or not.
        if (!status.isError) {

            // Handle downloaded history using:
            //   result.data.start - oldest message time stamp in response
            //   result.data.end - newest message time stamp in response
            //   result.data.messages - list of messages

            // Get messages

            for (id message in result.data.messages) {
                [messagesArray addObject:[self parseMessage:message]];
            }

            // Set timetoken

            lastTimeToken = [self parsePNTimeToken:result.data.end];

            // Save stuff

            [self saveObjects];

            dispatch_async(dispatch_get_main_queue(), ^{

                [self.messagesTable reloadData];

                [self scrollToBottom];
            });
        } else {
            // Request processing failed.

            UIAlertController *errorController = [UIAlertController alertControllerWithTitle:@"Error" message:@"Could not recieve messages" preferredStyle:UIAlertControllerStyleAlert];
            UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil];

            UIAlertAction *retryAction = [UIAlertAction actionWithTitle:@"Retry" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
                [status retry];
            }];
            [errorController addAction:cancelAction];
            [errorController addAction:retryAction];
            [self presentViewController:errorController animated:YES completion:nil];

        }
    }];
}

- (void)addMessage:(PNMessageResult *)message
{
    [messagesArray addObject:[self parseMessage:message.data.message]];
    lastTimeToken = [message.data.timetoken integerValue] + 1;
    [self saveObjects];
}

- (NSInteger)parsePNTimeToken:(NSNumber *)timeToken
{
    return trunc([timeToken integerValue] / pow(10, 7));
}

- (NSInteger)currentTimeToken
{
    return [[NSDate date] timeIntervalSince1970];
}

- (void)updateLostMessages
{
    [self.pnClient historyForChannel:kCHAT_CHANNEL start:[NSNumber numberWithInteger:lastTimeToken] end:[NSNumber numberWithInteger:[self currentTimeToken]] limit:NSIntegerMax withCompletion:^(PNHistoryResult *result, PNErrorStatus *status) {

        NSArray *tempResultArray = result.data.messages;

        for (id message in tempResultArray) {
            [messagesArray addObject:[self parseMessage:message]];
            NSLog(@"%@", [self parseMessage:message]);
        }

        lastTimeToken = [self currentTimeToken] + 1;

        [self saveObjects];

        [self loadObjects];

        dispatch_async(dispatch_get_main_queue(), ^{

            [self.messagesTable reloadData];
            [self scrollToBottom];

        });
    }];
}

这些方法非常简单。 parseMessage: 从任何地方获取消息并解析要显示的文本。 saveObjects 将 timeToken 和消息保存到磁盘,并加载它们。时间标记方法只是将 PN 时间标记转换为精度较低的格式并获取当前时间标记。 updateLostMessages 获取从最后一条消息 timetoken 到当前的所有消息,而不是获取所有消息。

viewDidLoad 中,我调用了 [self loadObjects] 然后是 [self updateLostMessages] 问题是消息重复!帮助表示赞赏。另外,很抱歉代码太长。

最佳答案

哈哈,我傻了。我只是在重新加载方法中忘记了 + 1 。好吧,对于任何想要使用此代码在本地存储消息而不是获取所有消息的人来说,给你。此代码存储最后一条消息的时间 token (+1),并获取从 x 时间 token 到现在的所有消息。

关于ios - PubNub 本地消息重复?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34456369/

相关文章:

vba - 删除Excel工作表单元格中的冗余数据

ios - 从应用程序启动警报警报

ios - WKWebCache 缓存

ios - 无法从 ApplePay PKPaymentAuthorizationViewController 获取电子邮件

objective-c - UIBarButtonItem 没有响应点击

iphone - 如何从数据库中检索多列数据?

objective-c - NSViewController 和界面生成器

ios - NSString 去掉括号

ruby-on-rails-3 - Rails 克隆复制或复制

python - 将 JSON 元素附加到列表,然后在 Python 中有效地删除重复项