如何将照片从用户的 blob id 提供给对话框?
How to give photo to dialog from user's blob id?
我正在使用 Quickblox,我上传了用户个人资料图片,如堆栈流中所述 () 它对我来说工作正常。
然后我就可以在 user2 的联系人中看到 user1 的个人资料照片。(通过下载 user1 的 blob 文件并将其转换为图像)
但现在我的问题是,如果我们想创建一个新的聊天对话框,用户 1 和用户 2 已登录。我应该 link 这个用户 1 的个人资料图片(如上文所述上传) stack over flow example) 以及我将创建的新对话框,用于与 user1 聊天。
问题:1 - 那么我如何 link 这个用户的个人资料图片与新创建的聊天对话框,尤其是在一对一聊天的情况下。(私人聊天)。
问题:2 - 聊天对话框中的图像应该能够在用户 1 更改其个人资料图片时更新(使用更新 blob api 调用)。正如我们在 WhatsApp 中看到的那样。
在,
问题:1
如果我理解你的问题,当你为两个用户创建一个对话框时,你想在你的对话框列表中显示对话框图像,对话框图像应该是其他用户的图像正确我的意思是用户 1 应该看到对话框图像User2 和 User2 看到的对话框图像应该和 User1 一样正确 ???
如果是,兄弟抱歉!但是您所遵循的方法是错误的:) Dialog 的 属性 对于两个用户都是相同的。因此,如果您将对话框的图像设置为 User1,则 user2 将看到 User1 的照片,但 User1 也会看到他自己的图像,这是错误的:)
我要解决的问题是,不要为对话框本身使用任何图像或名称,除非它是一个群组对话框 :)
每次您收到 QBChat
时,您都会在其中找到居住者 ID。在 QBChatPrivate
消息的情况下,占用者 ID 的计数将为 2,其中之一将是您自己的 ID。所以删除它会给你其他用户的ID。
每次我收到一条消息时,我都会找出除我自己以外的参与者,并且在将消息插入到 coredata 并在应用程序中显示之前,我会检查我的 coredata 以查找用户是否存在于我的本地数据库中.如果用户存在,我将获取有关该用户的所有信息,例如他的个人资料照片、姓名以及所有在列表中显示他的个人资料照片和姓名的信息。
否则我将使用他的 ID 下载有关用户的所有信息,然后将其插入数据库,最后将消息插入数据库。现在,当我显示它时,我将遵循相同的步骤,在对话框列表中显示用户的姓名、他的个人资料图片和最后一条消息。
这给人一种对话框正在显示其他用户名和他的个人资料照片的感觉。但实际上 dialog 从来没有任何私人对话的图像或名称 :)
结论
如果是私人对话,请不要将任何图像或名称保存到 ABChatDialog 本身:)
问题:2
WhatsApp 中的图片更新不仅涉及客户端逻辑,还包括来自服务器的支持。不幸的是,您没有来自服务器的此类支持,服务器会向所有客户端发送通知,告知个人资料图片更改。希望 Quickblox 尽快实现它。
解决方案
我们用一种简单的方法处理它,每次用户进入对话框列表屏幕时,我们都会获取当前可见的所有对话框中涉及的所有用户,并为每个用户创建一个单独的 NSOperations 并获取所有信息,包括他的名字,图像一切,让用户随时更新:)
在我们的应用程序中,我们提供了用户也可以更改他的名字的规定,因此对我们来说,重要的是要完全更新用户,而不仅仅是他的个人资料照片:)
后台线程中的所有操作运行保持主线程空闲并在后台更新核心数据。
使用带有 coredata 的 NSFetchedResultsController 允许我们在用户名和他的个人资料图片更新后立即更新。
当您打开特定的用户消息时,也会发生相同的过程。一旦您打开他的消息,我们就会获取并更新该特定用户的信息。
这涉及冗余的服务器调用,我们非常清楚这一点,但这种方法使用户信息始终保持更新。
编辑
根据您的要求,为您提供一些代码 :) 这里是一个非常抽象的代码,但并不完全有效,但我相信它应该会给您一个良好的开端 :)
问题 1:此代码让您了解如何在添加聊天本身之前先添加用户 :)
- (void)processMessage:(QBChatMessage *)message{
// processMessage method is called in background thread so creating a background managed object context for the queue. You can make use of performBlock as well
//once you recieve message check if dialog exists in your db or not
NSManagedObjectContext *privateManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[privateManagedObjectContext setParentContext:appdelegate.managedObjectContext];
NSFetchRequest *request=[[NSFetchRequest alloc] initWithEntityName:@"Dialog"];
NSPredicate *predicate=[NSPredicate predicateWithFormat:@"id == %@",message.dialogID];
[request setPredicate:predicate];
NSArray *results=[privateManagedObjectContext executeFetchRequest:request error:nil];
if([results count]>0){
//once dialog found for the chat
Dialog *updatedDialog=(Dialog *)[results objectAtIndex:0];
// involves is a one to many relation ship between user and dialog
NSPredicate *userExistsPredicate=[NSPredicate predicateWithFormat:@"recipient_Id = %@",[NSNumber numberWithInteger:message.senderID]];
NSArray *foundUserArray=[[updatedDialog.involves allObjects] filteredArrayUsingPredicate:userExistsPredicate];
if([foundUserArray count] > 0){
//user exists in db
//check if its a duplicate chat sometime same chat comes back specially in group chat
NSFetchRequest *request=[[NSFetchRequest alloc] initWithEntityName:@"Chats"];
NSPredicate *predicate=[NSPredicate predicateWithFormat:@"chat_Id == %@",message.ID];
[request setPredicate:predicate];
NSArray *results=[privateManagedObjectContext executeFetchRequest:request error:nil];
if([results count] ==0){
//message not in db
Chats *recievedChat=[NSEntityDescription insertNewObjectForEntityForName:@"Chats" inManagedObjectContext:privateManagedObjectContext];
recievedChat.sender_Id=[NSNumber numberWithInteger:message.senderID];
recievedChat.date_sent=message.dateSent;
recievedChat.chat_Id=message.ID;
recievedChat.belongs=updatedDialog;
recievedChat.message_Body=message.text;
//populate the way you want it
//commit background context use perform block for better performance
NSError *updateDialogError = nil;
[privateManagedObjectContext save:&updateDialogError];
dispatch_async(dispatch_get_main_queue(), ^{
//commit main context
[appdelegate.managedObjectContext save:nil];
});
}
}
else{
//fetch user not in db
[QBRequest usersWithIDs:@[[NSNumber numberWithInteger:message.senderID]] page:nil
successBlock:^(QBResponse *response, QBGeneralResponsePage *page, NSArray *users) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSManagedObjectContext *privateManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[privateManagedObjectContext setParentContext:appdelegate.managedObjectContext];
NSFetchRequest *request=[[NSFetchRequest alloc] initWithEntityName:@"Dialog"];
NSPredicate *predicate=[NSPredicate predicateWithFormat:@"id == %@",message.dialogID];
[request setPredicate:predicate];
NSArray *results=[privateManagedObjectContext executeFetchRequest:request error:nil];
Dialog *updatedDialog=[results objectAtIndex:0];
NSMutableArray *occupants=[[NSMutableArray alloc] init];
//create user
for(QBUUser *user in users){
if(user.ID != appdelegate.currentUser.ID){
Recipient *recipient=[NSEntityDescription insertNewObjectForEntityForName:@"Recipient" inManagedObjectContext:privateManagedObjectContext];
recipient.recipient_Name=user.fullName;
recipient.recipient_Id=[NSNumber numberWithInteger:user.ID];
[occupants addObject:recipient];
}
}
NSMutableArray *newUsersArray=[NSMutableArray arrayWithArray:[updatedDialog.involves allObjects]];
[newUsersArray addObjectsFromArray:occupants];
updatedDialog.involves=[NSSet setWithArray:newUsersArray];
NSFetchRequest *chatRequest=[[NSFetchRequest alloc] initWithEntityName:@"Chats"];
NSPredicate *chatPredicate=[NSPredicate predicateWithFormat:@"chat_Id == %@",message.ID];
[chatRequest setPredicate:chatPredicate];
NSArray *chatResults=[privateManagedObjectContext executeFetchRequest:chatRequest error:nil];
//add chat
if([chatResults count] ==0){
//add chats or messages
Chats *recievedChat=[NSEntityDescription insertNewObjectForEntityForName:@"Chats" inManagedObjectContext:privateManagedObjectContext];
recievedChat.sender_Id=[NSNumber numberWithInteger:message.senderID];
recievedChat.date_sent=message.dateSent;
recievedChat.chat_Id=message.ID;
recievedChat.belongs=updatedDialog;
recievedChat.message_Body=message.text;
}
//save context
NSError *updateDialogError = nil;
[privateManagedObjectContext save:&updateDialogError];
dispatch_async(dispatch_get_main_queue(), ^{
//commit main context
[appdelegate.managedObjectContext save:nil];
});
});
}];
}
}
}
问题二
你不需要为此编写代码 :) 一旦你完成了我说过的教程,你就会明白 NSOperation 是如何工作的 :) 然后只需在 NSOperation 中编写 quickblox api 来为你下载图像 :)
我希望我表达清楚了。快乐编码
我正在使用 Quickblox,我上传了用户个人资料图片,如堆栈流中所述 (
然后我就可以在 user2 的联系人中看到 user1 的个人资料照片。(通过下载 user1 的 blob 文件并将其转换为图像)
但现在我的问题是,如果我们想创建一个新的聊天对话框,用户 1 和用户 2 已登录。我应该 link 这个用户 1 的个人资料图片(如上文所述上传) stack over flow example) 以及我将创建的新对话框,用于与 user1 聊天。
问题:1 - 那么我如何 link 这个用户的个人资料图片与新创建的聊天对话框,尤其是在一对一聊天的情况下。(私人聊天)。
问题:2 - 聊天对话框中的图像应该能够在用户 1 更改其个人资料图片时更新(使用更新 blob api 调用)。正如我们在 WhatsApp 中看到的那样。
在,
问题:1
如果我理解你的问题,当你为两个用户创建一个对话框时,你想在你的对话框列表中显示对话框图像,对话框图像应该是其他用户的图像正确我的意思是用户 1 应该看到对话框图像User2 和 User2 看到的对话框图像应该和 User1 一样正确 ???
如果是,兄弟抱歉!但是您所遵循的方法是错误的:) Dialog 的 属性 对于两个用户都是相同的。因此,如果您将对话框的图像设置为 User1,则 user2 将看到 User1 的照片,但 User1 也会看到他自己的图像,这是错误的:)
我要解决的问题是,不要为对话框本身使用任何图像或名称,除非它是一个群组对话框 :)
每次您收到 QBChat
时,您都会在其中找到居住者 ID。在 QBChatPrivate
消息的情况下,占用者 ID 的计数将为 2,其中之一将是您自己的 ID。所以删除它会给你其他用户的ID。
每次我收到一条消息时,我都会找出除我自己以外的参与者,并且在将消息插入到 coredata 并在应用程序中显示之前,我会检查我的 coredata 以查找用户是否存在于我的本地数据库中.如果用户存在,我将获取有关该用户的所有信息,例如他的个人资料照片、姓名以及所有在列表中显示他的个人资料照片和姓名的信息。 否则我将使用他的 ID 下载有关用户的所有信息,然后将其插入数据库,最后将消息插入数据库。现在,当我显示它时,我将遵循相同的步骤,在对话框列表中显示用户的姓名、他的个人资料图片和最后一条消息。
这给人一种对话框正在显示其他用户名和他的个人资料照片的感觉。但实际上 dialog 从来没有任何私人对话的图像或名称 :)
结论
如果是私人对话,请不要将任何图像或名称保存到 ABChatDialog 本身:)
问题:2
WhatsApp 中的图片更新不仅涉及客户端逻辑,还包括来自服务器的支持。不幸的是,您没有来自服务器的此类支持,服务器会向所有客户端发送通知,告知个人资料图片更改。希望 Quickblox 尽快实现它。
解决方案
我们用一种简单的方法处理它,每次用户进入对话框列表屏幕时,我们都会获取当前可见的所有对话框中涉及的所有用户,并为每个用户创建一个单独的 NSOperations 并获取所有信息,包括他的名字,图像一切,让用户随时更新:)
在我们的应用程序中,我们提供了用户也可以更改他的名字的规定,因此对我们来说,重要的是要完全更新用户,而不仅仅是他的个人资料照片:)
后台线程中的所有操作运行保持主线程空闲并在后台更新核心数据。
使用带有 coredata 的 NSFetchedResultsController 允许我们在用户名和他的个人资料图片更新后立即更新。
当您打开特定的用户消息时,也会发生相同的过程。一旦您打开他的消息,我们就会获取并更新该特定用户的信息。
这涉及冗余的服务器调用,我们非常清楚这一点,但这种方法使用户信息始终保持更新。
编辑 根据您的要求,为您提供一些代码 :) 这里是一个非常抽象的代码,但并不完全有效,但我相信它应该会给您一个良好的开端 :)
问题 1:此代码让您了解如何在添加聊天本身之前先添加用户 :)
- (void)processMessage:(QBChatMessage *)message{
// processMessage method is called in background thread so creating a background managed object context for the queue. You can make use of performBlock as well
//once you recieve message check if dialog exists in your db or not
NSManagedObjectContext *privateManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[privateManagedObjectContext setParentContext:appdelegate.managedObjectContext];
NSFetchRequest *request=[[NSFetchRequest alloc] initWithEntityName:@"Dialog"];
NSPredicate *predicate=[NSPredicate predicateWithFormat:@"id == %@",message.dialogID];
[request setPredicate:predicate];
NSArray *results=[privateManagedObjectContext executeFetchRequest:request error:nil];
if([results count]>0){
//once dialog found for the chat
Dialog *updatedDialog=(Dialog *)[results objectAtIndex:0];
// involves is a one to many relation ship between user and dialog
NSPredicate *userExistsPredicate=[NSPredicate predicateWithFormat:@"recipient_Id = %@",[NSNumber numberWithInteger:message.senderID]];
NSArray *foundUserArray=[[updatedDialog.involves allObjects] filteredArrayUsingPredicate:userExistsPredicate];
if([foundUserArray count] > 0){
//user exists in db
//check if its a duplicate chat sometime same chat comes back specially in group chat
NSFetchRequest *request=[[NSFetchRequest alloc] initWithEntityName:@"Chats"];
NSPredicate *predicate=[NSPredicate predicateWithFormat:@"chat_Id == %@",message.ID];
[request setPredicate:predicate];
NSArray *results=[privateManagedObjectContext executeFetchRequest:request error:nil];
if([results count] ==0){
//message not in db
Chats *recievedChat=[NSEntityDescription insertNewObjectForEntityForName:@"Chats" inManagedObjectContext:privateManagedObjectContext];
recievedChat.sender_Id=[NSNumber numberWithInteger:message.senderID];
recievedChat.date_sent=message.dateSent;
recievedChat.chat_Id=message.ID;
recievedChat.belongs=updatedDialog;
recievedChat.message_Body=message.text;
//populate the way you want it
//commit background context use perform block for better performance
NSError *updateDialogError = nil;
[privateManagedObjectContext save:&updateDialogError];
dispatch_async(dispatch_get_main_queue(), ^{
//commit main context
[appdelegate.managedObjectContext save:nil];
});
}
}
else{
//fetch user not in db
[QBRequest usersWithIDs:@[[NSNumber numberWithInteger:message.senderID]] page:nil
successBlock:^(QBResponse *response, QBGeneralResponsePage *page, NSArray *users) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSManagedObjectContext *privateManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[privateManagedObjectContext setParentContext:appdelegate.managedObjectContext];
NSFetchRequest *request=[[NSFetchRequest alloc] initWithEntityName:@"Dialog"];
NSPredicate *predicate=[NSPredicate predicateWithFormat:@"id == %@",message.dialogID];
[request setPredicate:predicate];
NSArray *results=[privateManagedObjectContext executeFetchRequest:request error:nil];
Dialog *updatedDialog=[results objectAtIndex:0];
NSMutableArray *occupants=[[NSMutableArray alloc] init];
//create user
for(QBUUser *user in users){
if(user.ID != appdelegate.currentUser.ID){
Recipient *recipient=[NSEntityDescription insertNewObjectForEntityForName:@"Recipient" inManagedObjectContext:privateManagedObjectContext];
recipient.recipient_Name=user.fullName;
recipient.recipient_Id=[NSNumber numberWithInteger:user.ID];
[occupants addObject:recipient];
}
}
NSMutableArray *newUsersArray=[NSMutableArray arrayWithArray:[updatedDialog.involves allObjects]];
[newUsersArray addObjectsFromArray:occupants];
updatedDialog.involves=[NSSet setWithArray:newUsersArray];
NSFetchRequest *chatRequest=[[NSFetchRequest alloc] initWithEntityName:@"Chats"];
NSPredicate *chatPredicate=[NSPredicate predicateWithFormat:@"chat_Id == %@",message.ID];
[chatRequest setPredicate:chatPredicate];
NSArray *chatResults=[privateManagedObjectContext executeFetchRequest:chatRequest error:nil];
//add chat
if([chatResults count] ==0){
//add chats or messages
Chats *recievedChat=[NSEntityDescription insertNewObjectForEntityForName:@"Chats" inManagedObjectContext:privateManagedObjectContext];
recievedChat.sender_Id=[NSNumber numberWithInteger:message.senderID];
recievedChat.date_sent=message.dateSent;
recievedChat.chat_Id=message.ID;
recievedChat.belongs=updatedDialog;
recievedChat.message_Body=message.text;
}
//save context
NSError *updateDialogError = nil;
[privateManagedObjectContext save:&updateDialogError];
dispatch_async(dispatch_get_main_queue(), ^{
//commit main context
[appdelegate.managedObjectContext save:nil];
});
});
}];
}
}
}
问题二 你不需要为此编写代码 :) 一旦你完成了我说过的教程,你就会明白 NSOperation 是如何工作的 :) 然后只需在 NSOperation 中编写 quickblox api 来为你下载图像 :)
我希望我表达清楚了。快乐编码