Ios PubNub本地消息复制?
对于我的pubnub聊天应用程序,我正在本地存储一些消息,以防止它使用大量wifi/数据。它似乎工作正常,但有时最后一条消息会被复制。这是我的保存、加载、重新加载代码Ios PubNub本地消息复制?,ios,objective-c,duplicates,real-time,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 *message
#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:
one从任何内容获取消息并解析要显示的文本。saveObjects
将时间令牌和消息保存到磁盘,然后加载它们。timetoken方法只是将PN timetoken转换为精度较低的格式,并获取当前时间令牌。updatelstmessages
获取从最后一条消息timetoken到当前消息的所有消息,而不是获取所有消息
在
viewdiload
中,我调用[self-loadObjects]
,然后[self-updatelstmessages]
问题是消息重复!谢谢你的帮助。还有,很抱歉代码太长。哈哈,我真傻。我只是在重载方法中忘记了一个+1
。好的,对于任何想使用此代码在本地存储消息而不是获取所有消息的人来说,这就是了。此代码存储最后一条消息(+1)的时间令牌,并获取从x时间令牌到现在的所有消息