0

JSQ プロジェクトにコア データを正常に統合しました。JSQMessageData には、CDChatMessage という名前で作成した NSManagedObject を使用します

@interface CDChatMessage : NSManagedObject < JSQMessageData >
@end

私の JSQMessagesViewController では、NSfetchedresultsController を使用してい
ます。テキスト メッセージでは問題なく動作しますが、メディア メッセージを実装する方法がわかりません。

JSQMessage.h には、メディア データを表すプロパティがあります。

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

しかし、明らかに、タイプ JSQMessageMediaData のプロパティを NSManagedObject にアサシンすることはできません。コアデータで JSQMessageMediaData を使用するためのソリューションはありますか?

ありがとう。

4

1 に答える 1

2

基本的に、この種の問題を解決するために私が行ったことは次のとおりです。

JSQMessageData に準拠する CoreData オブジェクトを使用する代わりに、viewModel と呼ばれるものを使用します。

ViewModel は基本的に、CoreData オブジェクトから必要なすべての情報をアンラップし、JSQMessageData プロトコルに準拠する通常の NSObject です - テキスト、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 を使用できます。

私の答えが役立つことを願っています。詳細な回答が必要な場合はお尋ねください。;-)

于 2015-09-27T21:56:44.030 に答える