将JSQMessageMediaData与核心数据一起使用

时间:2015-09-27 17:38:50

标签: ios objective-c xcode chat jsqmessagesviewcontroller

我成功地将核心数据集成到我的JSQ项目中,对于我的JSQMessageData我使用我创建的名为CDChatMessage的NSManagedObject

@interface CDChatMessage : NSManagedObject < JSQMessageData >
@end

在我的JSQMessagesViewController中我使用NSfetchedresultsController,
它适用于短信,但我无法弄清楚如何实现媒体信息。

JSQMessage.h有一个代表媒体数据的属性

@property (copy, nonatomic, readonly) id< JSQMessageMediaData > media;

但显然我无法将JSQMessageMediaData类型的属性刺入我的NSManagedObject, 任何人都有将JSQMessageMediaData与Core Data一起使用的解决方案吗?

感谢。

1 个答案:

答案 0 :(得分:2)

基本上我为解决这类问题所做的就是:

我没有使用符合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来达到这种目的。

希望我的回答有所帮助。请询问您是否需要更详细的答案。 ;-)