基本上我为解决这类问题所做的就是:
我没有使用符合JSQMessageData的CoreData对象,而是使用了一个名为viewModel的东西。
ViewModel基本上是一个普通的NSObject,它只是从CoreData对象中解开所有必要信息并符合JSQMessageData协议 - 提供text,senderId和其他信息(如果需要还提供媒体消息)
@interface ChatMessageViewModel : NSObject <JSQMessageData> @property (nonatomic, strong, readonly) CDChatMessage *chatMessage; // main properties @property (nonatomic, copy, readonly) NSString *text; @property (nonatomic, copy, readonly) NSString *senderId; @property (nonatomic, copy, readonly) NSString *watcherId; ... @property (nonatomic, strong, readonly) JSQMessage *mediaMessage; - (instancetype)initWithChatMessage:(CDChatMessage *)chatMessage; @end
.m文件可能如下所示:
@interface ChatMessageViewModel () @property (nonatomic, strong, readwrite) CDChatMessage *chatMessage; // main properties @property (nonatomic, copy, readwrite) NSString *text; @property (nonatomic, copy, readwrite) NSString *senderId; @property (nonatomic, copy, readwrite) NSString *watcherId; ... @property (nonatomic, strong, readwrite) JSQMessage *mediaMessage; @end @implementation ChatMessageViewModel - (instancetype)initWithChatMessage:(CDChatMessage *)chatMessage if (self = [super init]) { _chatMessage = chatMessage; [self unpackViewModel]; } return self; } - (void)unpackViewModel { self.senderId = self.chatMessage.senderId; self.text = self.chatMessage.senderId; self.mediaMessage = [self unpackMediaData]; } - (JSQMessage *)unpackMediaData { // Here CDCustomPhotoMediaItem is a subclass of JSQPhotoMediaItem which just lets me create custom look of JSQ media item. JSQPhotoMediaItem *photoItem = [[CDCustomPhotoMediaItem alloc] init]; return [JSQMessage messageWithSenderId:self.senderId displayName:@"" media:photoItem]; }
在使用NSFetchResultsController获取数据后,我只需获取所有核心数据对象并将它们转换为不可变的viewModel。
然后在cellForItemAtIndexPath中我只是调用它:
cell.mediaView = [viewModel.media mediaView];
这种方法创建了一个很好的不可变包装器,它只包含JSQ聊天库所需的必要信息块。此外,您可以轻松地为此类对象编写测试。如果你使用的是swift,你可以使用struct来实现这种目的。
希望我的回答有所帮助请询问您是否需要更详细的答案。 ;-)