├── .gitignore ├── .travis.yml ├── Docs └── Explanation.md ├── Example ├── Podfile ├── Podfile.lock ├── Tests │ ├── Tests-Info.plist │ ├── Tests-Prefix.pch │ ├── Tests.m │ └── en.lproj │ │ └── InfoPlist.strings ├── WBChatIMKit.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ └── contents.xcworkspacedata │ └── xcshareddata │ │ └── xcschemes │ │ └── WBChatIMKit-Example.xcscheme ├── WBChatIMKit.xcworkspace │ └── contents.xcworkspacedata └── WBChatIMKit │ ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard │ ├── Images.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json │ ├── WBAppDelegate.h │ ├── WBAppDelegate.m │ ├── WBChatIMKit-Info.plist │ ├── WBChatIMKit-Prefix.pch │ ├── WBChatKitDelegateObj.h │ ├── WBChatKitDelegateObj.m │ ├── WBViewController.h │ ├── WBViewController.m │ ├── en.lproj │ └── InfoPlist.strings │ └── main.m ├── LICENSE ├── README.md ├── WBChatIMKit.podspec ├── WBChatIMKit ├── Assets │ └── .gitkeep └── Classes │ ├── .gitkeep │ ├── ChatUI │ ├── Chat │ │ ├── Cell │ │ │ ├── WBChatMessageBaseCell.h │ │ │ ├── WBChatMessageBaseCell.m │ │ │ ├── WBChatMessageHintCell.h │ │ │ ├── WBChatMessageHintCell.m │ │ │ ├── WBChatMessageImageCell.h │ │ │ ├── WBChatMessageImageCell.m │ │ │ ├── WBChatMessageTextCell.h │ │ │ ├── WBChatMessageTextCell.m │ │ │ ├── WBChatMessageTimeCell.h │ │ │ ├── WBChatMessageTimeCell.m │ │ │ ├── WBChatMessageVoiceCell.h │ │ │ └── WBChatMessageVoiceCell.m │ │ ├── CellModel │ │ │ ├── WBChatMessageBaseCellModel.h │ │ │ ├── WBChatMessageBaseCellModel.m │ │ │ ├── WBChatMessageImageCellModel.h │ │ │ ├── WBChatMessageImageCellModel.m │ │ │ ├── WBChatMessageRecallCellModel.h │ │ │ ├── WBChatMessageRecallCellModel.m │ │ │ ├── WBChatMessageTextCellModel.h │ │ │ ├── WBChatMessageTextCellModel.m │ │ │ ├── WBChatMessageTimeCellModel.h │ │ │ ├── WBChatMessageTimeCellModel.m │ │ │ ├── WBChatMessageVoiceCellModel.h │ │ │ └── WBChatMessageVoiceCellModel.m │ │ ├── Tool │ │ │ ├── UITableView+WBScrollToIndexPath.h │ │ │ ├── UITableView+WBScrollToIndexPath.m │ │ │ ├── WBChatCellConfig.h │ │ │ ├── WBChatCellConfig.m │ │ │ ├── WBShowBigImageTool.h │ │ │ ├── WBShowBigImageTool.m │ │ │ ├── WBVoicePlayer.h │ │ │ └── WBVoicePlayer.m │ │ ├── Views │ │ │ └── WBImageBrowser │ │ │ │ ├── WBImageBrowserCell.h │ │ │ │ ├── WBImageBrowserCell.m │ │ │ │ ├── WBImageBrowserView.h │ │ │ │ └── WBImageBrowserView.m │ │ ├── WBChatViewController+Extension.h │ │ ├── WBChatViewController+Extension.m │ │ ├── WBChatViewController.h │ │ └── WBChatViewController.m │ └── ChatList │ │ ├── Cell │ │ ├── WBChatListCell.h │ │ └── WBChatListCell.m │ │ ├── Model │ │ ├── WBChatListCellModel.h │ │ └── WBChatListCellModel.m │ │ ├── Views │ │ ├── WBBadgeButton.h │ │ └── WBBadgeButton.m │ │ ├── WBChatListController.h │ │ └── WBChatListController.m │ ├── Extra │ ├── Base │ │ ├── WBBaseController.h │ │ └── WBBaseController.m │ ├── Category │ │ ├── Date │ │ │ ├── NSDate+Extension.h │ │ │ └── NSDate+Extension.m │ │ ├── NSString │ │ │ ├── NSString+OPSize.h │ │ │ └── NSString+OPSize.m │ │ ├── UIImage │ │ │ ├── UIImage+WBImage.h │ │ │ └── UIImage+WBImage.m │ │ └── UIView │ │ │ ├── UIView+Frame │ │ │ ├── UIView+Frame.h │ │ │ └── UIView+Frame.m │ │ │ └── UIView+NextResponder │ │ │ ├── UIView+NextResponder.h │ │ │ └── UIView+NextResponder.m │ ├── Config │ │ ├── WBConfig.h │ │ └── WBConst.h │ ├── CustomView │ │ ├── HUD │ │ │ ├── UIView+WBToast.h │ │ │ ├── UIView+WBToast.m │ │ │ ├── WBHUD.h │ │ │ └── WBHUD.m │ │ ├── WBKeyBoard │ │ │ ├── EmojiBoard │ │ │ │ ├── Cell │ │ │ │ │ ├── WBEmojiKeyBoardCell.h │ │ │ │ │ └── WBEmojiKeyBoardCell.m │ │ │ │ ├── EmojiKeyoboardBar │ │ │ │ │ ├── WBEmojiGroupCell.h │ │ │ │ │ ├── WBEmojiGroupCell.m │ │ │ │ │ ├── WBEmojiGroupControl.h │ │ │ │ │ └── WBEmojiGroupControl.m │ │ │ │ ├── Model │ │ │ │ │ ├── WBEmotionPageModel.h │ │ │ │ │ └── WBEmotionPageModel.m │ │ │ │ ├── WBEmotionDisplayBoard.h │ │ │ │ └── WBEmotionDisplayBoard.m │ │ │ ├── MediaUtilities │ │ │ │ ├── WBTLAudioPlayer.h │ │ │ │ ├── WBTLAudioPlayer.m │ │ │ │ ├── WBTLAudioRecorder.h │ │ │ │ └── WBTLAudioRecorder.m │ │ │ ├── PlusBoard │ │ │ │ ├── Cell │ │ │ │ │ ├── WBPlusBoardCell.h │ │ │ │ │ └── WBPlusBoardCell.m │ │ │ │ ├── WBPlusDisplayBoard.h │ │ │ │ └── WBPlusDisplayBoard.m │ │ │ ├── TLRecorderIndicatorView │ │ │ │ ├── WBTLRecorderIndicatorView.h │ │ │ │ └── WBTLRecorderIndicatorView.m │ │ │ ├── TalkButton │ │ │ │ ├── WBTLTalkButton.h │ │ │ │ └── WBTLTalkButton.m │ │ │ ├── WBChatBarConst.h │ │ │ ├── WBChatBarView.h │ │ │ ├── WBChatBarView.m │ │ │ └── WBKeyBoardTextView │ │ │ │ ├── WBKeyBoardTextView.h │ │ │ │ └── WBKeyBoardTextView.m │ │ └── WBRefresh │ │ │ ├── UIScrollView+WBRefresh.h │ │ │ ├── UIScrollView+WBRefresh.m │ │ │ ├── WBRefreshHeaderView.h │ │ │ └── WBRefreshHeaderView.m │ └── Tools │ │ ├── ImageLoad │ │ ├── WBImageLoad.h │ │ └── WBImageLoad.m │ │ ├── SelectPhotoTool │ │ ├── WBSelectPhotoTool.h │ │ └── WBSelectPhotoTool.m │ │ ├── WBTools.h │ │ └── WBTools.m │ ├── Resource │ ├── Other.bundle │ │ ├── AddGroupMemberBtn@2x.png │ │ ├── AddGroupMemberBtnHL@2x.png │ │ ├── CellBlueSelected@2x.png │ │ ├── CellGraySelected@2x.png │ │ ├── ChatKit-Settings.plist │ │ ├── ChatKit-Theme.plist │ │ ├── Connectkeyboad_banner_mute@2x.png │ │ ├── Connectkeyboad_banner_mute@3x.png │ │ ├── Remind_Mute.png │ │ ├── SearchContactsBarIcon@2x.png │ │ ├── chatMuteOn@2x.png │ │ ├── conversationViewController_default_backgroundImage.png │ │ ├── en.lproj │ │ │ └── LCChatKitString.strings │ │ ├── safari-icon.png │ │ ├── safari-icon@2x.png │ │ └── zh-Hans.lproj │ │ │ └── LCChatKitString.strings │ └── WBUI.bundle │ │ ├── Album_test_close@2x.png │ │ ├── Album_test_donotlook@2x.png │ │ ├── Album_test_open@2x.png │ │ ├── Album_test_unlike@2x.png │ │ ├── Card_AddIcon@2x.png │ │ ├── CloudChatList_badge@2x.png │ │ ├── CloudChatList_badge_dot@2x.png │ │ ├── DeleteEmoticonBtn@2x.png │ │ ├── EmotionsEmojiHL@2x.png │ │ ├── EmotionsEmojiHL@3x.png │ │ ├── EmotionsSendBtnBlue@2x.png │ │ ├── EmotionsSendBtnBlueHL@2x.png │ │ ├── EmotionsSendBtnGrey@2x.png │ │ ├── ExclamationMark@2x.png │ │ ├── ExclamationMark@3x.png │ │ ├── Mode_listtotext@2x.png │ │ ├── Mode_listtotext@3x.png │ │ ├── Mode_listtotextHL@2x.png │ │ ├── Mode_listtotextHL@3x.png │ │ ├── Mode_texttolist@2x.png │ │ ├── Mode_texttolist@3x.png │ │ ├── Mode_texttolistHL@2x.png │ │ ├── Mode_texttolistHL@3x.png │ │ ├── Placeholder_Image@2x.png │ │ ├── ReceiverVoiceNodePlaying000@2x.png │ │ ├── ReceiverVoiceNodePlaying001@2x.png │ │ ├── ReceiverVoiceNodePlaying002@2x.png │ │ ├── ReceiverVoiceNodePlaying003@2x.png │ │ ├── ReceiverVoiceNodePlaying@2x.png │ │ ├── RecordCancel@2x.png │ │ ├── RecordCancel@3x.png │ │ ├── RecordingBkg@2x.png │ │ ├── RecordingBkg@3x.png │ │ ├── RecordingSignal001@2x.png │ │ ├── RecordingSignal001@3x.png │ │ ├── RecordingSignal002@2x.png │ │ ├── RecordingSignal002@3x.png │ │ ├── RecordingSignal003@2x.png │ │ ├── RecordingSignal003@3x.png │ │ ├── RecordingSignal004@2x.png │ │ ├── RecordingSignal004@3x.png │ │ ├── RecordingSignal005@2x.png │ │ ├── RecordingSignal005@3x.png │ │ ├── RecordingSignal006@2x.png │ │ ├── RecordingSignal006@3x.png │ │ ├── RecordingSignal007@2x.png │ │ ├── RecordingSignal007@3x.png │ │ ├── RecordingSignal008@2x.png │ │ ├── RecordingSignal008@3x.png │ │ ├── SenderVoiceNodePlaying000@2x.png │ │ ├── SenderVoiceNodePlaying001@2x.png │ │ ├── SenderVoiceNodePlaying002@2x.png │ │ ├── SenderVoiceNodePlaying003@2x.png │ │ ├── SenderVoiceNodePlaying@2x.png │ │ ├── SystemEmoji.json │ │ ├── ToolViewEmotion@2x.png │ │ ├── ToolViewEmotion@3x.png │ │ ├── ToolViewEmotionHL@2x.png │ │ ├── ToolViewEmotionHL@3x.png │ │ ├── ToolViewInputVoice@2x.png │ │ ├── ToolViewInputVoice@3x.png │ │ ├── ToolViewInputVoiceHL@2x.png │ │ ├── ToolViewInputVoiceHL@3x.png │ │ ├── ToolViewKeyboard@2x.png │ │ ├── ToolViewKeyboard@3x.png │ │ ├── ToolViewKeyboardHL@2x.png │ │ ├── ToolViewKeyboardHL@3x.png │ │ ├── TypeSelectorBtnHL_Black@2x.png │ │ ├── TypeSelectorBtnHL_Black@3x.png │ │ ├── TypeSelectorBtn_Black@2x.png │ │ ├── TypeSelectorBtn_Black@3x.png │ │ ├── WBEmojiInfo.plist │ │ ├── chat_bar_icons_camera@3x.png │ │ ├── chat_bar_icons_location@3x.png │ │ ├── chat_bar_icons_pic@3x.png │ │ ├── dialog_bubble_other@2x.png │ │ ├── header_male@2x.png │ │ ├── news-bg-card-me@2x.png │ │ ├── news-bg-me@2x.png │ │ ├── refresh_icon@2x.png │ │ └── refresh_icon@3x.png │ ├── ServiceSDK │ ├── Core │ │ ├── Base │ │ │ ├── Protocol │ │ │ │ ├── WBDBCreater.h │ │ │ │ └── WBTerminateHandler.h │ │ │ ├── WBCoreRegister.h │ │ │ ├── WBCoreRegister.m │ │ │ ├── WBDBClient.h │ │ │ ├── WBDBClient.m │ │ │ ├── WBUserManager.h │ │ │ └── WBUserManager.m │ │ ├── Category │ │ │ ├── AVCategory │ │ │ │ ├── AVIMConversation+WBExtension.h │ │ │ │ ├── AVIMConversation+WBExtension.m │ │ │ │ ├── AVIMMessage+WBExtension.h │ │ │ │ ├── AVIMMessage+WBExtension.m │ │ │ │ ├── AVIMTypedMessage+WBExtension.h │ │ │ │ └── AVIMTypedMessage+WBExtension.m │ │ │ └── Foundation │ │ │ │ ├── FMDatabase+WBAutoSql.h │ │ │ │ ├── FMDatabase+WBAutoSql.m │ │ │ │ ├── NSBundle+LCCKExtension.h │ │ │ │ ├── NSBundle+LCCKExtension.m │ │ │ │ ├── NSDate+WBExt.h │ │ │ │ ├── NSDate+WBExt.m │ │ │ │ ├── NSError+WBError.h │ │ │ │ ├── NSError+WBError.m │ │ │ │ ├── NSObject+WBExtension.h │ │ │ │ ├── NSObject+WBExtension.m │ │ │ │ ├── UIImage+WBScaleExtension.h │ │ │ │ └── UIImage+WBScaleExtension.m │ │ └── Tool │ │ │ ├── WBCoreConfiguration.h │ │ │ ├── WBManagerHeaders.h │ │ │ ├── WBSynthesizeSingleton.h │ │ │ ├── WBUserDefaults.h │ │ │ └── WBUserDefaults.m │ ├── Manager │ │ ├── Background │ │ │ ├── WBBackgroundManager.h │ │ │ └── WBBackgroundManager.m │ │ ├── Chat │ │ │ ├── Dao │ │ │ │ ├── WBChatInfoDao.h │ │ │ │ └── WBChatInfoDao.m │ │ │ ├── WBChatManager.h │ │ │ ├── WBChatManager.m │ │ │ └── WBMessageModel │ │ │ │ ├── WBChatInfoModel.h │ │ │ │ ├── WBChatInfoModel.m │ │ │ │ ├── WBMessageModel.h │ │ │ │ └── WBMessageModel.m │ │ ├── ChatList │ │ │ ├── Dao │ │ │ │ ├── WBChatListDao.h │ │ │ │ └── WBChatListDao.m │ │ │ ├── Model │ │ │ │ ├── WBChatListModel.h │ │ │ │ └── WBChatListModel.m │ │ │ ├── WBChatListManager.h │ │ │ └── WBChatListManager.m │ │ ├── File │ │ │ ├── WBFileManager.h │ │ │ ├── WBFileManager.m │ │ │ ├── WBNamedTool.h │ │ │ ├── WBNamedTool.m │ │ │ ├── WBPathManager.h │ │ │ └── WBPathManager.m │ │ └── Message │ │ │ ├── WBMessageManager.h │ │ │ └── WBMessageManager.m │ ├── MessageSubclass │ │ ├── WBGroupNotificationMessage.h │ │ └── WBGroupNotificationMessage.m │ ├── WBChatKit.h │ ├── WBChatKit.m │ ├── WBChatKitProtocol.h │ ├── WBDefine │ │ └── WBIMDefine.h │ ├── WBIMClientDelegateImp.h │ ├── WBIMClientDelegateImp.m │ └── WBServiceSDKHeaders.h │ ├── VoiceLib │ └── lame.framework │ │ ├── Headers │ │ └── lame.h │ │ └── lame │ └── WBChatIMKit.h └── _Pods.xcodeproj /.gitignore: -------------------------------------------------------------------------------- 1 | # OS X 2 | .DS_Store 3 | 4 | # Xcode 5 | build/ 6 | *.pbxuser 7 | !default.pbxuser 8 | *.mode1v3 9 | !default.mode1v3 10 | *.mode2v3 11 | !default.mode2v3 12 | *.perspectivev3 13 | !default.perspectivev3 14 | xcuserdata/ 15 | *.xccheckout 16 | profile 17 | *.moved-aside 18 | DerivedData 19 | *.hmap 20 | *.ipa 21 | 22 | # Bundler 23 | .bundle 24 | 25 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 26 | # Carthage/Checkouts 27 | 28 | Carthage/Build 29 | 30 | # We recommend against adding the Pods directory to your .gitignore. However 31 | # you should judge for yourself, the pros and cons are mentioned at: 32 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control 33 | # 34 | # Note: if you ignore the Pods directory, make sure to uncomment 35 | # `pod install` in .travis.yml 36 | # 37 | Pods/ 38 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # references: 2 | # * http://www.objc.io/issue-6/travis-ci.html 3 | # * https://github.com/supermarin/xcpretty#usage 4 | 5 | osx_image: xcode7.3 6 | language: objective-c 7 | # cache: cocoapods 8 | # podfile: Example/Podfile 9 | # before_install: 10 | # - gem install cocoapods # Since Travis is not always on latest version 11 | # - pod install --project-directory=Example 12 | script: 13 | - set -o pipefail && xcodebuild test -enableCodeCoverage YES -workspace Example/WBChatIMKit.xcworkspace -scheme WBChatIMKit-Example -sdk iphonesimulator9.3 ONLY_ACTIVE_ARCH=NO | xcpretty 14 | - pod lib lint 15 | -------------------------------------------------------------------------------- /Docs/Explanation.md: -------------------------------------------------------------------------------- 1 | # 更多细节 2 | 3 | ## 1.根据`ClientId`获取`memberName` 4 | 5 | 项目中区分用户是使用`ClientId`, 使用`ClientId`可以提供UI对应的名称. 6 | 7 | ChatKit需要使用者提供一些信息,即可以实现代理`WBChatKitProtocol`,提供给`[WBChatKit sharedInstance].delegate` 8 | 9 | 项目中使用如下: 10 | 11 | - WBChatListCellModel.m 12 | 13 | ``` 14 | - (void)handleTitle:(WBChatListModel *)dataModel{ 15 | WBConversationType type = dataModel.conversation.wb_conversationType; 16 | if (type == WBConversationTypeSingle) { 17 | NSArray *member = dataModel.conversation.members; 18 | // 如果实现了代理, 那么使用代理返回的数据 19 | if ([[WBChatKit sharedInstance].delegate respondsToSelector:@selector(memberNameWithClientID:)]) { 20 | NSString *otherObjectId = member.firstObject; 21 | if ([otherObjectId isEqualToString:[WBUserManager sharedInstance].clientId]) { 22 | otherObjectId = member.lastObject; 23 | } 24 | 25 | NSString *memberName = [[WBChatKit sharedInstance].delegate memberNameWithClientID:otherObjectId]; 26 | self.title = memberName; 27 | }else{ 28 | self.title = dataModel.conversation.name; 29 | } 30 | 31 | }else{ 32 | self.title = dataModel.conversation.name; 33 | } 34 | } 35 | 36 | ``` 37 | 38 | 39 | ## 2.会话页面消息的配置 `WBChatCellConfig` 40 | 41 | - WBChatCellConfig 单例的属性 42 | - WBImageLoad *imageLoad; 图片加载逻辑 43 | - UIImage *placeholdHeaderImage; 头像占位图 44 | - UIImage *placeholdImage; 图片占位图 45 | 46 | 47 | ### 2.1 `WBImageLoad *imageLoad` 图片加载逻辑 48 | 49 | 在`WBChatViewController`中, 图片消息可以加载Http资源, 是使用`WBChatCellConfig`中``WBImageLoad *imageLoad`` 50 | 51 | `- (void)imageView:(UIImageView *)imageView 52 | urlString:(NSString *)urlString 53 | placeholderImage:(UIImage *)placeholderImage;` 54 | 55 | 当用户自己实现时, 可以继承`WBImageLoad` 重写此方法, 然后重新设置`WBChatCellConfig `单例的`imageLoad`属性. 然后使用自定义的加载逻辑.例如使用` SDWebImage` 56 | 57 | - `#import "UIImageView+WebCache.h"` 58 | 59 | ``` 60 | - (void)imageView:(UIImageView *)imageView urlString:(NSString *)urlString placeholderImage:(UIImage *)placeholderImage{ 61 | [imageView sd_setImageWithURL:[NSURL URLWithString:urlString] placeholderImage:placeholderImage]; 62 | } 63 | 64 | ``` 65 | 66 | ### 2.2 头像占位图的使用 67 | 68 | ``` 69 | self.chatHeaderView.image = [WBChatCellConfig sharedInstance].placeholdHeaderImage; 70 | 71 | ``` 72 | 73 | ### 2.3 图片占位图的使用 74 | 75 | - WBChatMessageImageCell 的 `- (void)setCellModel:(WBChatMessageBaseCellModel *)cellModel 76 | ` 77 | 78 | ``` 79 | NSString *imageLocalPath = imageFrameModel.messageModel.imagePath; 80 | BOOL isLocalPath = ![imageLocalPath hasPrefix:@"http"]; 81 | UIImage *image = nil; 82 | if (isLocalPath) { 83 | NSData *imageData = [NSData dataWithContentsOfFile:imageLocalPath]; 84 | image = [UIImage imageWithData:imageData]; 85 | } 86 | 87 | if (image && isLocalPath) { 88 | self.dialogCellImageView.image = image; 89 | } 90 | else if (imageLocalPath.length && self.tempChatModel.thumbImage){ 91 | [[WBChatCellConfig sharedInstance].imageLoad imageView:self.dialogCellImageView 92 | urlString:imageLocalPath 93 | placeholderImage:self.tempChatModel.thumbImage]; 94 | } 95 | else if (self.tempChatModel.thumbImage) { 96 | self.dialogCellImageView.image = self.tempChatModel.thumbImage; 97 | } 98 | else{ 99 | self.dialogCellImageView.image = [WBChatCellConfig sharedInstance].placeholdImage; 100 | } 101 | 102 | ``` 103 | 104 | 105 | ### 2.4 其他属性 106 | 107 | `WBChatCellConfig` 单例的其他属性是控制消息控件的`frame`, 根据实际情况用户可以自己调整. 108 | 109 | -------------------------------------------------------------------------------- /Example/Podfile: -------------------------------------------------------------------------------- 1 | use_frameworks! 2 | 3 | target 'WBChatIMKit_Example' do 4 | pod 'WBChatIMKit', :path => '../' 5 | 6 | target 'WBChatIMKit_Tests' do 7 | inherit! :search_paths 8 | 9 | 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /Example/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - AVOSCloud (10.0.2) 3 | - AVOSCloudIM (10.0.2): 4 | - AVOSCloud (= 10.0.2) 5 | - AVOSCloudIM/_ARC (= 10.0.2) 6 | - AVOSCloudIM/_NOARC (= 10.0.2) 7 | - AVOSCloudIM/_ARC (10.0.2): 8 | - AVOSCloud (= 10.0.2) 9 | - AVOSCloudIM/_NOARC (= 10.0.2) 10 | - AVOSCloudIM/_NOARC (10.0.2): 11 | - AVOSCloud (= 10.0.2) 12 | - FMDB (2.7.2): 13 | - FMDB/standard (= 2.7.2) 14 | - FMDB/standard (2.7.2) 15 | - WBChatIMKit (0.1.4): 16 | - AVOSCloud 17 | - AVOSCloudIM 18 | - FMDB 19 | 20 | DEPENDENCIES: 21 | - WBChatIMKit (from `../`) 22 | 23 | EXTERNAL SOURCES: 24 | WBChatIMKit: 25 | :path: ../ 26 | 27 | SPEC CHECKSUMS: 28 | AVOSCloud: bfd439e58b0306e40fbcf8791d28ae906a51a73d 29 | AVOSCloudIM: 1c4b09e32f17a58ccd1b7602c48ccae3baeaa8ed 30 | FMDB: 6198a90e7b6900cfc046e6bc0ef6ebb7be9236aa 31 | WBChatIMKit: 804b932b4be329b0d47cffc805ecf84427d7815c 32 | 33 | PODFILE CHECKSUM: aee3dd1c5a17d0f36ae4585cc0cbc32927e09bc7 34 | 35 | COCOAPODS: 1.4.0 36 | -------------------------------------------------------------------------------- /Example/Tests/Tests-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundlePackageType 14 | BNDL 15 | CFBundleShortVersionString 16 | 1.0 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /Example/Tests/Tests-Prefix.pch: -------------------------------------------------------------------------------- 1 | // The contents of this file are implicitly included at the beginning of every test case source file. 2 | 3 | #ifdef __OBJC__ 4 | 5 | 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /Example/Tests/Tests.m: -------------------------------------------------------------------------------- 1 | // 2 | // WBChatIMKitTests.m 3 | // WBChatIMKitTests 4 | // 5 | // Created by Ding RedRain on 03/13/2018. 6 | // Copyright (c) 2018 Ding RedRain. All rights reserved. 7 | // 8 | 9 | @import XCTest; 10 | 11 | @interface Tests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation Tests 16 | 17 | - (void)setUp 18 | { 19 | [super setUp]; 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | } 22 | 23 | - (void)tearDown 24 | { 25 | // Put teardown code here. This method is called after the invocation of each test method in the class. 26 | [super tearDown]; 27 | } 28 | 29 | - (void)testExample 30 | { 31 | XCTFail(@"No implementation for \"%s\"", __PRETTY_FUNCTION__); 32 | } 33 | 34 | @end 35 | 36 | -------------------------------------------------------------------------------- /Example/Tests/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Example/WBChatIMKit.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Example/WBChatIMKit.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Example/WBChatIMKit/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /Example/WBChatIMKit/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "size" : "1024x1024", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /Example/WBChatIMKit/WBAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // WBAppDelegate.h 3 | // WBChatIMKit 4 | // 5 | // Created by Ding RedRain on 03/13/2018. 6 | // Copyright (c) 2018 Ding RedRain. All rights reserved. 7 | // 8 | 9 | @import UIKit; 10 | 11 | @interface WBAppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Example/WBChatIMKit/WBAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // WBAppDelegate.m 3 | // WBChatIMKit 4 | // 5 | // Created by Ding RedRain on 03/13/2018. 6 | // Copyright (c) 2018 Ding RedRain. All rights reserved. 7 | // 8 | 9 | #import "WBAppDelegate.h" 10 | #import 11 | @implementation WBAppDelegate 12 | 13 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 14 | { 15 | [AVOSCloud setAllLogsEnabled:false]; 16 | [WBChatKit setAppId:@"O9I67dBpCiW8WcgoD89dCpla-gzGzoHsz" 17 | clientKey:@"HwqdEYsaL3D3Xqr45Ryr0PW1"]; 18 | return YES; 19 | } 20 | 21 | - (void)applicationWillResignActive:(UIApplication *)application 22 | { 23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 24 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 25 | } 26 | 27 | - (void)applicationDidEnterBackground:(UIApplication *)application 28 | { 29 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 30 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 31 | } 32 | 33 | - (void)applicationWillEnterForeground:(UIApplication *)application 34 | { 35 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 36 | } 37 | 38 | - (void)applicationDidBecomeActive:(UIApplication *)application 39 | { 40 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 41 | } 42 | 43 | - (void)applicationWillTerminate:(UIApplication *)application 44 | { 45 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 46 | } 47 | 48 | @end 49 | -------------------------------------------------------------------------------- /Example/WBChatIMKit/WBChatIMKit-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.0 25 | LSRequiresIPhoneOS 26 | 27 | NSAppTransportSecurity 28 | 29 | NSAllowsArbitraryLoads 30 | 31 | 32 | NSCameraUsageDescription 33 | 应用需要您开启此权限 34 | NSContactsUsageDescription 35 | 应用需要您开启此权限 36 | NSLocationAlwaysUsageDescription 37 | 应用需要您开启此权限 38 | NSLocationUsageDescription 39 | 应用需要您开启此权限 40 | NSLocationWhenInUseUsageDescription 41 | 应用需要您开启此权限 42 | NSMicrophoneUsageDescription 43 | 应用需要您开启此权限 44 | NSPhotoLibraryUsageDescription 45 | 应用需要您开启此权限 46 | UILaunchStoryboardName 47 | LaunchScreen 48 | UIMainStoryboardFile 49 | Main 50 | UIRequiredDeviceCapabilities 51 | 52 | armv7 53 | 54 | UISupportedInterfaceOrientations 55 | 56 | UIInterfaceOrientationPortrait 57 | UIInterfaceOrientationLandscapeLeft 58 | UIInterfaceOrientationLandscapeRight 59 | 60 | UISupportedInterfaceOrientations~ipad 61 | 62 | UIInterfaceOrientationPortrait 63 | UIInterfaceOrientationPortraitUpsideDown 64 | UIInterfaceOrientationLandscapeLeft 65 | UIInterfaceOrientationLandscapeRight 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /Example/WBChatIMKit/WBChatIMKit-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header 3 | // 4 | // The contents of this file are implicitly included at the beginning of every source file. 5 | // 6 | 7 | #import 8 | 9 | #ifndef __IPHONE_5_0 10 | #warning "This project uses features only available in iOS SDK 5.0 and later." 11 | #endif 12 | 13 | #ifdef __OBJC__ 14 | @import UIKit; 15 | @import Foundation; 16 | #endif 17 | -------------------------------------------------------------------------------- /Example/WBChatIMKit/WBChatKitDelegateObj.h: -------------------------------------------------------------------------------- 1 | // 2 | // WBChatKitDelegateObj.h 3 | // WBChatIMKit_Example 4 | // 5 | // Created by RedRain on 2018/3/14. 6 | // Copyright © 2018年 Ding RedRain. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | @interface WBChatKitDelegateObj : NSObject 12 | + (instancetype)sharedManager; 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /Example/WBChatIMKit/WBChatKitDelegateObj.m: -------------------------------------------------------------------------------- 1 | // 2 | // WBChatKitDelegateObj.m 3 | // WBChatIMKit_Example 4 | // 5 | // Created by RedRain on 2018/3/14. 6 | // Copyright © 2018年 Ding RedRain. All rights reserved. 7 | // 8 | 9 | #import "WBChatKitDelegateObj.h" 10 | 11 | @implementation WBChatKitDelegateObj 12 | + (instancetype)sharedManager { 13 | static WBChatKitDelegateObj *_shared = nil; 14 | static dispatch_once_t onceToken; 15 | dispatch_once(&onceToken, ^{ 16 | _shared = [WBChatKitDelegateObj new]; 17 | }); 18 | 19 | return _shared; 20 | } 21 | 22 | 23 | #pragma mark - WBChatKitProtocol 24 | - (NSString *)memberNameWithClientID:(NSString *)clientId{ 25 | AVQuery *query = [AVQuery queryWithClassName:@"_User"]; 26 | AVObject *obj = [query getObjectWithId:clientId]; 27 | return ((AVUser *)obj).username; 28 | } 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /Example/WBChatIMKit/WBViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // WBViewController.h 3 | // WBChatIMKit 4 | // 5 | // Created by Ding RedRain on 03/13/2018. 6 | // Copyright (c) 2018 Ding RedRain. All rights reserved. 7 | // 8 | 9 | @import UIKit; 10 | 11 | @interface WBViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Example/WBChatIMKit/WBViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // WBViewController.m 3 | // WBChatIMKit 4 | // 5 | // Created by Ding RedRain on 03/13/2018. 6 | // Copyright (c) 2018 Ding RedRain. All rights reserved. 7 | // 8 | 9 | #import "WBViewController.h" 10 | #import 11 | #import "WBChatKitDelegateObj.h" 12 | @interface WBViewController () 13 | 14 | @end 15 | 16 | @implementation WBViewController 17 | 18 | - (void)viewDidLoad 19 | { 20 | [super viewDidLoad]; 21 | // Do any additional setup after loading the view, typically from a nib. 22 | [WBChatKit sharedInstance].delegate = [WBChatKitDelegateObj sharedManager]; 23 | 24 | [self loginTom:nil]; 25 | 26 | } 27 | 28 | 29 | - (void)didReceiveMemoryWarning 30 | { 31 | [super didReceiveMemoryWarning]; 32 | // Dispose of any resources that can be recreated. 33 | } 34 | 35 | - (IBAction)createAndSend:(id)sender { 36 | WBMessageModel *text = [WBMessageModel createWithText:[NSDate new].description]; 37 | 38 | // 请查看这个方法的具体实现 !!! 39 | [[WBChatKit sharedInstance] sendTargetUserId:@"Jerry" 40 | message:text 41 | success:^(WBMessageModel * _Nonnull aMessage) 42 | { 43 | [self.view wb_makeToast:@"消息发送成功"]; 44 | 45 | } error:^(WBMessageModel * _Nonnull aMessage, NSError * _Nonnull error) { 46 | [self.view wb_makeToast:error.description]; 47 | 48 | }]; 49 | 50 | } 51 | 52 | - (IBAction)pushRecentConnecter:(id)sender { 53 | WBChatListController *vc = [[WBChatListController alloc]init]; 54 | 55 | UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc]; 56 | [self presentViewController:nav animated:YES completion:nil]; 57 | 58 | } 59 | 60 | 61 | 62 | - (IBAction)logOut{ 63 | [[WBChatKit sharedInstance] closeWithCallback:^(BOOL succeeded, NSError * _Nonnull error) { 64 | if (succeeded) { 65 | WBLog(@"退出成功"); 66 | [self.view wb_makeToast:@"退出成功"]; 67 | }else{ 68 | 69 | WBLog(@"退出失败"); 70 | [self.view wb_makeToast:@"退出失败"]; 71 | } 72 | }]; 73 | } 74 | 75 | - (IBAction)loginTom:(id)sender { 76 | [self loginWithID:@"Tom"]; 77 | 78 | } 79 | 80 | - (IBAction)loginJerry:(id)sender { 81 | [self loginWithID:@"Jerry"]; 82 | } 83 | 84 | - (void)loginWithID:(NSString *)userId{ 85 | 86 | [[WBChatKit sharedInstance] openWithClientId:userId 87 | success:^(NSString * _Nonnull clientId) 88 | { 89 | WBLog(@"链接成功"); 90 | [self.view wb_makeToast:@"链接成功"]; 91 | 92 | } error:^(NSError * _Nonnull error) { 93 | WBLog(@"链接失败: %@", 94 | error.description); 95 | [self.view wb_makeToast:@"链接失败"]; 96 | }]; 97 | } 98 | 99 | @end 100 | -------------------------------------------------------------------------------- /Example/WBChatIMKit/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Example/WBChatIMKit/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // WBChatIMKit 4 | // 5 | // Created by Ding RedRain on 03/13/2018. 6 | // Copyright (c) 2018 Ding RedRain. All rights reserved. 7 | // 8 | 9 | @import UIKit; 10 | #import "WBAppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) 13 | { 14 | @autoreleasepool { 15 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([WBAppDelegate class])); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2018 Ding RedRain <447154278@qq.com> 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /WBChatIMKit.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # Be sure to run `pod lib lint WBChatIMKit.podspec' to ensure this is a 3 | # valid spec before submitting. 4 | # 5 | # Any lines starting with a # are optional, but their use is encouraged 6 | # To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html 7 | # 8 | 9 | Pod::Spec.new do |s| 10 | s.name = 'WBChatIMKit' 11 | s.version = '0.1.5' 12 | s.summary = "基于LeanCloud的IM功能,可以快速使用的UI框架" 13 | 14 | # This description is used to generate tags and improve search results. 15 | # * Think: What does it do? Why did you write it? What is the focus? 16 | # * Try to keep it short, snappy and to the point. 17 | # * Write the description between the DESC delimiters below. 18 | # * Finally, don't worry about the indent, CocoaPods strips it! 19 | 20 | s.description = "提供了发送文字,图片,语音消息的控件" \ 21 | "提供了最近联系人列表"\ 22 | "未读消息提醒, 草稿缓存等基础功能" 23 | 24 | s.homepage = 'https://github.com/rxdxxxx/WBChatIMKit' 25 | # s.screenshots = 'www.example.com/screenshots_1', 'www.example.com/screenshots_2' 26 | s.license = { :type => 'MIT', :file => 'LICENSE' } 27 | s.author = { 'rxdxxxx' => '447154278@qq.com' } 28 | s.source = { :git => 'https://github.com/rxdxxxx/WBChatIMKit.git', :tag => s.version.to_s } 29 | # s.social_media_url = 'https://twitter.com/' 30 | 31 | s.ios.deployment_target = '8.0' 32 | 33 | s.source_files = 'WBChatIMKit/Classes/**/*.{h,m}','WBChatIMKit' 34 | 35 | s.vendored_frameworks = 'WBChatIMKit/Classes/VoiceLib/lame.framework' 36 | 37 | s.resources = 'WBChatIMKit/Classes/Resource/*', 'WBChatIMKit/**/*.xib' 38 | 39 | # s.resource_bundles = { 40 | # 'WBChatIMKit' => ['WBChatIMKit/Assets/*.png'] 41 | # } 42 | 43 | # s.frameworks = 'UIKit', 'MapKit' 44 | s.requires_arc = true 45 | s.dependency 'FMDB' 46 | s.dependency 'AVOSCloud' 47 | s.dependency 'AVOSCloudIM' 48 | end 49 | -------------------------------------------------------------------------------- /WBChatIMKit/Assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Assets/.gitkeep -------------------------------------------------------------------------------- /WBChatIMKit/Classes/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/.gitkeep -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ChatUI/Chat/Cell/WBChatMessageBaseCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // WBChatBaseCell.h 3 | // WBChat 4 | // 5 | // Created by RedRain on 2018/1/18. 6 | // Copyright © 2018年 RedRain. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "WBChatMessageBaseCellModel.h" 11 | #import "UIView+Frame.h" 12 | #import "UIImage+WBImage.h" 13 | 14 | @class WBChatMessageBaseCell; 15 | 16 | @protocol WBChatMessageCellDelegate 17 | 18 | - (void)cell:(WBChatMessageBaseCell *)cell resendMessage:(WBChatMessageBaseCellModel *)cellModel; 19 | - (void)cell:(WBChatMessageBaseCell *)cell tapImageViewModel:(WBChatMessageBaseCellModel *)cellModel; 20 | 21 | @end 22 | 23 | @interface WBChatMessageBaseCell : UITableViewCell 24 | 25 | /** 26 | 父类根据 cellModel 创建对应的子类对象 27 | */ 28 | + (instancetype)cellWithTableView:(UITableView *)tableView cellModel:(WBChatMessageBaseCellModel *)cellModel; 29 | 30 | 31 | /** 32 | 子类必须重写 创建cell, cell的复用逻辑已经实现, 使用类名作为唯一标识ID 33 | */ 34 | + (instancetype)cellWithTableView:(UITableView *)tableView; 35 | 36 | @property (nonatomic, weak) id delegate; 37 | 38 | @property (nonatomic, strong) WBChatMessageBaseCellModel *cellModel; 39 | 40 | 41 | ///气泡 42 | @property (nonatomic, strong) UIImageView *bubbleImageView; 43 | 44 | 45 | ///发送的消息的状态 46 | @property (nonatomic, strong) UIImageView *messageStatusImageView; 47 | 48 | /** 49 | * 会话界面消息阅读状态 50 | */ 51 | @property (nonatomic, strong) UILabel *messageReadStateLabel; 52 | 53 | /** 54 | 显示的cell的indexPath 55 | */ 56 | @property (nonatomic, strong) NSIndexPath *indexPath; 57 | 58 | @end 59 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ChatUI/Chat/Cell/WBChatMessageHintCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // WBChatMessageHintCell.h 3 | // AVOSCloud 4 | // 5 | // Created by RedRain on 2018/3/14. 6 | // 7 | 8 | #import 9 | 10 | @interface WBChatMessageHintCell : WBChatMessageBaseCell 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ChatUI/Chat/Cell/WBChatMessageHintCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // WBChatMessageHintCell.m 3 | // AVOSCloud 4 | // 5 | // Created by RedRain on 2018/3/14. 6 | // 7 | 8 | #import "WBChatMessageHintCell.h" 9 | #import "WBChatMessageRecallCellModel.h" 10 | @interface WBChatMessageHintCell () 11 | 12 | @property (nonatomic, strong) UILabel *hintLabel; 13 | 14 | @end 15 | @implementation WBChatMessageHintCell 16 | 17 | + (instancetype)cellWithTableView:(UITableView *)tableView { 18 | static NSString *ID = @"WBChatMessageHintCell"; 19 | WBChatMessageHintCell *cell = [tableView dequeueReusableCellWithIdentifier:ID]; 20 | if (cell == nil) { 21 | cell = [[WBChatMessageHintCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID]; 22 | cell.backgroundColor = [UIColor clearColor]; 23 | } 24 | return cell; 25 | } 26 | 27 | - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { 28 | self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; 29 | if (self) { 30 | 31 | [self.contentView addSubview:self.hintLabel]; 32 | 33 | } 34 | return self; 35 | } 36 | 37 | - (void)setCellModel:(WBChatMessageBaseCellModel *)cellModel{ 38 | [super setCellModel:cellModel]; 39 | 40 | NSString *hintString = @"此版本暂时不支持此类消息."; 41 | 42 | if ([cellModel isKindOfClass:WBChatMessageRecallCellModel.class]) { 43 | WBChatMessageRecallCellModel *fModel = (WBChatMessageRecallCellModel *)cellModel; 44 | hintString = fModel.hintString; 45 | } 46 | 47 | 48 | self.hintLabel.text = hintString; 49 | UIFont *font = [WBChatCellConfig sharedInstance].timeFont; 50 | CGSize size = [hintString sizeWithAttributes:@{NSFontAttributeName:font}]; 51 | self.hintLabel.frame = CGRectMake(kWBScreenWidth/2-size.width/2-10 ,15,size.width+20,20); 52 | 53 | 54 | } 55 | 56 | - (UILabel *)hintLabel{ 57 | if (!_hintLabel) { 58 | 59 | _hintLabel=[[UILabel alloc] init]; 60 | _hintLabel.backgroundColor=[UIColor lightGrayColor]; 61 | _hintLabel.font = [WBChatCellConfig sharedInstance].timeFont; 62 | _hintLabel.textAlignment=NSTextAlignmentCenter; 63 | _hintLabel.textColor = [UIColor whiteColor]; 64 | _hintLabel.layer.masksToBounds=true; 65 | _hintLabel.layer.cornerRadius = 4; 66 | } 67 | return _hintLabel; 68 | } 69 | 70 | @end 71 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ChatUI/Chat/Cell/WBChatMessageImageCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // WBChatMessageImageCell.h 3 | // WBChat 4 | // 5 | // Created by RedRain on 2018/2/5. 6 | // Copyright © 2018年 RedRain. All rights reserved. 7 | // 8 | 9 | #import "WBChatMessageBaseCell.h" 10 | 11 | @interface WBChatMessageImageCell : WBChatMessageBaseCell 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ChatUI/Chat/Cell/WBChatMessageTextCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // WBChatMessageTextCell.h 3 | // WBChat 4 | // 5 | // Created by RedRain on 2018/1/19. 6 | // Copyright © 2018年 RedRain. All rights reserved. 7 | // 8 | 9 | #import "WBChatMessageBaseCell.h" 10 | 11 | @interface WBChatMessageTextCell : WBChatMessageBaseCell 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ChatUI/Chat/Cell/WBChatMessageTextCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // WBChatMessageTextCell.m 3 | // WBChat 4 | // 5 | // Created by RedRain on 2018/1/19. 6 | // Copyright © 2018年 RedRain. All rights reserved. 7 | // 8 | 9 | #import "WBChatMessageTextCell.h" 10 | #import "WBChatMessageTextCellModel.h" 11 | @interface WBChatMessageTextCell () 12 | ///会话文本内容 13 | @property (nonatomic, strong)UILabel *mLabel; 14 | 15 | @property (nonatomic, strong) UIScrollView *textContentScrollView; 16 | 17 | @property (nonatomic, strong) UIMenuController *menuController; 18 | 19 | @end 20 | 21 | @implementation WBChatMessageTextCell 22 | 23 | + (instancetype)cellWithTableView:(UITableView *)tableView { 24 | 25 | static NSString *ID = @"WBChatMessageTextCell"; 26 | WBChatMessageTextCell *cell = [tableView dequeueReusableCellWithIdentifier:ID]; 27 | if (cell == nil) { 28 | cell = [[WBChatMessageTextCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID]; 29 | } 30 | 31 | return cell; 32 | } 33 | - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{ 34 | if (self=[super initWithStyle:style reuseIdentifier:reuseIdentifier]) { 35 | [self.contentView addSubview:self.mLabel]; 36 | } 37 | return self; 38 | } 39 | 40 | - (void)setSelected:(BOOL)selected animated:(BOOL)animated { 41 | [super setSelected:selected animated:animated]; 42 | 43 | // Configure the view for the selected state 44 | } 45 | - (void)backTapClick:(UITapGestureRecognizer *)tap{ 46 | 47 | } 48 | 49 | #pragma mark - Getters and Getters 50 | - (void)setCellModel:(WBChatMessageTextCellModel *)cellModel{ 51 | [super setCellModel:cellModel]; 52 | 53 | 54 | [UIView setAnimationsEnabled:NO]; 55 | 56 | self.bubbleImageView.frame = cellModel.textWithBubbleRectFrame; 57 | self.mLabel.frame=cellModel.textRectFrame; 58 | [UIView setAnimationsEnabled:YES]; 59 | 60 | 61 | 62 | 63 | if(cellModel.messageModel.content.ioType == AVIMMessageIOTypeIn){ 64 | self.mLabel.textColor=[UIColor blackColor]; 65 | } 66 | else{ 67 | self.mLabel.textColor=[UIColor whiteColor]; 68 | } 69 | self.mLabel.text = cellModel.content; 70 | 71 | 72 | } 73 | 74 | #pragma mark - getters and setters 75 | -(UILabel *)mLabel{ 76 | if(nil==_mLabel) 77 | { 78 | _mLabel=[[UILabel alloc] initWithFrame:CGRectZero]; 79 | _mLabel.font = [WBChatCellConfig sharedInstance].textFont; 80 | _mLabel.numberOfLines = 0; 81 | _mLabel.lineBreakMode = NSLineBreakByWordWrapping; 82 | } 83 | return _mLabel; 84 | } 85 | 86 | - (UIScrollView *)textContentScrollView { 87 | if (!_textContentScrollView) { 88 | //3.设置滚动视图 89 | _textContentScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, kWBScreenWidth, kWBScreenWidth)]; 90 | _textContentScrollView.backgroundColor = [UIColor whiteColor]; 91 | _textContentScrollView.showsHorizontalScrollIndicator = NO; 92 | _textContentScrollView.showsVerticalScrollIndicator = YES; 93 | _textContentScrollView.bounces = YES; 94 | UITapGestureRecognizer *backTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(backTapClick:)]; 95 | [_textContentScrollView addGestureRecognizer:backTap]; 96 | 97 | } 98 | return _textContentScrollView; 99 | } 100 | 101 | @end 102 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ChatUI/Chat/Cell/WBChatMessageTimeCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // WBChatMessageTimeCell.h 3 | // WBChat 4 | // 5 | // Created by RedRain on 2018/3/1. 6 | // Copyright © 2018年 RedRain. All rights reserved. 7 | // 8 | 9 | #import "WBChatMessageBaseCell.h" 10 | 11 | @interface WBChatMessageTimeCell : WBChatMessageBaseCell 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ChatUI/Chat/Cell/WBChatMessageTimeCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // WBChatMessageTimeCell.m 3 | // WBChat 4 | // 5 | // Created by RedRain on 2018/3/1. 6 | // Copyright © 2018年 RedRain. All rights reserved. 7 | // 8 | 9 | #import "WBChatMessageTimeCell.h" 10 | #import "WBChatMessageTimeCellModel.h" 11 | 12 | @interface WBChatMessageTimeCell () 13 | 14 | @property (nonatomic, strong) UILabel *timeLabel; 15 | 16 | @property (nonatomic, weak) UITableView * tableView; 17 | @end 18 | 19 | @implementation WBChatMessageTimeCell 20 | 21 | 22 | - (void)dealloc{ 23 | [[NSNotificationCenter defaultCenter] removeObserver:self]; 24 | } 25 | 26 | + (instancetype)cellWithTableView:(UITableView *)tableView { 27 | static NSString *ID = @"WBChatMessageTimeCell"; 28 | WBChatMessageTimeCell *cell = [tableView dequeueReusableCellWithIdentifier:ID]; 29 | if (cell == nil) { 30 | cell = [[WBChatMessageTimeCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID]; 31 | cell.tableView = tableView; 32 | cell.backgroundColor = [UIColor clearColor]; 33 | } 34 | return cell; 35 | } 36 | - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { 37 | self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; 38 | if (self) { 39 | 40 | [self.contentView addSubview:self.timeLabel]; 41 | 42 | } 43 | return self; 44 | } 45 | 46 | - (void)setCellModel:(WBChatMessageBaseCellModel *)cellModel{ 47 | [super setCellModel:cellModel]; 48 | WBChatMessageTimeCellModel *fModel = (WBChatMessageTimeCellModel *)cellModel; 49 | 50 | self.timeLabel.text = fModel.timeString; 51 | UIFont *font = [WBChatCellConfig sharedInstance].timeFont; 52 | CGSize size = [fModel.timeString sizeWithAttributes:@{NSFontAttributeName:font}]; 53 | self.timeLabel.frame = CGRectMake(kWBScreenWidth/2-size.width/2-10 ,15,size.width+20,20); 54 | 55 | 56 | } 57 | 58 | - (UILabel *)timeLabel{ 59 | if (!_timeLabel) { 60 | 61 | _timeLabel=[[UILabel alloc] init]; 62 | _timeLabel.backgroundColor=[UIColor lightGrayColor]; 63 | _timeLabel.font = [WBChatCellConfig sharedInstance].timeFont; 64 | _timeLabel.textAlignment=NSTextAlignmentCenter; 65 | _timeLabel.textColor = [UIColor whiteColor]; 66 | _timeLabel.layer.masksToBounds=true; 67 | _timeLabel.layer.cornerRadius = 4; 68 | } 69 | return _timeLabel; 70 | } 71 | @end 72 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ChatUI/Chat/Cell/WBChatMessageVoiceCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // WBChatMessageVoiceCell.h 3 | // WBChat 4 | // 5 | // Created by RedRain on 2018/2/6. 6 | // Copyright © 2018年 RedRain. All rights reserved. 7 | // 8 | 9 | #import "WBChatMessageBaseCell.h" 10 | 11 | @interface WBChatMessageVoiceCell : WBChatMessageBaseCell 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ChatUI/Chat/CellModel/WBChatMessageBaseCellModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // WBChatBaseCellModel.h 3 | // WBChat 4 | // 5 | // Created by RedRain on 2018/1/18. 6 | // Copyright © 2018年 RedRain. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "WBChatCellConfig.h" 11 | #import "WBServiceSDKHeaders.h" 12 | 13 | 14 | @interface WBChatMessageBaseCellModel : NSObject 15 | 16 | + (instancetype)modelWithMessageModel:(WBMessageModel *)messageModel; 17 | 18 | @property (nonatomic, strong) WBMessageModel *messageModel; 19 | 20 | ///< 消息类型 21 | @property (nonatomic, assign) WBChatMessageType cellType; 22 | 23 | ///< 对方头像的位置 24 | @property (nonatomic, assign) CGRect headerRectFrame; 25 | 26 | ///< 自己头像的位置 27 | @property (nonatomic, assign) CGRect myHeaderRectFrame; 28 | 29 | ///< cell的高度 30 | @property (nonatomic, assign) CGFloat cellHeight; 31 | 32 | ///< 发送的消息的状态位置 33 | @property (nonatomic, assign) CGRect messageStatusRectFrame; 34 | 35 | ///< 会话界面消息阅读状态 36 | @property (nonatomic, assign) CGRect messageReadStateRectFrame; 37 | 38 | ///< 对方昵称的位置 39 | @property (nonatomic, assign) CGRect usernameRectFrame; 40 | 41 | 42 | @property (nonatomic, assign) BOOL showName; 43 | 44 | - (int64_t)cellTimeStamp; 45 | 46 | @end 47 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ChatUI/Chat/CellModel/WBChatMessageImageCellModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // WBChatMessageImageCellModel.h 3 | // WBChat 4 | // 5 | // Created by RedRain on 2018/2/5. 6 | // Copyright © 2018年 RedRain. All rights reserved. 7 | // 8 | 9 | #import "WBChatMessageBaseCellModel.h" 10 | 11 | @interface WBChatMessageImageCellModel : WBChatMessageBaseCellModel 12 | 13 | //图片cell frame 14 | @property (nonatomic, assign) CGRect imageRectFrame; 15 | //进度圈的位置 16 | @property (nonatomic, assign) CGRect imageProcessRectFrame; 17 | //进度百分比的位置 18 | @property (nonatomic, assign) CGRect labelProcessRectFrame; 19 | 20 | @property (nonatomic, assign) CGFloat imageUploadProcess; 21 | @end 22 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ChatUI/Chat/CellModel/WBChatMessageRecallCellModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // WBChatMessageRecallCellModel.h 3 | // AVOSCloud 4 | // 5 | // Created by RedRain on 2018/3/14. 6 | // 7 | 8 | #import 9 | 10 | @interface WBChatMessageRecallCellModel : WBChatMessageBaseCellModel 11 | 12 | @property (nonatomic, copy) NSString *hintString; 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ChatUI/Chat/CellModel/WBChatMessageRecallCellModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // WBChatMessageRecallCellModel.m 3 | // AVOSCloud 4 | // 5 | // Created by RedRain on 2018/3/14. 6 | // 7 | 8 | #import "WBChatMessageRecallCellModel.h" 9 | 10 | @implementation WBChatMessageRecallCellModel 11 | - (instancetype)init 12 | { 13 | self = [super init]; 14 | if (self) { 15 | self.cellType = WBChatMessageTypeRecalled; 16 | self.cellHeight = 36; 17 | self.hintString = @"此消息已被撤回."; 18 | } 19 | return self; 20 | } 21 | @end 22 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ChatUI/Chat/CellModel/WBChatMessageTextCellModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // WBChatMessageTextCellModel.h 3 | // WBChat 4 | // 5 | // Created by RedRain on 2018/1/19. 6 | // Copyright © 2018年 RedRain. All rights reserved. 7 | // 8 | 9 | #import "WBChatMessageBaseCellModel.h" 10 | 11 | @interface WBChatMessageTextCellModel : WBChatMessageBaseCellModel 12 | 13 | @property (nonatomic, copy) NSString *content; ///< 消息内容 14 | 15 | @property (nonatomic, assign, readonly) CGRect textRectFrame; 16 | 17 | @property (nonatomic, assign, readonly) CGRect textWithBubbleRectFrame; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ChatUI/Chat/CellModel/WBChatMessageTimeCellModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // WBChatMessageTimeCellModel.h 3 | // WBChat 4 | // 5 | // Created by RedRain on 2018/3/1. 6 | // Copyright © 2018年 RedRain. All rights reserved. 7 | // 8 | 9 | #import "WBChatMessageBaseCellModel.h" 10 | 11 | @interface WBChatMessageTimeCellModel : WBChatMessageBaseCellModel 12 | 13 | + (instancetype)modelWithTimeStamp:(NSTimeInterval)timeStamp; 14 | 15 | @property (nonatomic, assign) NSTimeInterval timeStamp; 16 | 17 | @property (nonatomic, copy) NSString *timeString; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ChatUI/Chat/CellModel/WBChatMessageTimeCellModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // WBChatMessageTimeCellModel.m 3 | // WBChat 4 | // 5 | // Created by RedRain on 2018/3/1. 6 | // Copyright © 2018年 RedRain. All rights reserved. 7 | // 8 | 9 | #import "WBChatMessageTimeCellModel.h" 10 | #import "NSDate+Extension.h" 11 | @implementation WBChatMessageTimeCellModel 12 | - (instancetype)init 13 | { 14 | self = [super init]; 15 | if (self) { 16 | self.cellType = WBChatMessageTypeTime; 17 | self.cellHeight = 36; 18 | } 19 | return self; 20 | } 21 | 22 | + (instancetype)modelWithTimeStamp:(NSTimeInterval)timeStamp{ 23 | WBChatMessageTimeCellModel *model = [WBChatMessageTimeCellModel new]; 24 | model.timeStamp = timeStamp; 25 | return model; 26 | } 27 | 28 | - (void)setTimeStamp:(NSTimeInterval)timeStamp{ 29 | _timeStamp = timeStamp; 30 | self.timeString = [self timeStringByTimeStamp:timeStamp]; 31 | } 32 | 33 | - (NSString *)timeStringByTimeStamp:(long long)timeStamp { 34 | // 公众号的时间戳, 会多1000. 35 | if (timeStamp > 10000000000) { 36 | timeStamp = timeStamp/1000; 37 | } 38 | 39 | NSDateFormatter *fmt = [[NSDateFormatter alloc] init]; 40 | NSDate *createDate = [NSDate dateWithTimeIntervalSince1970:timeStamp]; 41 | if ([createDate wb_isToday]) { 42 | fmt.dateFormat = @"HH:mm"; 43 | return [fmt stringFromDate:createDate]; 44 | }else if ([createDate wb_isThisYear]){ 45 | 46 | fmt.dateFormat = @"MM月dd日 HH:mm"; 47 | return [fmt stringFromDate:createDate]; 48 | }else { 49 | //如果当前时间是12小时制,就会显示08:07 50 | fmt.dateFormat = @"yyyy年MM月dd日 HH:mm"; 51 | return [fmt stringFromDate:createDate]; 52 | } 53 | } 54 | @end 55 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ChatUI/Chat/CellModel/WBChatMessageVoiceCellModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // WBChatMessageVoiceCellModel.h 3 | // WBChat 4 | // 5 | // Created by RedRain on 2018/2/6. 6 | // Copyright © 2018年 RedRain. All rights reserved. 7 | // 8 | 9 | #import "WBChatMessageBaseCellModel.h" 10 | 11 | typedef NS_ENUM(NSUInteger, WBVoiceCellState) { 12 | WBVoiceCellStateNormal, 13 | WBVoiceCellStatePlaying, 14 | WBVoiceCellStateDownloading 15 | }; 16 | 17 | @interface WBChatMessageVoiceCellModel : WBChatMessageBaseCellModel 18 | 19 | @property (nonatomic, assign) CGRect voiceWaveImageFrame; 20 | @property (nonatomic, assign) CGRect voiceTimeNumLabelFrame; 21 | @property (nonatomic, assign) CGRect voiceBubbleFrame; 22 | 23 | @property (nonatomic, assign) WBVoiceCellState voiceState; // 语音播放的状态 24 | 25 | - (UIImageView *)messageVoiceAnimationImageViewWithBubbleMessageType:(BOOL)owner; 26 | @end 27 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ChatUI/Chat/Tool/UITableView+WBScrollToIndexPath.h: -------------------------------------------------------------------------------- 1 | // 2 | // UITableView+WBScrollToIndexPath.h 3 | 4 | 5 | #import 6 | 7 | @interface UITableView (WBScrollToIndexPath) 8 | /** 9 | * TableView滚动到底部 10 | * 11 | * @param animated 是否有动画 12 | */ 13 | -(void)wb_scrollToBottomAnimated:(BOOL)animated; 14 | 15 | /** 16 | * TableView滚动到指定的indexPath 17 | * 18 | * @param indexPath 滚动到的目标行 19 | * @param animated 是否有动画 20 | */ 21 | - (void)wb_scrollToIndexPath:(NSIndexPath*)indexPath Animated:(BOOL)animated; 22 | 23 | /** 24 | * TableView滚动到指定的indexPath 25 | * 26 | * @param indexPath 滚动到的目标行 27 | * @param postion tablev滚动显示的位置 28 | * @param animated 是否有动画 29 | */ 30 | - (void)wb_scrollToIndexPath:(NSIndexPath *)indexPath atScrollPosition:(UITableViewScrollPosition)postion Animated:(BOOL)animated; 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ChatUI/Chat/Tool/UITableView+WBScrollToIndexPath.m: -------------------------------------------------------------------------------- 1 | // 2 | // UITableView+WBScrollToIndexPath.m 3 | 4 | 5 | #import "UITableView+WBScrollToIndexPath.h" 6 | 7 | @implementation UITableView (WBScrollToIndexPath) 8 | -(void)wb_scrollToBottomAnimated:(BOOL)animated{ 9 | 10 | // workaround for really long messages not scrolling 11 | // if last message is too long, use scroll position bottom for better appearance, else use top 12 | // possibly a UIKit bug, see #480 on GitHub 13 | NSUInteger finalRow = MAX(0, [self numberOfRowsInSection:0]-1); 14 | NSIndexPath *finalIndexPath = [NSIndexPath indexPathForRow:finalRow inSection:0]; 15 | 16 | [self wb_scrollToIndexPath:finalIndexPath atScrollPosition:UITableViewScrollPositionBottom Animated:animated]; 17 | } 18 | 19 | - (void)wb_scrollToIndexPath:(NSIndexPath*)indexPath Animated:(BOOL)animated{ 20 | 21 | [self wb_scrollToIndexPath:indexPath atScrollPosition:UITableViewScrollPositionBottom Animated:animated]; 22 | 23 | } 24 | 25 | - (void)wb_scrollToIndexPath:(NSIndexPath *)indexPath atScrollPosition:(UITableViewScrollPosition)postion Animated:(BOOL)animated{ 26 | 27 | 28 | if ([self numberOfSections] == 0) { 29 | return; 30 | } 31 | 32 | if ([self numberOfRowsInSection:0] == 0) { 33 | return; 34 | } 35 | 36 | // CGFloat tableViewContentHeight = self.contentSize.height; 37 | // BOOL isContentTooSmall = (tableViewContentHeight < CGRectGetHeight(self.frame)); 38 | // if (isContentTooSmall) { 39 | // // workaround for the first few messages not scrolling 40 | // // when the collection view content size is too small, `scrollToItemAtIndexPath:` doesn't work properly 41 | // // this seems to be a UIKit bug, see #256 on GitHub 42 | // [self scrollRectToVisible:CGRectMake(0.0, tableViewContentHeight - 1.0f, 1.0f, 1.0f) 43 | // animated:animated]; 44 | // return; 45 | // } 46 | 47 | 48 | [self scrollToRowAtIndexPath:indexPath atScrollPosition:postion animated:animated]; 49 | 50 | } 51 | 52 | @end 53 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ChatUI/Chat/Tool/WBChatCellConfig.h: -------------------------------------------------------------------------------- 1 | // 2 | // WBChatCellConfig.h 3 | // WBChat 4 | // 5 | // Created by RedRain on 2018/1/19. 6 | // Copyright © 2018年 RedRain. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "WBConst.h" 11 | #import "WBImageLoad.h" 12 | 13 | @interface WBChatCellConfig : NSObject 14 | 15 | + (instancetype)sharedInstance; 16 | 17 | @property (nonatomic, strong) WBImageLoad *imageLoad; 18 | @property (nonatomic, strong) UIImage *placeholdHeaderImage; 19 | @property (nonatomic, strong) UIImage *placeholdImage; 20 | 21 | @property (nonatomic, assign) CGFloat normalSpace; ///< 控件间的距离 默认: 5 22 | 23 | 24 | @property (nonatomic, assign) CGSize headerImageSize; ///< 头像大小: 默认:{50,50} 25 | @property (nonatomic, assign) CGFloat headerMarginSpace; ///< 头像距离屏幕边界的距离: 默认:15 26 | @property (nonatomic, assign) CGFloat headerBubbleSpace; ///< 头像和气泡的距离 默认: 12 27 | 28 | 29 | @property (nonatomic, assign) CGSize userNameSize; ///< 展示的用户名称 默认: {200,15} 30 | 31 | @property (nonatomic, assign) CGSize messageStatusIconSize; ///< 消息的状态图片 默认: {20,20} 32 | @property (nonatomic, assign) CGFloat messageStatusIconToBubble; ///< 状态图片和气泡的距离 默认: 5 33 | 34 | @property (nonatomic, assign) CGSize messageStatusLabelSize; ///< 消息的状态文字 默认: {40,20} 35 | @property (nonatomic, assign) CGFloat messageStatusLabelToBubble; ///< 消息的状态文字和气泡的距离 默认: 5 36 | 37 | @property (nonatomic, strong) UIFont *timeFont; // 默认使用字体: 12 38 | 39 | 40 | // 文字消息相关 41 | @property (nonatomic, strong) UIFont *textFont; // 默认使用字体: 17 42 | @property (nonatomic, assign) UIEdgeInsets textbubbleContentInset; ///< 文本气泡内部文字距离气泡边界的距离 43 | @property (nonatomic, assign) CGFloat bubbleClosedAngleWidth; ///< 气泡前面尖角的宽度 默认: 5 44 | @property (nonatomic, assign) CGFloat textMaxWidth; ///< 文本的最大宽度 45 | 46 | // 图片消息相关 47 | @property (nonatomic, assign) CGSize imageProgressSize; 48 | 49 | // 语音相关 50 | @property (nonatomic, assign) CGSize voiceWaveSize; 51 | 52 | @end 53 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ChatUI/Chat/Tool/WBChatCellConfig.m: -------------------------------------------------------------------------------- 1 | // 2 | // WBChatCellConfig.m 3 | // WBChat 4 | // 5 | // Created by RedRain on 2018/1/19. 6 | // Copyright © 2018年 RedRain. All rights reserved. 7 | // 8 | 9 | #import "WBChatCellConfig.h" 10 | #import "UIImage+WBImage.h" 11 | 12 | @implementation WBChatCellConfig 13 | 14 | + (instancetype)sharedInstance { 15 | static WBChatCellConfig *_sharedWBChatCellConfig = nil; 16 | static dispatch_once_t onceToken; 17 | dispatch_once(&onceToken, ^{ 18 | _sharedWBChatCellConfig = [[WBChatCellConfig alloc] init]; 19 | }); 20 | 21 | return _sharedWBChatCellConfig; 22 | } 23 | 24 | - (instancetype)init 25 | { 26 | self = [super init]; 27 | if (self) { 28 | self.imageLoad = [[WBImageLoad alloc] init]; 29 | self.placeholdHeaderImage = [UIImage wb_resourceImageNamed:@"header_male"]; 30 | self.placeholdImage = [UIImage wb_resourceImageNamed:@"Placeholder_Image"]; 31 | 32 | self.headerImageSize = CGSizeMake(43, 43); 33 | self.headerMarginSpace = 15; 34 | self.headerBubbleSpace = 12; 35 | self.textbubbleContentInset = UIEdgeInsetsMake(13, 6, 13, 6); 36 | self.bubbleClosedAngleWidth = 5; 37 | self.userNameSize = CGSizeMake(200, 15); 38 | self.timeFont = [UIFont systemFontOfSize:12]; 39 | self.textFont = [UIFont systemFontOfSize:15]; 40 | 41 | CGFloat screenWidth = [UIScreen mainScreen].bounds.size.width; 42 | self.textMaxWidth = ((screenWidth < 375) ? 190 : ceil(screenWidth - 2 * 50 - 5 - 2 * 13)); 43 | 44 | self.normalSpace = 5; 45 | self.messageStatusIconSize = CGSizeMake(20, 20); 46 | self.messageStatusIconToBubble = 5; 47 | 48 | self.messageStatusLabelSize = CGSizeMake(40, 20); 49 | self.messageStatusLabelToBubble = 5; 50 | 51 | 52 | self.imageProgressSize = CGSizeMake(20, 20); 53 | 54 | self.voiceWaveSize = CGSizeMake(16, 16); 55 | } 56 | return self; 57 | } 58 | 59 | @end 60 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ChatUI/Chat/Tool/WBShowBigImageTool.h: -------------------------------------------------------------------------------- 1 | // 2 | // WBShowBigImageView.h 3 | // WBChat 4 | // 5 | // Created by RedRain on 2018/3/1. 6 | // Copyright © 2018年 RedRain. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface WBShowBigImageTool : NSObject 12 | + (void)showWithImage:(UIImage *)image orgFrame:(CGRect)orgFrame; 13 | @end 14 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ChatUI/Chat/Tool/WBShowBigImageTool.m: -------------------------------------------------------------------------------- 1 | // 2 | // WBShowBigImageView.m 3 | // WBChat 4 | // 5 | // Created by RedRain on 2018/3/1. 6 | // Copyright © 2018年 RedRain. All rights reserved. 7 | // 8 | 9 | #import "WBShowBigImageTool.h" 10 | @interface WBShowBigImageTool () 11 | @property (nonatomic, strong) UIImage *image; 12 | @property (nonatomic, assign) CGRect tempFrame; 13 | @property (strong, nonatomic) UIView *backView; 14 | @property (strong, nonatomic) UIImageView *actionImageView; 15 | 16 | @end 17 | 18 | 19 | @implementation WBShowBigImageTool 20 | 21 | + (instancetype)sharedInstance { 22 | static WBShowBigImageTool *_sharedInstance = nil; 23 | static dispatch_once_t onceToken; 24 | dispatch_once(&onceToken, ^{ 25 | _sharedInstance = [WBShowBigImageTool new]; 26 | }); 27 | 28 | return _sharedInstance; 29 | } 30 | 31 | 32 | + (void)showWithImage:(UIImage *)image orgFrame:(CGRect)orgFrame{ 33 | WBShowBigImageTool *view = [WBShowBigImageTool sharedInstance]; 34 | view.tempFrame = orgFrame; 35 | view.image = image; 36 | [view showPic]; 37 | } 38 | 39 | - (instancetype)init 40 | { 41 | self = [super init]; 42 | if (self) { 43 | 44 | } 45 | return self; 46 | } 47 | 48 | - (void)showPic{ 49 | [UIApplication sharedApplication].statusBarHidden = YES; 50 | 51 | _backView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height)]; 52 | _backView.backgroundColor = [UIColor blackColor]; 53 | [_backView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(backTapAction)]]; 54 | [[UIApplication sharedApplication].keyWindow addSubview:_backView]; 55 | 56 | _actionImageView = [[UIImageView alloc] initWithImage:self.image]; 57 | _actionImageView.frame = self.tempFrame; 58 | _actionImageView.contentMode = UIViewContentModeScaleAspectFit; 59 | 60 | [[UIApplication sharedApplication].keyWindow addSubview:_actionImageView]; 61 | [UIView animateWithDuration:.3 animations:^{ 62 | CGFloat fixelW = CGImageGetWidth(self.actionImageView.image.CGImage); 63 | CGFloat fixelH = CGImageGetHeight(self.actionImageView.image.CGImage); 64 | self.actionImageView.frame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, fixelH * [UIScreen mainScreen].bounds.size.width / fixelW); 65 | self.actionImageView.center = self.backView.center; 66 | }]; 67 | } 68 | 69 | - (void)backTapAction{ 70 | [UIApplication sharedApplication].statusBarHidden = NO; 71 | [UIView animateWithDuration:.2 animations:^{ 72 | self.actionImageView.frame = self.tempFrame; 73 | self.backView.alpha = .3; 74 | } completion:^(BOOL finished) { 75 | [self.backView removeFromSuperview]; 76 | [self.actionImageView removeFromSuperview]; 77 | }]; 78 | } 79 | 80 | @end 81 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ChatUI/Chat/Tool/WBVoicePlayer.h: -------------------------------------------------------------------------------- 1 | // 2 | // WBVoicePlayer.h 3 | // WBChat 4 | // 5 | // Created by RedRain on 2018/2/24. 6 | // Copyright © 2018年 RedRain. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface WBVoicePlayer : NSObject 12 | + (instancetype)player; 13 | 14 | - (void)playVoiceWithPath:(NSString *)path complete:(void (^)(BOOL finished))complete; 15 | 16 | - (void)stopPlayingAudio; 17 | @end 18 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ChatUI/Chat/Views/WBImageBrowser/WBImageBrowserCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // WBImageBrowserCell.m.h 3 | // WBChat 4 | // 5 | // Created by RedRain on 2018/1/16. 6 | // Copyright © 2018年 RedRain. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface WBImageBrowserCell : UICollectionViewCell 12 | 13 | @property (strong, nonatomic) UIScrollView *imageScrollView; 14 | @property (strong, nonatomic) UIImageView *imageImageView; 15 | 16 | @property (nonatomic, copy) void (^singleTapBlock)(void); 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ChatUI/Chat/Views/WBImageBrowser/WBImageBrowserCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // WBImageBrowserCell.m 3 | // WBChat 4 | // 5 | // Created by RedRain on 2018/1/16. 6 | // Copyright © 2018年 RedRain. All rights reserved. 7 | // 8 | 9 | #import "WBImageBrowserCell.h" 10 | 11 | @interface WBImageBrowserCell () 12 | 13 | @end; 14 | 15 | @implementation WBImageBrowserCell 16 | 17 | 18 | - (instancetype)initWithFrame:(CGRect)frame { 19 | self = [super initWithFrame:frame]; 20 | if (self) { 21 | self.imageScrollView = [[UIScrollView alloc] initWithFrame:[UIScreen mainScreen].bounds]; 22 | self.imageScrollView.maximumZoomScale = 3.0; 23 | self.imageScrollView.minimumZoomScale = 1; 24 | self.imageScrollView.showsHorizontalScrollIndicator = NO; 25 | self.imageScrollView.showsVerticalScrollIndicator = NO; 26 | self.imageScrollView.delegate = self; 27 | [self.contentView addSubview:self.imageScrollView]; 28 | 29 | self.imageImageView = [[UIImageView alloc] initWithFrame:[UIScreen mainScreen].bounds]; 30 | self.imageImageView.contentMode = UIViewContentModeScaleAspectFit; 31 | [self.imageScrollView addSubview:self.imageImageView]; 32 | 33 | 34 | 35 | // 添加手势 36 | UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(singleTapAction:)]; 37 | [self.imageScrollView addGestureRecognizer:singleTap]; 38 | 39 | UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(doubleTapAction:)]; 40 | doubleTap.numberOfTapsRequired = 2; 41 | [self.imageScrollView addGestureRecognizer:doubleTap]; 42 | 43 | [singleTap requireGestureRecognizerToFail:doubleTap]; 44 | 45 | 46 | } 47 | return self; 48 | } 49 | 50 | - (void)layoutSubviews{ 51 | [super layoutSubviews]; 52 | 53 | self.imageScrollView.frame = [UIScreen mainScreen].bounds; 54 | self.imageImageView.frame = [UIScreen mainScreen].bounds; 55 | } 56 | 57 | #pragma mark - UIScrollViewDelegate 58 | - (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView { 59 | return scrollView.subviews[0]; 60 | } 61 | 62 | 63 | #pragma mark - Action 64 | - (void)singleTapAction:(UITapGestureRecognizer *)tap { 65 | 66 | if (self.singleTapBlock) { 67 | self.singleTapBlock(); 68 | } 69 | 70 | } 71 | 72 | - (void)doubleTapAction:(UITapGestureRecognizer *)tap { 73 | 74 | CGFloat scale = self.imageScrollView.zoomScale == 1 ? 3 : 1; 75 | CGRect zoomRect = [self zoomRectForScale:scale withCenter:[tap locationInView:tap.view]]; 76 | [self.imageScrollView zoomToRect:zoomRect animated:YES]; 77 | } 78 | 79 | #pragma mark - Private Methods 80 | // 双击时的中心点 81 | - (CGRect)zoomRectForScale:(float)scale withCenter:(CGPoint)center { 82 | CGRect zoomRect = CGRectZero; 83 | zoomRect.size.height = self.imageScrollView.frame.size.height / scale; 84 | zoomRect.size.width = self.imageScrollView.frame.size.width / scale; 85 | zoomRect.origin.x = center.x - (zoomRect.size.width / 2.0); 86 | zoomRect.origin.y = center.y - (zoomRect.size.height / 2.0); 87 | return zoomRect; 88 | } 89 | 90 | 91 | @end 92 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ChatUI/Chat/Views/WBImageBrowser/WBImageBrowserView.h: -------------------------------------------------------------------------------- 1 | // 2 | // WBImageBrowserView.h 3 | // WBChat 4 | // 5 | // Created by RedRain on 2018/1/16. 6 | // Copyright © 2018年 RedRain. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface WBImageBrowserView : UIView 12 | 13 | + (instancetype)browserWithImageArray:(NSArray *)imageModelArray; 14 | 15 | @property (nonatomic, assign) NSInteger startIndex; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ChatUI/Chat/WBChatViewController+Extension.h: -------------------------------------------------------------------------------- 1 | // 2 | // WBChatViewController+Extension.h 3 | // AVOSCloud 4 | // 5 | // Created by RedRain on 2018/3/15. 6 | // 7 | 8 | #import 9 | #import "WBChatViewController.h" 10 | 11 | @interface WBChatViewController (Extension) 12 | 13 | /** 14 | tableView是否在最底部 15 | */ 16 | - (BOOL)isTableViewBottomVisible; 17 | 18 | 19 | /** 20 | 向给定的消息数组中增加 `时间model` 21 | 22 | @param localMessages 给定的messageCellModel 23 | @return 添加完`时间model`的数组 24 | */ 25 | - (NSMutableArray *)appendTimerStampIntoMessageArray:(NSArray *)localMessages; 26 | 27 | 28 | /** 29 | 单独插入一条message到tableView中 30 | */ 31 | - (void)appendAMessageToTableView:(WBMessageModel *)aMessage; 32 | 33 | /** 34 | 刷新一条消息的状态 35 | 36 | @param aMessage 需要被属性的message 37 | */ 38 | - (void)refershAMessageState:(WBMessageModel *)aMessage; 39 | 40 | /** 41 | 下拉刷新时, 加载更多消息 42 | */ 43 | - (void)loadMoreMessage; 44 | @end 45 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ChatUI/Chat/WBChatViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // WBChatViewController.h 3 | // WBChat 4 | // 5 | // Created by RedRain on 2018/1/16. 6 | // Copyright © 2018年 RedRain. All rights reserved. 7 | // 8 | 9 | #import "WBBaseController.h" 10 | #import "WBServiceSDKHeaders.h" 11 | #import "WBChatBarView.h" 12 | #import "WBSelectPhotoTool.h" 13 | #import "WBChatMessageBaseCell.h" 14 | 15 | @class WBChatMessageBaseCellModel; 16 | @class WBChatMessageBaseCell; 17 | @protocol WBChatBarViewDelegate; 18 | /****************************************************************************************** 19 | ************************ 子类可能需要可以实现方法, 方便自定义消息等操作 ************************ 20 | *****************************************************************************************/ 21 | @protocol WBChatViewControllerSubclassing 22 | 23 | @optional 24 | 25 | /** 26 | 子类实现的cell 27 | */ 28 | - (UITableViewCell *)wb_controllerTableView:(UITableView *)table cellForRowAtIndexPath:(NSIndexPath *)indexPath; 29 | 30 | /** 31 | 在cell提供给tableView之前, 再次提供给子类修改的机会, 32 | -tableView:cellForRowAtIndexPath 返回之前 33 | 34 | @param cell 即将提供给tableView的cell 35 | */ 36 | - (void)wb_willDisplayMessageCell:(WBChatMessageBaseCell *)cell atIndexPath:(NSIndexPath *)indexPath; 37 | 38 | @end 39 | 40 | /****************************************************************************************** 41 | ************************ WBChatViewController ************************ 42 | *****************************************************************************************/ 43 | @interface WBChatViewController : WBBaseController 44 | 46 | 47 | /** 48 | 会话对象 49 | */ 50 | @property (nonatomic, strong) AVIMConversation *conversation; 51 | 52 | /** 53 | 存放消息列表的数组 54 | */ 55 | @property (nonatomic, strong) NSMutableArray *dataArray; 56 | 57 | 58 | /** 59 | 从最近联系人列表进入到聊天界面 60 | 61 | @param conversation 会话镀锡 62 | @return 控制器对象 63 | */ 64 | + (instancetype)createWithConversation:(AVIMConversation *)conversation; 65 | 66 | 67 | 68 | /** 69 | 发送消息. 70 | 此方法的行为: 71 | 1.判断这条消息和上一条消息的关系后(间隔3分钟),决定是否插入时间 72 | 2.tableView滚动到最底部 73 | 3.发送消息后, 根据回执刷新对应的消息 74 | 75 | @param message 消息模型,保存 76 | */ 77 | - (void)sendMessage:(WBMessageModel *)message; 78 | 79 | @end 80 | 81 | 82 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ChatUI/ChatList/Cell/WBChatListCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // WBChatListCell.h 3 | // WBChat 4 | // 5 | // Created by RedRain on 2017/12/11. 6 | // Copyright © 2017年 RedRain. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "WBChatListCellModel.h" 11 | 12 | @interface WBChatListCell : UITableViewCell 13 | 14 | @property (nonatomic, strong) WBChatListCellModel *cellModel; 15 | 16 | /** 17 | 创建cell, cell的复用逻辑已经实现, 使用类名作为唯一标识ID 18 | */ 19 | + (instancetype)cellWithTableView:(UITableView *)tableView; 20 | 21 | 22 | /** 23 | cell的高度 24 | */ 25 | + (CGFloat)cellHeight; 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ChatUI/ChatList/Model/WBChatListCellModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // WBChatListCellModel.h 3 | // WBChat 4 | // 5 | // Created by RedRain on 2017/12/11. 6 | // Copyright © 2017年 RedRain. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "WBConfig.h" 11 | 12 | @interface WBChatListCellModel : NSObject 13 | 14 | @property (nonatomic, assign) CGRect chatUserHeaderViewF; 15 | @property (nonatomic, assign) CGRect chatTitleF; 16 | @property (nonatomic, assign) CGRect chatMessageF; 17 | @property (nonatomic, assign) CGRect chatTimeF; 18 | @property (nonatomic, assign) CGRect cutLineF; 19 | @property (nonatomic, assign) CGRect unreadBadgeBtnF; 20 | 21 | 22 | 23 | @property (nonatomic, copy) NSAttributedString *lastMessageString; 24 | @property (nonatomic, copy) NSString *title; 25 | 26 | @property (nonatomic, strong) WBChatListModel *dataModel; 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ChatUI/ChatList/Views/WBBadgeButton.h: -------------------------------------------------------------------------------- 1 | // 2 | // WBBadgeButton.h 3 | 4 | #import 5 | 6 | @interface WBBadgeButton : UIButton 7 | @property (nonatomic, copy) NSString* badgeValue; 8 | 9 | 10 | @end 11 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ChatUI/ChatList/Views/WBBadgeButton.m: -------------------------------------------------------------------------------- 1 | // 2 | // WBBadgeButton.m 3 | 4 | 5 | #import "WBBadgeButton.h" 6 | #import "UIImage+WBImage.h" 7 | @implementation WBBadgeButton 8 | 9 | - (instancetype)initWithFrame:(CGRect)frame 10 | { 11 | self = [super initWithFrame:frame]; 12 | if (self) { 13 | self.hidden = YES; 14 | self.userInteractionEnabled = NO; 15 | self.titleLabel.textAlignment = NSTextAlignmentCenter; 16 | self.contentMode = UIViewContentModeScaleAspectFit; 17 | self.layer.cornerRadius = CGRectGetWidth(frame)/2; 18 | self.layer.masksToBounds = YES; 19 | self.titleLabel.font = [UIFont systemFontOfSize:12]; 20 | } 21 | return self; 22 | } 23 | -(void)setBadgeValue:(NSString *)badgeValue { 24 | _badgeValue = [badgeValue copy]; 25 | 26 | if (badgeValue && [badgeValue intValue] != 0 ) { 27 | 28 | self.hidden = NO; 29 | NSString *imageName; 30 | if ([badgeValue integerValue] > 99) { 31 | badgeValue = @""; 32 | imageName = @"CloudChatList_badge_dot"; 33 | } else { 34 | imageName = @"CloudChatList_badge"; 35 | } 36 | [self setBackgroundImage:[UIImage wb_resourceImageNamed:imageName] forState:UIControlStateNormal]; 37 | 38 | NSString *text = [NSString stringWithFormat:@"%@",badgeValue]; 39 | [self setTitle:text forState:UIControlStateNormal]; 40 | 41 | }else { 42 | 43 | self.hidden = YES; 44 | } 45 | } 46 | 47 | @end 48 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ChatUI/ChatList/WBChatListController.h: -------------------------------------------------------------------------------- 1 | // 2 | // WBChatListController.h 3 | // WBChat 4 | // 5 | // Created by RedRain on 2017/11/17. 6 | // Copyright © 2017年 RedRain. All rights reserved. 7 | // 8 | 9 | #import "WBBaseController.h" 10 | @class WBChatListCellModel; 11 | @interface WBChatListController : WBBaseController 12 | @property (nonatomic, strong) NSMutableArray *dataArray; 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Extra/Base/WBBaseController.h: -------------------------------------------------------------------------------- 1 | // 2 | // RRBaseController.h 3 | // Whiteboard 4 | // 5 | // Created by RedRain on 2017/11/5. 6 | // Copyright © 2017年 RedRain. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "WBConfig.h" 11 | 12 | @interface WBBaseController : UIViewController 13 | 14 | @property (nonatomic, strong) UITableView *tableView; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Extra/Base/WBBaseController.m: -------------------------------------------------------------------------------- 1 | // 2 | // RRBaseController.m 3 | // Whiteboard 4 | // 5 | // Created by RedRain on 2017/11/5. 6 | // Copyright © 2017年 RedRain. All rights reserved. 7 | // 8 | 9 | #import "WBBaseController.h" 10 | #import "WBConfig.h" 11 | 12 | @interface WBBaseController () 13 | 14 | 15 | @end 16 | 17 | @implementation WBBaseController 18 | - (void)dealloc{ 19 | [WBNotificationCenter removeObserver:self]; 20 | } 21 | - (void)viewDidLoad { 22 | [super viewDidLoad]; 23 | // Do any additional setup after loading the view. 24 | self.view.backgroundColor = [UIColor whiteColor]; 25 | self.automaticallyAdjustsScrollViewInsets = NO; 26 | } 27 | 28 | - (void)didReceiveMemoryWarning { 29 | [super didReceiveMemoryWarning]; 30 | // Dispose of any resources that can be recreated. 31 | } 32 | 33 | #pragma mark - Life Cycle 34 | #pragma mark - UITableViewDelegate 35 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ 36 | return 0; 37 | } 38 | 39 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ 40 | return [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"DefaultCell"]; 41 | } 42 | 43 | #pragma mark - CustomDelegate 44 | 45 | #pragma mark - Event Response 46 | #pragma mark - Private Methods 47 | #pragma mark - Public Methods 48 | #pragma mark - Getters and Setters 49 | - (UITableView *)tableView{ 50 | if (!_tableView) { 51 | CGRect frame =[UIScreen mainScreen].bounds; 52 | _tableView = [[UITableView alloc] initWithFrame:frame style:UITableViewStylePlain]; 53 | 54 | _tableView.backgroundColor = [UIColor clearColor]; 55 | _tableView.dataSource = self; 56 | _tableView.delegate = self; 57 | _tableView.autoresizingMask = UIViewAutoresizingNone; 58 | _tableView.tableFooterView = [UIView new]; 59 | _tableView.separatorStyle = UITableViewCellSeparatorStyleNone; 60 | 61 | if (@available(iOS 11.0, *)) { 62 | _tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever; 63 | } else { 64 | // Fallback on earlier versions 65 | } 66 | 67 | 68 | } 69 | return _tableView; 70 | } 71 | 72 | @end 73 | 74 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Extra/Category/Date/NSDate+Extension.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSDate+Extension.h 3 | // CMBMobileBank 4 | // 5 | // Created by Jason Ding on 15/12/8. 6 | // Copyright © 2015年 efetion. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSDate (Extension) 12 | 13 | /** 14 | 会话列表的时间格式 15 | 16 | 今天: HH:mm 17 | 昨天: 昨天 18 | 其余: MM月dd日 19 | 20 | @return 格式化后的字符床 21 | */ 22 | - (NSString *)wb_chatListTimeString; 23 | 24 | 25 | - (BOOL)wb_isThisYear; 26 | - (BOOL)wb_isYesterday; 27 | - (BOOL)wb_isToday; 28 | + (BOOL)wb_miniteInterval:(NSInteger)miniteInterval firstTime:(long long)firstTime secondTime:(long long)secondTime; 29 | @end 30 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Extra/Category/NSString/NSString+OPSize.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+OPSize.h 3 | // LCGOptimusPrime 4 | // 5 | // Created by RedRain on 2017/8/9. 6 | // Copyright © 2017年 erics. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSString (OPSize) 12 | - (CGSize)lcg_sizeWithFont:(UIFont *)font maxW:(CGFloat)maxW; 13 | - (CGSize)lcg_sizeWithFont:(UIFont *)font; 14 | 15 | 16 | /** 17 | 去除字符串收尾空格,以及回车换行符 18 | 19 | @return 处理后的字符串 20 | */ 21 | - (NSString *)lcg_removeWhitespaceAndNewlineCharacterSet; 22 | 23 | /** 24 | 排除自身特殊字符 25 | 26 | @return 处理后的字符串 27 | */ 28 | - (NSString *)lcg_filterSpecialStr; 29 | 30 | 31 | - (BOOL)isLegalExpressCode:(NSString *)expressCode; 32 | 33 | - (NSString *)wb_MD5String; 34 | 35 | - (NSMutableAttributedString *)wb_makeSearchString:(NSString *)search color:(UIColor *)color; 36 | @end 37 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Extra/Category/UIImage/UIImage+WBImage.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+WBImage.h 3 | // WBChat 4 | // 5 | // Created by RedRain on 2018/1/19. 6 | // Copyright © 2018年 RedRain. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIImage (WBImage) 12 | 13 | /** 14 | 获取到用户默认头像 15 | */ 16 | + (UIImage *)wb_userHeaderPlaceholderImage; 17 | 18 | /** 19 | 根据图片名称, 去WBUI.bundle中获取图片 20 | */ 21 | + (UIImage *)wb_resourceImageNamed:(NSString *)name; 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Extra/Category/UIImage/UIImage+WBImage.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+WBImage.m 3 | // WBChat 4 | // 5 | // Created by RedRain on 2018/1/19. 6 | // Copyright © 2018年 RedRain. All rights reserved. 7 | // 8 | 9 | #import "UIImage+WBImage.h" 10 | #import "WBBaseController.h" 11 | @implementation UIImage (WBImage) 12 | 13 | + (UIImage *)wb_userHeaderPlaceholderImage{ 14 | return [self wb_resourceImageNamed:@"header_male"]; 15 | } 16 | + (UIImage *)wb_resourceImageNamed:(NSString *)name{ 17 | //先从默认目录里读 18 | UIImage *imageFromMainBundle = [UIImage imageNamed:name]; 19 | if (imageFromMainBundle) { 20 | return imageFromMainBundle; 21 | } 22 | //读不到再去Bundle里读 23 | //此处Scale是判断图片是@2x还是@3x 24 | NSInteger scale = (NSInteger)[[UIScreen mainScreen] scale]; 25 | for (NSInteger i = scale; i >= 1; i--) { 26 | NSString *filepath = [self getImagePath:name scale:i]; 27 | UIImage *tempImage = [UIImage imageWithContentsOfFile:filepath]; 28 | if (tempImage) { 29 | return tempImage; 30 | } 31 | } 32 | return nil; 33 | } 34 | 35 | + (NSString *)getImagePath:(NSString *)name scale:(NSInteger)scale{ 36 | static NSBundle *resBundle = nil; 37 | if (resBundle == nil) { 38 | // 这里不使用mainBundle是为了适配pod 1.x和0.x 39 | resBundle = [self bundleUrlWithResourcsName:@"WBUI"]; 40 | } 41 | NSBundle *customBundle = resBundle; 42 | NSString *bundlePath = [customBundle bundlePath]; 43 | NSString *imgPath = [bundlePath stringByAppendingPathComponent:name]; 44 | NSString *pathExtension = [imgPath pathExtension]; 45 | //没有后缀加上PNG后缀 46 | if (!pathExtension || pathExtension.length == 0) { 47 | pathExtension = @"png"; 48 | } 49 | //Scale是根据屏幕不同选择使用@2x还是@3x的图片 50 | NSString *imageName = nil; 51 | if (scale == 1) { 52 | imageName = [NSString stringWithFormat:@"%@.%@", [[imgPath lastPathComponent] stringByDeletingPathExtension], pathExtension]; 53 | } 54 | else { 55 | imageName = [NSString stringWithFormat:@"%@@%ldx.%@", [[imgPath lastPathComponent] stringByDeletingPathExtension], (long)scale, pathExtension]; 56 | } 57 | //返回删掉旧名称加上新名称的路径 58 | return [[imgPath stringByDeletingLastPathComponent] stringByAppendingPathComponent:imageName]; 59 | } 60 | 61 | + (NSBundle *)bundleUrlWithResourcsName:(NSString *)name{ 62 | return [NSBundle bundleWithPath:[[NSBundle bundleForClass:[WBBaseController class]] pathForResource:name ofType:@"bundle"]]; 63 | } 64 | @end 65 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Extra/Category/UIView/UIView+Frame/UIView+Frame.h: -------------------------------------------------------------------------------- 1 | /* 2 | Erica Sadun, http://ericasadun.com 3 | iPhone Developer's Cookbook, 3.0 Edition 4 | BSD License, Use at your own risk 5 | */ 6 | 7 | #import 8 | 9 | CGPoint CGRectGetCenter(CGRect rect); 10 | CGRect CGRectMoveToCenter(CGRect rect, CGPoint center); 11 | 12 | @interface UIView (ViewFrameGeometry) 13 | 14 | @property CGPoint origin_wb; 15 | @property CGSize size_wb; 16 | 17 | @property (readonly) CGPoint bottomLeft_wb; 18 | @property (readonly) CGPoint bottomRight_wb; 19 | @property (readonly) CGPoint topRight_wb; 20 | 21 | @property(nonatomic,assign)CGFloat width_wb; 22 | @property(nonatomic,assign)CGFloat height_wb; 23 | 24 | @property CGFloat top_wb; 25 | @property CGFloat left_wb; 26 | 27 | @property CGFloat bottom_wb; 28 | @property CGFloat right_wb; 29 | 30 | //中心点的x与y 31 | @property (nonatomic, assign) CGFloat centerX_wb; 32 | @property (nonatomic, assign) CGFloat centerY_wb; 33 | 34 | 35 | 36 | - (void) moveBy_wb: (CGPoint) delta; 37 | - (void) scaleBy_wb: (CGFloat) scaleFactor; 38 | - (void) fitInSize_wb: (CGSize) aSize; 39 | 40 | - (void) wb_addRorationAnimaitonInLayer; 41 | @end 42 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Extra/Category/UIView/UIView+NextResponder/UIView+NextResponder.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+NextResponder.h 3 | // IOSStudy 4 | // 5 | // Created by gtexpress on 15/3/20. 6 | // Copyright (c) 2015年 ETHAN_chenliang. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //获取UIView当前所在控制器 12 | @interface UIView (NextResponder) 13 | 14 | - (UIViewController *)lcg_viewController; 15 | 16 | 17 | /** 18 | 使用Xib创建View, 需要xib文件和类名一致. 19 | 20 | @return view实例 21 | */ 22 | + (instancetype)lcg_viewFromXib; 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Extra/Category/UIView/UIView+NextResponder/UIView+NextResponder.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+NextResponder.m 3 | // IOSStudy 4 | // 5 | // Created by gtexpress on 15/3/20. 6 | // Copyright (c) 2015年 ETHAN_chenliang. All rights reserved. 7 | // 8 | 9 | #import "UIView+NextResponder.h" 10 | 11 | @implementation UIView (NextResponder) 12 | 13 | //获取上一级响应者 14 | - (UIViewController *)lcg_viewController 15 | { 16 | UIResponder *next = self.nextResponder; 17 | while (next != nil) { 18 | if ([next isKindOfClass:[UIViewController class]]) { 19 | return (UIViewController *)next; 20 | } 21 | next = next.nextResponder; 22 | } 23 | return nil; 24 | } 25 | 26 | + (instancetype)lcg_viewFromXib{ 27 | return [[NSBundle mainBundle] loadNibNamed:NSStringFromClass(self) owner:nil options:nil].firstObject; 28 | } 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Extra/Config/WBConfig.h: -------------------------------------------------------------------------------- 1 | // 2 | // WBConfig.pch 3 | // Whiteboard 4 | // 5 | // Created by RedRain on 2017/11/5. 6 | // Copyright © 2017年 RedRain. All rights reserved. 7 | // 8 | 9 | #ifndef WBConfig_pch 10 | #define WBConfig_pch 11 | 12 | // 第三方库, 要放在最上面 13 | #import "WBHUD.h" 14 | 15 | #if __has_include() 16 | #import 17 | #else 18 | #import "AVOSCloud.h" 19 | #endif 20 | 21 | #if __has_include() 22 | #import 23 | #else 24 | #import "AVOSCloudIM.h" 25 | #endif 26 | 27 | // 分类 28 | #import "WBConst.h" 29 | 30 | #import "UIView+Frame.h" 31 | #import "NSString+OPSize.h" 32 | #import "UIView+NextResponder.h" 33 | #import "NSDate+Extension.h" 34 | 35 | 36 | // 工具类 37 | #import "WBTools.h" 38 | 39 | #import "WBServiceSDKHeaders.h" 40 | 41 | 42 | 43 | #endif /* WBConfig_pch */ 44 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Extra/Config/WBConst.h: -------------------------------------------------------------------------------- 1 | // 2 | // WBConst.h 3 | // Whiteboard 4 | // 5 | // Created by RedRain on 2017/11/5. 6 | // Copyright © 2017年 RedRain. All rights reserved. 7 | // 8 | 9 | #ifndef WBConst_h 10 | #define WBConst_h 11 | 12 | 13 | #define kBoardHoldImage [UIImage imageNamed:@"star_bg"] 14 | #define kUserHeaderHoldImage [UIImage wb_resourceImageNamed:@"header_male"] 15 | #define kWBScreenWidth ([UIScreen mainScreen].bounds.size.width) 16 | #define kWBScreenHeight ([UIScreen mainScreen].bounds.size.height) 17 | #define kWBNavigationBarHeight (64) 18 | #define kWBSearchBarHeightHeight (55) 19 | #define WBNotificationCenter [NSNotificationCenter defaultCenter] 20 | #define WBRGBA(r,g,b,a) [UIColor colorWithRed:r/255.0 green:g/255.0 blue:b/255.0 alpha:a] 21 | 22 | #define WB_IS_IPHONE_X (fabs((double)[[ UIScreen mainScreen ] bounds ].size.height - ( double )812)==0) 23 | 24 | #define WB_IPHONEX_TOP_SPACE ((WB_IS_IPHONE_X)?24:0) 25 | 26 | #define WB_IPHONEX_BOTTOM_SPACE ((WB_IS_IPHONE_X)?34:0) 27 | 28 | #define WB_NavHeight (64+WB_IPHONEX_TOP_SPACE) 29 | 30 | #define WB_TabBarHeight (49+WB_IPHONEX_BOTTOM_SPACE) 31 | 32 | //如果有Debug这个宏的话,就允许log输出...可变参数 33 | #ifdef DEBUG 34 | #define WBLog(...) NSLog(__VA_ARGS__) 35 | #else 36 | #define WBLog(...) 37 | #endif 38 | 39 | // 重写对象的debugDescription方法, 方便于控制台打印 40 | #define kWBOverwriteDebugDescription \ 41 | - (NSString *)debugDescription { \ 42 | NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];\ 43 | uint count;\ 44 | objc_property_t *properties = class_copyPropertyList([self class], &count);\ 45 | for(int i = 0; i -- %@",[self class],self,dictionary];\ 53 | } 54 | 55 | #define kWBAlphaNum @"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" 56 | 57 | #define kWBOverwriteCopyWithZone \ 58 | - (id)copyWithZone:(NSZone *)zone{\ 59 | id newOne = [[self class] new];\ 60 | [[OPPropertyListManager shareInstance] setupPropertyValueFromObj:self toObj:newOne];\ 61 | return newOne;\ 62 | } 63 | 64 | 65 | 66 | 67 | /* 68 | 69 | 70 | // 打印属性的值 71 | kWBOverwriteDebugDescription 72 | 73 | // 用户支持 NSCopying 协议 74 | kWBOverwriteCopyWithZone 75 | 76 | */ 77 | 78 | #endif /* WBConst_h */ 79 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Extra/CustomView/HUD/WBHUD.h: -------------------------------------------------------------------------------- 1 | // 2 | // WBHUD.h 3 | // Whiteboard 4 | // 5 | // Created by RedRain on 2017/11/5. 6 | // Copyright © 2017年 RedRain. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface WBHUD : NSObject 12 | 13 | + (void)showMessage:(NSString *)message toView:(UIView *)view; 14 | + (void)hideForView:(UIView *)view; 15 | + (void)showSuccessMessage:(NSString *)message toView:(UIView *)view; 16 | + (void)showErrorMessage:(NSString *)message toView:(UIView *)view; 17 | + (void)progressFromView:(UIView *)view; 18 | @end 19 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Extra/CustomView/HUD/WBHUD.m: -------------------------------------------------------------------------------- 1 | // 2 | // WBHUD.m 3 | // Whiteboard 4 | // 5 | // Created by RedRain on 2017/11/5. 6 | // Copyright © 2017年 RedRain. All rights reserved. 7 | // 8 | 9 | #import "WBHUD.h" 10 | #import "UIView+WBToast.h" 11 | 12 | @implementation WBHUD 13 | 14 | + (void)showMessage:(NSString *)message toView:(UIView *)view{ 15 | [view wb_makeToastActivity]; 16 | [view wb_makeToast:message duration:3 position:CSToastPositionCenter]; 17 | } 18 | 19 | + (void)hideForView:(UIView *)view{ 20 | [view wb_hideToastActivity]; 21 | } 22 | 23 | + (void)createCustomHUDFromView:(UIView *)view{ 24 | 25 | 26 | 27 | } 28 | 29 | + (void)showSuccessMessage:(NSString *)message toView:(UIView *)view{ 30 | 31 | [view wb_hideToastActivity]; 32 | [view wb_makeToast:message duration:3 position:CSToastPositionCenter]; 33 | 34 | 35 | } 36 | + (void)showErrorMessage:(NSString *)message toView:(UIView *)view{ 37 | [self hideForView:view]; 38 | [view wb_makeToast:message duration:3 position:CSToastPositionCenter]; 39 | } 40 | 41 | + (void)progressFromView:(UIView *)view{ 42 | [view wb_makeToastActivity]; 43 | } 44 | 45 | 46 | @end 47 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Extra/CustomView/WBKeyBoard/EmojiBoard/Cell/WBEmojiKeyBoardCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // WBEmojiKeyBoardCell.h 3 | // WBChat 4 | // 5 | // Created by RedRain on 2018/1/24. 6 | // Copyright © 2018年 RedRain. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "WBEmotionPageModel.h" 11 | 12 | @interface WBEmojiKeyBoardCell : UICollectionViewCell 13 | 14 | @property (nonatomic, strong) WBEmotionPageItemModel *cellModel; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Extra/CustomView/WBKeyBoard/EmojiBoard/Cell/WBEmojiKeyBoardCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // WBEmojiKeyBoardCell.m 3 | // WBChat 4 | // 5 | // Created by RedRain on 2018/1/24. 6 | // Copyright © 2018年 RedRain. All rights reserved. 7 | // 8 | 9 | #import "WBEmojiKeyBoardCell.h" 10 | #import "UIImage+WBImage.h" 11 | 12 | @interface WBEmojiKeyBoardCell () 13 | 14 | @property (nonatomic, strong) UIImageView *imageView; 15 | 16 | @property (nonatomic, strong) UILabel *label; 17 | @end 18 | 19 | @implementation WBEmojiKeyBoardCell 20 | - (instancetype)initWithFrame:(CGRect)frame 21 | { 22 | self = [super initWithFrame:frame]; 23 | if (self) { 24 | [self.contentView addSubview:self.imageView]; 25 | [self.contentView addSubview:self.label]; 26 | } 27 | return self; 28 | } 29 | 30 | - (void)layoutSubviews{ 31 | [super layoutSubviews]; 32 | 33 | CGFloat iWidth = 32; 34 | self.imageView.frame = CGRectMake((self.frame.size.width - iWidth) / 2 , (self.frame.size.height - iWidth) / 2, iWidth, iWidth); 35 | self.label.frame = self.imageView.frame; 36 | 37 | } 38 | 39 | - (void)setCellModel:(WBEmotionPageItemModel *)cellModel{ 40 | _cellModel = cellModel; 41 | 42 | 43 | switch (cellModel.type) { 44 | case WBEmotionItemTypeDelete: 45 | { 46 | 47 | [self.imageView setHidden:NO]; 48 | [self.label setHidden:YES]; 49 | [self.imageView setImage:[UIImage wb_resourceImageNamed:@"DeleteEmoticonBtn"]]; 50 | } 51 | break; 52 | case WBEmotionItemTypeEmoji: 53 | { 54 | 55 | [self.imageView setHidden:YES]; 56 | [self.label setHidden:NO]; 57 | [self.label setText:cellModel.name]; 58 | } 59 | break; 60 | 61 | default: 62 | break; 63 | } 64 | } 65 | 66 | - (UIImageView *)imageView 67 | { 68 | if (_imageView == nil) { 69 | _imageView = [[UIImageView alloc] init]; 70 | } 71 | return _imageView; 72 | } 73 | 74 | - (UILabel *)label 75 | { 76 | if (_label == nil) { 77 | _label = [[UILabel alloc] init]; 78 | [_label setFont:[UIFont systemFontOfSize:28.0f]]; 79 | [_label setTextAlignment:NSTextAlignmentCenter]; 80 | } 81 | return _label; 82 | } 83 | 84 | @end 85 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Extra/CustomView/WBKeyBoard/EmojiBoard/EmojiKeyoboardBar/WBEmojiGroupCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // WBEmojiGroupCell.h 3 | // TLChat 4 | // 5 | // Created by 李伯坤 on 16/2/19. 6 | // Copyright © 2016年 李伯坤. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface WBEmojiGroupCell : UICollectionViewCell 12 | 13 | @property (nonatomic, strong) id emojiGroup; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Extra/CustomView/WBKeyBoard/EmojiBoard/EmojiKeyoboardBar/WBEmojiGroupCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // WBEmojiGroupCell.m 3 | // TLChat 4 | // 5 | // Created by 李伯坤 on 16/2/19. 6 | // Copyright © 2016年 李伯坤. All rights reserved. 7 | // 8 | 9 | #import "WBEmojiGroupCell.h" 10 | #import "WBEmotionPageModel.h" 11 | #import "UIImage+WBImage.h" 12 | @interface WBEmojiGroupCell () 13 | 14 | @property (nonatomic, strong) UIImageView *groupIconView; 15 | 16 | @end 17 | 18 | @implementation WBEmojiGroupCell 19 | 20 | - (id)initWithFrame:(CGRect)frame 21 | { 22 | if (self = [super initWithFrame:frame]) { 23 | [self setBackgroundColor:[UIColor clearColor]]; 24 | UIView *selectedView = [[UIView alloc] init]; 25 | selectedView.backgroundColor = [UIColor colorWithRed:(245.0)/255.0f green:245.0/255.0f blue:(247.0)/255.0f alpha:1.0]; 26 | 27 | [self setSelectedBackgroundView:selectedView]; 28 | 29 | [self.contentView addSubview:self.groupIconView]; 30 | 31 | } 32 | return self; 33 | } 34 | - (void)layoutSubviews{ 35 | [super layoutSubviews]; 36 | CGFloat WH = 30; 37 | self.groupIconView.frame = CGRectMake((self.frame.size.width - WH) / 2, (self.frame.size.height - WH) / 2, WH, WH); 38 | } 39 | - (void)setEmojiGroup:(WBEmotionPageModel *)emojiGroup 40 | { 41 | _emojiGroup = emojiGroup; 42 | 43 | self.groupIconView.image = [UIImage wb_resourceImageNamed:emojiGroup.tabImageName]; 44 | } 45 | 46 | #pragma mark - # Private Methods 47 | 48 | 49 | 50 | - (void)drawRect:(CGRect)rect 51 | { 52 | [super drawRect:rect]; 53 | CGContextRef context = UIGraphicsGetCurrentContext(); 54 | CGContextSetLineWidth(context, 0.5); 55 | CGContextSetStrokeColorWithColor(context, [UIColor colorWithWhite:0.5 alpha:0.3].CGColor); 56 | CGContextBeginPath(context); 57 | CGContextMoveToPoint(context, self.frame.size.width - 0.5, 5); 58 | CGContextAddLineToPoint(context, self.frame.size.width - 0.5, self.frame.size.height - 5); 59 | CGContextStrokePath(context); 60 | } 61 | 62 | #pragma mark - Getter - 63 | - (UIImageView *)groupIconView 64 | { 65 | if (_groupIconView == nil) { 66 | _groupIconView = [[UIImageView alloc] init]; 67 | } 68 | return _groupIconView; 69 | } 70 | 71 | @end 72 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Extra/CustomView/WBKeyBoard/EmojiBoard/EmojiKeyoboardBar/WBEmojiGroupControl.h: -------------------------------------------------------------------------------- 1 | // 2 | // WBEmojiGroupControl.h 3 | 4 | #import 5 | 6 | typedef NS_ENUM(NSInteger, WBGroupControlSendButtonStatus) { 7 | WBGroupControlSendButtonStatusGray, 8 | WBGroupControlSendButtonStatusBlue, 9 | WBGroupControlSendButtonStatusNone, 10 | }; 11 | #define WBKeyBoardSCREEN_SIZE_emoji [UIScreen mainScreen].bounds.size 12 | #define WBKeyBoardSCREEN_WIDTH_emoji WBKeyBoardSCREEN_SIZE_emoji.width 13 | #define WBiOSVersion_emoji ([[UIDevice currentDevice].systemVersion doubleValue]) 14 | #define WBNavigationBarHeight_emoji (WBiOSVersion_emoji >= 7.0 ? 64 : 44) 15 | #define WB_IS_IPHONE_X_emoji (fabs((double)[[ UIScreen mainScreen ] bounds ].size.height - ( double )812)==0) 16 | #define WB_IPHONEX_TOP_SPACE_emoji ((WB_IS_IPHONE_X_emoji)?24:0) 17 | #define WB_IPHONEX_BOTTOM_SPACE_emoji ((WB_IS_IPHONE_X_emoji)?34:0) 18 | #define WB_NavHeight_emoji (64+WB_IPHONEX_TOP_SPACE_emoji) 19 | #define WB_TabBarHeight_emoji (49+WB_IPHONEX_BOTTOM_SPACE_emoji) 20 | #define WB_EmojiBoard_Height (216) 21 | @class WBEmojiGroupControl; 22 | @protocol WBEmojiGroupControlDelegate 23 | 24 | - (void)emojiGroupControl:(WBEmojiGroupControl*)emojiGroupControl didSelectedGroup:(id)group; 25 | 26 | - (void)emojiGroupControlEditButtonDown:(WBEmojiGroupControl *)emojiGroupControl; 27 | 28 | - (void)emojiGroupControlEditMyEmojiButtonDown:(WBEmojiGroupControl *)emojiGroupControl; 29 | 30 | - (void)emojiGroupControlSendButtonDown:(WBEmojiGroupControl *)emojiGroupControl; 31 | 32 | @end 33 | 34 | @interface WBEmojiGroupControl : UIView 35 | 36 | @property (nonatomic, assign) WBGroupControlSendButtonStatus sendButtonStatus; 37 | 38 | @property (nonatomic, strong) NSMutableArray *emojiGroupData; 39 | 40 | @property (nonatomic, assign) iddelegate; 41 | 42 | - (void)selectEmojiGroupAtIndex:(NSInteger)index; 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Extra/CustomView/WBKeyBoard/EmojiBoard/Model/WBEmotionPageModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // WBEmojiKeyBoardCellModel.h 3 | // WBChat 4 | // 5 | // Created by RedRain on 2018/1/24. 6 | // Copyright © 2018年 RedRain. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | typedef NS_ENUM(NSUInteger, WBEmotionItemType) { 12 | WBEmotionItemTypeDelete, 13 | WBEmotionItemTypeEmoji 14 | }; 15 | 16 | typedef NS_ENUM(NSUInteger, WBEmotionPageType) { 17 | WBEmotionPageTypeAdd, 18 | WBEmotionPageTypeEmoji, 19 | WBEmotionPageTypeSend, 20 | WBEmotionPageTypeCollect 21 | }; 22 | 23 | @interface WBEmotionPageItemModel : NSObject 24 | 25 | @property (nonatomic, assign) WBEmotionItemType type; 26 | 27 | @property (nonatomic, strong) NSString *name; 28 | 29 | 30 | 31 | @end 32 | 33 | 34 | @interface WBEmotionPageModel : NSObject 35 | 36 | @property (nonatomic, copy) NSString *tabImageName; 37 | 38 | @property (nonatomic, assign) WBEmotionPageType type; 39 | 40 | @property (nonatomic, assign) CGSize cellSize; 41 | 42 | @property (nonatomic, strong) NSMutableArray *pageDataArray; 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Extra/CustomView/WBKeyBoard/EmojiBoard/Model/WBEmotionPageModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // WBEmojiKeyBoardCellModel.m 3 | // WBChat 4 | // 5 | // Created by RedRain on 2018/1/24. 6 | // Copyright © 2018年 RedRain. All rights reserved. 7 | // 8 | 9 | #import "WBEmotionPageModel.h" 10 | 11 | @implementation WBEmotionPageItemModel 12 | 13 | @end 14 | 15 | @implementation WBEmotionPageModel 16 | 17 | - (NSString *)tabImageName{ 18 | switch (self.type) { 19 | case WBEmotionPageTypeEmoji: 20 | return @"EmotionsEmojiHL"; 21 | break; 22 | 23 | default: 24 | return _tabImageName; 25 | break; 26 | } 27 | } 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Extra/CustomView/WBKeyBoard/EmojiBoard/WBEmotionDisplayBoard.h: -------------------------------------------------------------------------------- 1 | // 2 | // WBEmojiKeyBoard.h 3 | // WBChat 4 | // 5 | // Created by RedRain on 2018/1/24. 6 | // Copyright © 2018年 RedRain. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "WBEmojiGroupControl.h" 11 | 12 | #define WBEmotionDisplayBoardDidSelectEmojiNotifi @"WBEmotionDisplayBoardDidSelectEmojiNotifi" 13 | #define WBEmotionDisplayBoardSendClickNotifi @"WBEmotionDisplayBoardSendClickNotifi" 14 | 15 | 16 | 17 | @interface WBEmotionDisplayBoard : UIView 18 | 19 | + (instancetype)createEmojiKeyboard; 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Extra/CustomView/WBKeyBoard/MediaUtilities/WBTLAudioPlayer.h: -------------------------------------------------------------------------------- 1 | // 2 | // TLAudioPlayer.h 3 | // TLChat 4 | // 5 | // Created by 李伯坤 on 16/7/12. 6 | // Copyright © 2016年 李伯坤. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface WBTLAudioPlayer : NSObject 12 | 13 | @property (nonatomic, assign, readonly) BOOL isPlaying; 14 | 15 | + (WBTLAudioPlayer *)sharedAudioPlayer; 16 | 17 | - (void)playAudioAtPath:(NSString *)path complete:(void (^)(BOOL finished))complete; 18 | 19 | - (void)stopPlayingAudio; 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Extra/CustomView/WBKeyBoard/MediaUtilities/WBTLAudioPlayer.m: -------------------------------------------------------------------------------- 1 | // 2 | // TLAudioPlayer.m 3 | // TLChat 4 | // 5 | // Created by 李伯坤 on 16/7/12. 6 | // Copyright © 2016年 李伯坤. All rights reserved. 7 | // 8 | 9 | #import "WBTLAudioPlayer.h" 10 | #import 11 | 12 | @interface WBTLAudioPlayer() 13 | 14 | @property (nonatomic, strong) void (^ completeBlock)(BOOL finished); 15 | 16 | @property (nonatomic, strong) AVAudioPlayer *player; 17 | 18 | @end 19 | 20 | @implementation WBTLAudioPlayer 21 | 22 | + (WBTLAudioPlayer *)sharedAudioPlayer 23 | { 24 | static WBTLAudioPlayer *audioPlayer; 25 | static dispatch_once_t once; 26 | dispatch_once(&once, ^{ 27 | audioPlayer = [[WBTLAudioPlayer alloc] init]; 28 | }); 29 | return audioPlayer; 30 | } 31 | 32 | - (void)playAudioAtPath:(NSString *)path complete:(void (^)(BOOL finished))complete; 33 | { 34 | if (self.player && self.player.isPlaying) { 35 | [self stopPlayingAudio]; 36 | } 37 | self.completeBlock = complete; 38 | NSError *error; 39 | self.player = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:&error]; 40 | [self.player setDelegate:self]; 41 | if (error) { 42 | if (complete) { 43 | complete(NO); 44 | } 45 | return; 46 | } 47 | [self.player play]; 48 | } 49 | 50 | - (void)stopPlayingAudio 51 | { 52 | [self.player stop]; 53 | if (self.completeBlock) { 54 | self.completeBlock(NO); 55 | } 56 | } 57 | 58 | - (BOOL)isPlaying 59 | { 60 | if (self.player) { 61 | return self.player.isPlaying; 62 | } 63 | return NO; 64 | } 65 | 66 | #pragma mark - # Delegate 67 | //MARK: AVAudioPlayerDelegate 68 | - (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag 69 | { 70 | if (self.completeBlock) { 71 | self.completeBlock(YES); 72 | self.completeBlock = nil; 73 | } 74 | } 75 | 76 | - (void)audioPlayerDecodeErrorDidOccur:(AVAudioPlayer *)player error:(NSError *)error 77 | { 78 | if (self.completeBlock) { 79 | self.completeBlock(NO); 80 | self.completeBlock = nil; 81 | } 82 | } 83 | 84 | @end 85 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Extra/CustomView/WBKeyBoard/MediaUtilities/WBTLAudioRecorder.h: -------------------------------------------------------------------------------- 1 | // 2 | // TLAudioRecorder.h 3 | // TLChat 4 | // 5 | // Created by 李伯坤 on 16/7/11. 6 | // Copyright © 2016年 李伯坤. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface WBTLAudioRecorder : NSObject 12 | 13 | + (WBTLAudioRecorder *)sharedRecorder; 14 | 15 | - (void)startRecordingWithVolumeChangedBlock:(void (^)(CGFloat volume))volumeChanged 16 | completeBlock:(void (^)(NSString *path, CGFloat time))complete 17 | cancelBlock:(void (^)(void))cancel; 18 | - (void)stopRecording; 19 | - (void)cancelRecording; 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Extra/CustomView/WBKeyBoard/PlusBoard/Cell/WBPlusBoardCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // WBPlusBoardCell.h 3 | // WBChat 4 | // 5 | // Created by RedRain on 2018/1/31. 6 | // Copyright © 2018年 RedRain. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface WBPlusBoardCell : UICollectionViewCell 12 | 13 | @property (nonatomic, strong) UIImageView *iconImageView; 14 | @property (nonatomic, strong) UILabel *iconTitleLabel; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Extra/CustomView/WBKeyBoard/PlusBoard/Cell/WBPlusBoardCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // WBPlusBoardCell.m 3 | // WBChat 4 | // 5 | // Created by RedRain on 2018/1/31. 6 | // Copyright © 2018年 RedRain. All rights reserved. 7 | // 8 | 9 | #import "WBPlusBoardCell.h" 10 | 11 | @interface WBPlusBoardCell () 12 | @end 13 | 14 | @implementation WBPlusBoardCell 15 | - (instancetype)initWithFrame:(CGRect)frame 16 | { 17 | self = [super initWithFrame:frame]; 18 | if (self) { 19 | [self.contentView addSubview:self.iconImageView]; 20 | [self.contentView addSubview:self.iconTitleLabel]; 21 | } 22 | return self; 23 | } 24 | - (void)layoutSubviews{ 25 | [super layoutSubviews]; 26 | 27 | CGFloat iWidth = 40; 28 | self.iconImageView.frame = CGRectMake((self.frame.size.width - iWidth) / 2 , (self.frame.size.height - iWidth) / 2 - 8, iWidth, iWidth); 29 | 30 | 31 | CGRect titleRect = CGRectMake(CGRectGetMinX(self.iconImageView.frame), CGRectGetMaxY(self.iconImageView.frame) + 4, CGRectGetWidth(self.iconImageView.frame), 20); 32 | self.iconTitleLabel.frame = titleRect; 33 | 34 | } 35 | 36 | - (UIImageView *)iconImageView 37 | { 38 | if (_iconImageView == nil) { 39 | _iconImageView = [[UIImageView alloc] init]; 40 | } 41 | return _iconImageView; 42 | } 43 | 44 | - (UILabel *)iconTitleLabel 45 | { 46 | if (_iconTitleLabel == nil) { 47 | _iconTitleLabel = [[UILabel alloc] init]; 48 | [_iconTitleLabel setFont:[UIFont systemFontOfSize:12.0f]]; 49 | [_iconTitleLabel setTextAlignment:NSTextAlignmentCenter]; 50 | _iconTitleLabel.textColor = [UIColor grayColor]; 51 | } 52 | return _iconTitleLabel; 53 | } 54 | @end 55 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Extra/CustomView/WBKeyBoard/PlusBoard/WBPlusDisplayBoard.h: -------------------------------------------------------------------------------- 1 | // 2 | // WBPlusDisplayBoard.h 3 | // WBChat 4 | // 5 | // Created by RedRain on 2018/1/31. 6 | // Copyright © 2018年 RedRain. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "WBEmojiGroupControl.h" 11 | #import "WBChatBarConst.h" 12 | 13 | @interface WBPlusDisplayBoard : UIView 14 | 15 | + (instancetype)createPlusBoard; 16 | 17 | @property (nonatomic, weak) id delegate; 18 | @property (nonatomic, weak) id dataSource; 19 | 20 | - (void)reloadData; 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Extra/CustomView/WBKeyBoard/TLRecorderIndicatorView/WBTLRecorderIndicatorView.h: -------------------------------------------------------------------------------- 1 | // 2 | // WBTLRecorderIndicatorView.h 3 | // TLChat 4 | // 5 | // Created by 李伯坤 on 16/7/12. 6 | // Copyright © 2016年 李伯坤. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | typedef NS_ENUM(NSInteger, WBTLRecorderStatus) { 12 | WBTLRecorderStatusRecording, 13 | WBTLRecorderStatusWillCancel, 14 | WBTLRecorderStatusTooShort, 15 | }; 16 | 17 | @interface WBTLRecorderIndicatorView : UIView 18 | 19 | @property (nonatomic, assign) WBTLRecorderStatus status; 20 | 21 | /** 22 | * 音量大小,取值(0-1) 23 | */ 24 | @property (nonatomic, assign) CGFloat volume; 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Extra/CustomView/WBKeyBoard/TalkButton/WBTLTalkButton.h: -------------------------------------------------------------------------------- 1 | // 2 | // TLTalkButton.h 3 | // TLChat 4 | // 5 | // Created by 李伯坤 on 16/7/11. 6 | // Copyright © 2016年 李伯坤. All rights reserved. 7 | // 8 | 9 | #import 10 | #define WBAudioCompleteFinishNotification @"WBAudioCompleteFinishNotification" 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | @interface WBTLTalkButton : UIView 14 | 15 | @property (nonatomic, strong) NSString *normalTitle; 16 | @property (nonatomic, strong) NSString *cancelTitle; 17 | @property (nonatomic, strong) NSString *highlightTitle; 18 | 19 | @property (nonatomic, strong) UIColor *highlightColor; 20 | 21 | @property (nonatomic, strong) UILabel *titleLabel; 22 | 23 | - (void)setTouchBeginAction:(void (^)(void))touchBegin 24 | willTouchCancelAction:(void (^)(BOOL cancel))willTouchCancel 25 | touchEndAction:(void (^)(void))touchEnd 26 | touchCancelAction:(void (^)(void))touchCancel; 27 | 28 | @end 29 | NS_ASSUME_NONNULL_END 30 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Extra/CustomView/WBKeyBoard/WBChatBarConst.h: -------------------------------------------------------------------------------- 1 | // 2 | // WBChatBarConst.h 3 | // WBChat 4 | // 5 | // Created by RedRain on 2018/2/1. 6 | // Copyright © 2018年 RedRain. All rights reserved. 7 | // 8 | 9 | #ifndef WBChatBarConst_h 10 | #define WBChatBarConst_h 11 | 12 | typedef NS_ENUM(NSUInteger, WBPlusBoardButtonType) { 13 | WBPlusBoardButtonTypePhotoAlbum = 0, // 相册 14 | WBPlusBoardButtonTypeCamera, // 相机 15 | WBPlusBoardButtonTypeVideo, // 视频聊天 16 | WBPlusBoardButtonTypeAudio, // 音频聊天 17 | WBPlusBoardButtonTypeFile, // 文件按钮 18 | WBPlusBoardButtonTypeVideoFile, // 小视频 19 | WBPlusBoardButtonTypeLocation, // 位置 20 | WBPlusBoardButtonTypeNameCard // 名片 21 | }; 22 | 23 | typedef NS_ENUM(NSInteger, WBChatBarStatus) { 24 | WBChatBarStatusInit, 25 | WBChatBarStatusVoice, 26 | WBChatBarStatusEmoji, 27 | WBChatBarStatusMore, 28 | WBChatBarStatusKeyboard, 29 | }; 30 | 31 | #define kPlusBoardIcon @"icon" 32 | #define kPlusBoardTitle @"title" 33 | #define kPlusBoardType @"type" 34 | 35 | #define PlusBoardItemDicInfo(A,B,C) @{kPlusBoardIcon:A,kPlusBoardTitle:B,kPlusBoardType:C} 36 | 37 | @class WBChatBarView; 38 | /************************************************************************** 39 | * 加号按钮弹出的键盘的代理方法. 40 | ************************************************************************ 41 | */ 42 | @protocol WBChatBarViewDelegate 43 | 44 | 45 | /** 46 | 点击键盘发送,回调的方法 47 | 48 | @param sendText 发送的消息内容 49 | */ 50 | - (void)chatBar:(WBChatBarView *)keyBoardView sendText:(NSString *)sendText; 51 | 52 | 53 | /** 54 | 录音完成后,返回音频路径 55 | 56 | @param audioPath 音频文件的路径 57 | */ 58 | - (void)chatBar:(WBChatBarView *)keyBoardView recoderAudioPath:(NSString *)audioPath duration:(NSNumber *)duration; 59 | 60 | /** 61 | 点击plusBoard后, 返回对应的数据 62 | 63 | @param itemInfo 点击对应的item, 返回此Item对应的数据. 64 | 每一个Dictionary的内容: 65 | @{ 66 | @"icon": UIImage, 67 | @"title":@"相册", 68 | @"type":@(WBPlusBoardButtonTypePhotoAlbum) 69 | } 70 | */ 71 | - (void)chatBar:(WBChatBarView *)chatBar didSelectItemInfo:(NSDictionary *)itemInfo; 72 | 73 | @end 74 | 75 | @protocol WBChatBarViewDataSource 76 | 77 | /** 78 | 给plusBoard添加按钮 79 | 80 | @return plusBoard 需要展示的数据, 81 | 每一个Dictionary的内容: 82 | @{ 83 | @"icon": UIImage, 84 | @"title":@"相册", 85 | @"type":@(WBPlusBoardButtonTypePhotoAlbum) 86 | } 87 | */ 88 | - (NSArray *)plusBoardItemInfos:(WBChatBarView *)keyBoardView; 89 | 90 | @end 91 | 92 | #endif /* WBChatBarConst_h */ 93 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Extra/CustomView/WBKeyBoard/WBChatBarView.h: -------------------------------------------------------------------------------- 1 | // 2 | // WBKeyBoard.h 3 | // WBChat 4 | // 5 | // Created by RedRain on 2018/1/20. 6 | // Copyright © 2018年 RedRain. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "WBChatBarConst.h" 11 | 12 | @interface WBChatBarView : UIView 13 | 14 | @property (nonatomic, assign) WBChatBarStatus status; 15 | 16 | @property (nonatomic, assign) BOOL activity; 17 | 18 | @property (nonatomic, weak) id delegate; 19 | @property (nonatomic, weak) id dataSource; 20 | 21 | @property (nonatomic, copy) NSString *chatText; 22 | 23 | 24 | - (void)stateToInit; 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Extra/CustomView/WBKeyBoard/WBKeyBoardTextView/WBKeyBoardTextView.h: -------------------------------------------------------------------------------- 1 | // 2 | // WBKeyBoardTextView.h 3 | // WBChat 4 | // 5 | // Created by RedRain on 2018/1/22. 6 | // Copyright © 2018年 RedRain. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface WBKeyBoardTextView : UITextView 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Extra/CustomView/WBKeyBoard/WBKeyBoardTextView/WBKeyBoardTextView.m: -------------------------------------------------------------------------------- 1 | // 2 | // WBKeyBoardTextView.m 3 | // WBChat 4 | // 5 | // Created by RedRain on 2018/1/22. 6 | // Copyright © 2018年 RedRain. All rights reserved. 7 | // 8 | 9 | #import "WBKeyBoardTextView.h" 10 | 11 | @implementation WBKeyBoardTextView 12 | 13 | 14 | - (void)setContentOffset:(CGPoint)s{ 15 | 16 | if(self.tracking || self.decelerating){ 17 | //initiated by user... 18 | 19 | UIEdgeInsets insets = self.contentInset; 20 | insets.bottom = 0; 21 | insets.top = 0; 22 | self.contentInset = insets; 23 | 24 | } else { 25 | 26 | float bottomOffset = (self.contentSize.height - self.frame.size.height + self.contentInset.bottom); 27 | if(s.y < bottomOffset && self.scrollEnabled){ 28 | UIEdgeInsets insets = self.contentInset; 29 | insets.bottom = 8; 30 | insets.top = 0; 31 | self.contentInset = insets; 32 | } 33 | } 34 | 35 | // Fix "overscrolling" bug 36 | if (s.y > self.contentSize.height - self.frame.size.height && !self.decelerating && !self.tracking && !self.dragging){ 37 | s = CGPointMake(s.x, self.contentSize.height - self.frame.size.height); 38 | } 39 | 40 | [super setContentOffset:s]; 41 | } 42 | @end 43 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Extra/CustomView/WBRefresh/UIScrollView+WBRefresh.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIScrollView+WBRefresh.h 3 | // WBRefreshDemo 4 | // 5 | // Created by RedRain on 2018/3/7. 6 | // Copyright © 2018年 RedRain. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "WBRefreshHeaderView.h" 11 | 12 | 13 | 14 | @interface UIScrollView (WBRefresh) 15 | 16 | // 头部刷新视图 17 | @property (nonatomic, strong) WBRefreshHeaderView *wb_headerView; 18 | 19 | // 当前头部视图刷新的状态 20 | @property (nonatomic, assign) WBRefreshState wb_refreshState; 21 | 22 | @property (nonatomic, copy) void (^wb_headerRefreshBlock)(void); 23 | 24 | - (void)wb_addRefreshHeaderViewWithBlock:(void (^)(void))headerBlock; 25 | - (void)wb_endRefreshing; 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Extra/CustomView/WBRefresh/UIScrollView+WBRefresh.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIScrollView+WBRefresh.m 3 | // WBRefreshDemo 4 | // 5 | // Created by RedRain on 2018/3/7. 6 | // Copyright © 2018年 RedRain. All rights reserved. 7 | // 8 | 9 | #import "UIScrollView+WBRefresh.h" 10 | #import 11 | 12 | #define WBRefreshKeyPathContentOffset @"contentOffset" 13 | 14 | @implementation UIScrollView (WBRefresh) 15 | - (void)wb_addRefreshHeaderViewWithBlock:(void (^)(void))headerBlock{ 16 | self.wb_headerRefreshBlock = headerBlock; 17 | 18 | if (self.wb_headerView == nil) { 19 | self.wb_headerView = [[WBRefreshHeaderView alloc] initWithFrame: 20 | CGRectMake(0, 21 | -WBRefreshHeaderHeight, 22 | [UIScreen mainScreen].bounds.size.width, 23 | WBRefreshHeaderHeight)]; 24 | [self addSubview:self.wb_headerView]; 25 | } 26 | 27 | [self addObserver:self forKeyPath:WBRefreshKeyPathContentOffset options:NSKeyValueObservingOptionNew context:nil]; 28 | } 29 | - (void)removeFromSuperview{ 30 | 31 | } 32 | 33 | - (void)wb_endRefreshing{ 34 | self.wb_refreshState = WBRefreshStateIdle; 35 | self.contentInset = UIEdgeInsetsMake(0, 0, 10, 0); 36 | 37 | // [UIView animateWithDuration:0.4 animations:^{ 38 | // }]; 39 | } 40 | - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{ 41 | 42 | if (![keyPath isEqualToString:WBRefreshKeyPathContentOffset]) { 43 | return; 44 | } 45 | if (!self.dragging) { 46 | return; 47 | } 48 | if (self.contentOffset.y >= 0) { 49 | return; 50 | } 51 | if (self.wb_refreshState == WBRefreshStateRefreshing) { 52 | return; 53 | } 54 | 55 | if (self.contentOffset.y <= -WBRefreshHeaderHeight) { 56 | self.wb_refreshState = WBRefreshStateRefreshing; 57 | }else{ 58 | self.wb_refreshState = WBRefreshStateIdle; 59 | } 60 | } 61 | 62 | #pragma mark - Setter or Getter 63 | - (void)setWb_headerView:(WBRefreshHeaderView *)wb_headerView{ 64 | objc_setAssociatedObject(self, @selector(wb_headerView), wb_headerView, OBJC_ASSOCIATION_RETAIN); 65 | } 66 | - (WBRefreshHeaderView *)wb_headerView{ 67 | return objc_getAssociatedObject(self, _cmd); 68 | } 69 | 70 | - (void)setWb_refreshState:(WBRefreshState)wb_refreshState{ 71 | objc_setAssociatedObject(self, @selector(wb_refreshState), @(wb_refreshState), OBJC_ASSOCIATION_COPY); 72 | 73 | self.wb_headerView.state = wb_refreshState; 74 | 75 | if (wb_refreshState == WBRefreshStateRefreshing) { 76 | self.contentInset = UIEdgeInsetsMake(WBRefreshHeaderHeight, 0, 10, 0); 77 | 78 | if (self.wb_headerRefreshBlock) { 79 | self.wb_headerRefreshBlock(); 80 | } 81 | } 82 | 83 | 84 | } 85 | - (WBRefreshState)wb_refreshState{ 86 | return ((NSNumber *)objc_getAssociatedObject(self, _cmd)).integerValue; 87 | } 88 | 89 | - (void)setWb_headerRefreshBlock:(void (^)(void))wb_headerRefreshBlock{ 90 | objc_setAssociatedObject(self, @selector(wb_headerRefreshBlock), wb_headerRefreshBlock, OBJC_ASSOCIATION_COPY); 91 | } 92 | - (void (^)(void))wb_headerRefreshBlock{ 93 | return objc_getAssociatedObject(self, _cmd); 94 | } 95 | 96 | @end 97 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Extra/CustomView/WBRefresh/WBRefreshHeaderView.h: -------------------------------------------------------------------------------- 1 | // 2 | // WBRefreshHeaderView.h 3 | // WBRefreshDemo 4 | // 5 | // Created by RedRain on 2018/3/7. 6 | // Copyright © 2018年 RedRain. All rights reserved. 7 | // 8 | 9 | #import 10 | typedef NS_ENUM(NSUInteger, WBRefreshState) { 11 | WBRefreshStateIdle = 1, // 闲置 12 | WBRefreshStateRefreshing, // 刷新中 13 | }; 14 | #define WBRefreshHeaderHeight (30) 15 | 16 | 17 | 18 | @interface WBRefreshHeaderView : UIView 19 | 20 | @property (nonatomic, assign) WBRefreshState state; 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Extra/CustomView/WBRefresh/WBRefreshHeaderView.m: -------------------------------------------------------------------------------- 1 | // 2 | // WBRefreshHeaderView.m 3 | // WBRefreshDemo 4 | // 5 | // Created by RedRain on 2018/3/7. 6 | // Copyright © 2018年 RedRain. All rights reserved. 7 | // 8 | 9 | #import "WBRefreshHeaderView.h" 10 | 11 | @interface WBRefreshHeaderView () 12 | 13 | @property (nonatomic, strong) UIActivityIndicatorView *refreshView; 14 | 15 | @end 16 | 17 | @implementation WBRefreshHeaderView 18 | - (void)dealloc{ 19 | [self.superview removeObserver:self.superview forKeyPath:@"contentOffset"]; 20 | 21 | } 22 | - (instancetype)initWithFrame:(CGRect)frame 23 | { 24 | self = [super initWithFrame:frame]; 25 | if (self) { 26 | _refreshView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]; 27 | _refreshView.hidden = YES; 28 | [_refreshView startAnimating]; 29 | [self addSubview:_refreshView]; 30 | } 31 | return self; 32 | } 33 | 34 | - (void)layoutSubviews{ 35 | [super layoutSubviews]; 36 | self.refreshView.center = CGPointMake(([UIScreen mainScreen].bounds.size.width)/ 2 - 10, 37 | self.bounds.size.height - 20); 38 | } 39 | 40 | - (void)setState:(WBRefreshState)state{ 41 | _state = state; 42 | 43 | self.refreshView.hidden = (state != WBRefreshStateRefreshing); 44 | 45 | } 46 | 47 | @end 48 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Extra/Tools/ImageLoad/WBImageLoad.h: -------------------------------------------------------------------------------- 1 | // 2 | // WBImageLoad.h 3 | // WBChat 4 | // 5 | // Created by RedRain on 2018/2/6. 6 | // Copyright © 2018年 RedRain. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface WBImageLoad : NSObject 12 | 13 | - (void)imageView:(UIImageView *)imageView 14 | urlString:(NSString *)urlString 15 | placeholderImage:(UIImage *)placeholderImage; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Extra/Tools/ImageLoad/WBImageLoad.m: -------------------------------------------------------------------------------- 1 | // 2 | // WBImageLoad.m 3 | // WBChat 4 | // 5 | // Created by RedRain on 2018/2/6. 6 | // Copyright © 2018年 RedRain. All rights reserved. 7 | // 8 | 9 | #import "WBImageLoad.h" 10 | 11 | @implementation WBImageLoad 12 | 13 | - (void)imageView:(UIImageView *)imageView urlString:(NSString *)urlString placeholderImage:(UIImage *)placeholderImage{ 14 | imageView.image = placeholderImage; 15 | } 16 | 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Extra/Tools/SelectPhotoTool/WBSelectPhotoTool.h: -------------------------------------------------------------------------------- 1 | // 2 | // WBSelectPhotoTool.h 3 | // WBChat 4 | // 5 | // Created by RedRain on 2017/8/1. 6 | // Copyright © 2017年 RedRain. All rights reserved. 7 | // 8 | 9 | #import 10 | @class WBSelectPhotoTool; 11 | 12 | @protocol WBSelectPhotoToolDelegate 13 | 14 | - (void)toolWillSelectImage:(WBSelectPhotoTool *)tool; 15 | 16 | - (void)tool:(WBSelectPhotoTool *)tool didSelectImage:(UIImage *)image; 17 | 18 | @end 19 | 20 | @interface WBSelectPhotoTool : NSObject 21 | 22 | @property (nonatomic, assign) NSUInteger tag; 23 | 24 | 25 | @property (nonatomic, weak) id delegate; 26 | 27 | 28 | /** 29 | 在showController.view中弹出 alertSheet 30 | */ 31 | - (void)showSheetInController:(UIViewController *)showController; 32 | 33 | 34 | /** 35 | 直接显示相册 36 | */ 37 | - (void)visitPhotoLibraryInController:(UIViewController *)showController; 38 | 39 | /** 40 | 直接显示相机 41 | */ 42 | - (void)visitCameraInController:(UIViewController*)showController; 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Extra/Tools/WBTools.h: -------------------------------------------------------------------------------- 1 | // 2 | // OPUITools.h 3 | // LCGOptimusPrime 4 | // 5 | // Created by RedRain on 2017/7/28. 6 | // Copyright © 2017年 erics. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface WBTools : NSObject 12 | + (void)view:(UIView *)view setupShadowColor:(UIColor *)color offset:(CGSize)offset; 13 | 14 | 15 | /** 16 | 压缩Image到接近指定的值附近 17 | */ 18 | + (NSData *)compressOriginalImage:(UIImage *)image toMaxDataSizeKBytes:(CGFloat)size; 19 | 20 | 21 | /** 22 | 压缩Image到指定kb附近, 返回base64编码后的String 23 | 24 | @param image 原始图片 25 | @param size 压缩到的大小kb 26 | @return base64字符串 27 | */ 28 | + (NSString *)base64StringWithCompressImage:(UIImage *)image toMaxDataSizeKBytes:(CGFloat)size; 29 | 30 | /** 31 | 给一个View绘制虚线的边框 32 | */ 33 | + (void)drawLineDashPatterForView:(UIView *)view; 34 | 35 | /** 36 | * 描述:利用正则判断手机号格式是否正确 37 | * 38 | * @param mobile 需要判断的手机号 39 | * 40 | * @return 返回是否正确 41 | */ 42 | + (BOOL) isValidateMobile:(NSString *)mobile; 43 | 44 | /** 45 | * 正则判断密码:密码只能为8-16 位数字,字母及常用符号组成 46 | * 47 | * @param password 密码字符串 48 | * 49 | * @return 是否正确 50 | */ 51 | +(BOOL)isValidatePassWord:(NSString *)password; 52 | 53 | /** 54 | * 描述:利用正则判断验证码格式是否正确 55 | * 56 | * @param authCode 需要判断的字符串 57 | * 58 | * @return 返回是否正确 59 | */ 60 | 61 | + (BOOL)isValidateAuthCode:(NSString *)authCode; 62 | 63 | /** 64 | 描述:利用正则判断邮箱格式是否正确 65 | 参数:需要判断的字符串 66 | **/ 67 | +(BOOL)isValidateEmail:(NSString *)email; 68 | 69 | 70 | 71 | /** 72 | 验证身份证号码 73 | */ 74 | + (BOOL)isValidateIDCard:(NSString *)identityString; 75 | 76 | 77 | /** 78 | 打电话 79 | 80 | @param phoneNum 电话号 81 | */ 82 | + (void)callPhoneByStr:(NSString *)phoneNum; 83 | 84 | /** 85 | 粗略的验证银行卡号 86 | */ 87 | + (BOOL)IsBankCardRoughly:(NSString *)cardNumber; 88 | 89 | /** 90 | 细致规则验证银行账号 91 | */ 92 | + (BOOL) IsBankCard:(NSString *)cardNumber; 93 | 94 | 95 | /** 96 | 字符串转拼音 97 | 98 | @param word 需要被转换的字符串 99 | @return 转换后的拼音 100 | */ 101 | + (NSString *)transformChinese:(NSString *)word; 102 | 103 | @end 104 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/Other.bundle/AddGroupMemberBtn@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/Other.bundle/AddGroupMemberBtn@2x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/Other.bundle/AddGroupMemberBtnHL@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/Other.bundle/AddGroupMemberBtnHL@2x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/Other.bundle/CellBlueSelected@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/Other.bundle/CellBlueSelected@2x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/Other.bundle/CellGraySelected@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/Other.bundle/CellGraySelected@2x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/Other.bundle/ChatKit-Settings.plist: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/Other.bundle/ChatKit-Settings.plist -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/Other.bundle/ChatKit-Theme.plist: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/Other.bundle/ChatKit-Theme.plist -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/Other.bundle/Connectkeyboad_banner_mute@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/Other.bundle/Connectkeyboad_banner_mute@2x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/Other.bundle/Connectkeyboad_banner_mute@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/Other.bundle/Connectkeyboad_banner_mute@3x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/Other.bundle/Remind_Mute.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/Other.bundle/Remind_Mute.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/Other.bundle/SearchContactsBarIcon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/Other.bundle/SearchContactsBarIcon@2x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/Other.bundle/chatMuteOn@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/Other.bundle/chatMuteOn@2x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/Other.bundle/conversationViewController_default_backgroundImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/Other.bundle/conversationViewController_default_backgroundImage.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/Other.bundle/en.lproj/LCChatKitString.strings: -------------------------------------------------------------------------------- 1 | // LCChatKitString.strings 2 | // LeanCloudChatKit-iOS 3 | // 4 | // v0.8.5 Created by ElonChan on 16/3/1. 5 | // Copyright © 2016年 LeanCloud. All rights reserved. 6 | // 7 | "Delete" = "Delete"; 8 | "draft" = "Draft"; 9 | "mentioned" = "You are mentioned"; 10 | "copy" = "copy"; 11 | "transpond" = "transpond"; 12 | "resend" = "resend"; 13 | "cancel" = "cancel"; 14 | "done" = "done"; 15 | "ok" = "ok"; 16 | "favorites" = "favorites"; 17 | "more" = "more"; 18 | "Location" = "Location"; 19 | "Photo" = "Photo"; 20 | "TextDetail" = "TextDetail"; 21 | "Video" = "Video"; 22 | "News" = "News"; 23 | "Contact" = "Contact"; 24 | "Chat" = "Chat"; 25 | "Emotion" = "Emotion"; 26 | "Album" = "Album"; 27 | "Bottle" = "Bottle"; 28 | "NearbyPeople" = "NearbyPeople"; 29 | "Shake" = "Shake"; 30 | "Scanning" = "Scanning"; 31 | "Gamge" = "Gamge"; 32 | "Expression" = "Expression"; 33 | "MyAlbum" = "MyAlbum"; 34 | "MyBankCard" = "MyBankCard"; 35 | "MyFavorites" = "MyFavorites"; 36 | "MyProfileInfo" = "MyProfileInfo"; 37 | "Setting" = "Setting"; 38 | "Profile" = "Profile"; 39 | "News" = "News"; 40 | "Voice" = "Voice"; 41 | "Sight" = "Sight"; 42 | "Community" = "Community"; 43 | "ConfirmDeletion" = "Confirm deletion"; 44 | "netDisconnected" = "Network unavailable, Check network"; 45 | "connectSucceeded" = "connect succeeded"; 46 | "connectFailed" = "connect failed"; 47 | "requestForceSingleSignOnAuthorization" = "Force sign on?"; 48 | "call" = "call"; 49 | "unknownMessage" = "Unsupported message, please update your APP"; 50 | "unknownMessageType" = "Unsupported message type"; 51 | "SingleWelcomeMessage" = "Hello!"; 52 | "GroupWelcomeMessage" = "Hello!"; 53 | "GroupWelcomeMessageWithNickName" = "Hello! I am "; 54 | "SingleConversation" = "single chat"; 55 | "GroupConversation" = "group chat"; 56 | "SystemConversation" = "system notification"; 57 | "ConversationAvatarURLKey" = "avatarURL"; 58 | "nickNameIsNil" = "[no nick name]"; 59 | "message.bar.error.title" = "Error Title"; 60 | "message.bar.error.message" = "This is an error message!"; 61 | "message.bar.success.title" = "Success Title"; 62 | "message.bar.success.message" = "This is a success message!"; 63 | "message.bar.info.title" = "--------"; 64 | "message.bar.info.message" = "--------"; 65 | 66 | 67 | "button.label.success.message" = "Success Message"; 68 | "button.label.error.message" = "Error Message"; 69 | "button.label.info.message" = "Information Message"; 70 | "button.label.hide.all" = "Hide All"; 71 | 72 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/Other.bundle/safari-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/Other.bundle/safari-icon.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/Other.bundle/safari-icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/Other.bundle/safari-icon@2x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/Other.bundle/zh-Hans.lproj/LCChatKitString.strings: -------------------------------------------------------------------------------- 1 | // LCChatKitString.strings 2 | // LeanCloudChatKit-iOS 3 | // 4 | // v0.8.5 Created by ElonChan on 16/3/1. 5 | // Copyright © 2016年 LeanCloud. All rights reserved. 6 | // 7 | 8 | "Delete" = "删除"; 9 | "copy" = "复制"; 10 | "draft" = "草稿"; 11 | "mentioned" = "有人@你"; 12 | "resend" = "重新发送"; 13 | "cancel" = "取消"; 14 | "done" = "确定"; 15 | "ok" = "确定"; 16 | "transpond" = "转发"; 17 | "favorites" = "收藏"; 18 | "more" = "更多"; 19 | "Location" = "位置"; 20 | "Photo" = "图片"; 21 | "TextDetail" = "文本消息"; 22 | "Video" = "视频"; 23 | "News" = "发现"; 24 | "Contact" = "联系人"; 25 | "Chat" = "聊天"; 26 | "Emotion" = "表情详情"; 27 | "Album" = "朋友圈"; 28 | "Bottle" = "漂流瓶"; 29 | "NearbyPeople" = "附近的人"; 30 | "Shake" = "摇一摇"; 31 | "Scanning" = "扫一扫"; 32 | "Gamge" = "游戏"; 33 | "Profile" = "我"; 34 | "Profile" = "Profile"; 35 | "Expression" = "表情"; 36 | "MyAlbum" = "我的相册"; 37 | "MyBankCard" = "我的银行卡"; 38 | "MyFavorites" = "我的收藏"; 39 | "MyProfileInfo" = "个人信息"; 40 | "Setting" = "设置"; 41 | "Profile" = "我"; 42 | "News" = "新闻"; 43 | "Voice" = "声音"; 44 | "Sight" = "表情"; 45 | "Community" = "小区"; 46 | "ConfirmDeletion" = "确认删除吗"; 47 | "call" = "拨打"; 48 | "netDisconnected" = "当前网络不可用,请检查你的网络设置"; 49 | "connectSucceeded" = "连接成功"; 50 | "connectFailed" = "连接失败"; 51 | "requestForceSingleSignOnAuthorization" = "当前账号已在其它设备登录,请问是否强制登录?强制登录会踢掉当前已经登录的设备。"; 52 | "unknownMessage" = "当前版本暂不支持查看此消息,请尝试升级APP查看"; 53 | "unknownMessageType" = "未知消息类型"; 54 | "SingleWelcomeMessage" = "我们已经是好友啦,一起来聊天吧!"; 55 | "GroupWelcomeMessage" = "大家好"; 56 | "GroupWelcomeMessageWithNickName" = "大家好,我是"; 57 | "SingleConversation" = "单聊"; 58 | "GroupConversation" = "群聊"; 59 | "SystemConversation" = "系统通知"; 60 | "ConversationAvatarURLKey" = "avatarURL"; 61 | "nickNameIsNil" = "[该用户未设置昵称]"; 62 | "message.bar.error.title" = "错误"; 63 | "message.bar.error.message" = "错误"; 64 | "message.bar.success.title" = "成功"; 65 | "message.bar.success.message" = "成功"; 66 | "message.bar.info.title" = "--------"; 67 | "message.bar.info.message" = "--------"; 68 | 69 | 70 | "button.label.success.message" = "成功"; 71 | "button.label.error.message" = "失败"; 72 | "button.label.info.message" = "注意"; 73 | "button.label.hide.all" = "隐藏"; 74 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/Album_test_close@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/Album_test_close@2x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/Album_test_donotlook@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/Album_test_donotlook@2x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/Album_test_open@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/Album_test_open@2x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/Album_test_unlike@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/Album_test_unlike@2x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/Card_AddIcon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/Card_AddIcon@2x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/CloudChatList_badge@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/CloudChatList_badge@2x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/CloudChatList_badge_dot@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/CloudChatList_badge_dot@2x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/DeleteEmoticonBtn@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/DeleteEmoticonBtn@2x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/EmotionsEmojiHL@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/EmotionsEmojiHL@2x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/EmotionsEmojiHL@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/EmotionsEmojiHL@3x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/EmotionsSendBtnBlue@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/EmotionsSendBtnBlue@2x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/EmotionsSendBtnBlueHL@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/EmotionsSendBtnBlueHL@2x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/EmotionsSendBtnGrey@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/EmotionsSendBtnGrey@2x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/ExclamationMark@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/ExclamationMark@2x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/ExclamationMark@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/ExclamationMark@3x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/Mode_listtotext@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/Mode_listtotext@2x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/Mode_listtotext@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/Mode_listtotext@3x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/Mode_listtotextHL@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/Mode_listtotextHL@2x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/Mode_listtotextHL@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/Mode_listtotextHL@3x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/Mode_texttolist@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/Mode_texttolist@2x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/Mode_texttolist@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/Mode_texttolist@3x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/Mode_texttolistHL@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/Mode_texttolistHL@2x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/Mode_texttolistHL@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/Mode_texttolistHL@3x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/Placeholder_Image@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/Placeholder_Image@2x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/ReceiverVoiceNodePlaying000@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/ReceiverVoiceNodePlaying000@2x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/ReceiverVoiceNodePlaying001@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/ReceiverVoiceNodePlaying001@2x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/ReceiverVoiceNodePlaying002@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/ReceiverVoiceNodePlaying002@2x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/ReceiverVoiceNodePlaying003@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/ReceiverVoiceNodePlaying003@2x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/ReceiverVoiceNodePlaying@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/ReceiverVoiceNodePlaying@2x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/RecordCancel@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/RecordCancel@2x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/RecordCancel@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/RecordCancel@3x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/RecordingBkg@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/RecordingBkg@2x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/RecordingBkg@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/RecordingBkg@3x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/RecordingSignal001@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/RecordingSignal001@2x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/RecordingSignal001@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/RecordingSignal001@3x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/RecordingSignal002@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/RecordingSignal002@2x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/RecordingSignal002@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/RecordingSignal002@3x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/RecordingSignal003@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/RecordingSignal003@2x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/RecordingSignal003@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/RecordingSignal003@3x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/RecordingSignal004@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/RecordingSignal004@2x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/RecordingSignal004@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/RecordingSignal004@3x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/RecordingSignal005@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/RecordingSignal005@2x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/RecordingSignal005@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/RecordingSignal005@3x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/RecordingSignal006@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/RecordingSignal006@2x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/RecordingSignal006@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/RecordingSignal006@3x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/RecordingSignal007@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/RecordingSignal007@2x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/RecordingSignal007@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/RecordingSignal007@3x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/RecordingSignal008@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/RecordingSignal008@2x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/RecordingSignal008@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/RecordingSignal008@3x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/SenderVoiceNodePlaying000@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/SenderVoiceNodePlaying000@2x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/SenderVoiceNodePlaying001@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/SenderVoiceNodePlaying001@2x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/SenderVoiceNodePlaying002@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/SenderVoiceNodePlaying002@2x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/SenderVoiceNodePlaying003@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/SenderVoiceNodePlaying003@2x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/SenderVoiceNodePlaying@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/SenderVoiceNodePlaying@2x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/ToolViewEmotion@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/ToolViewEmotion@2x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/ToolViewEmotion@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/ToolViewEmotion@3x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/ToolViewEmotionHL@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/ToolViewEmotionHL@2x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/ToolViewEmotionHL@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/ToolViewEmotionHL@3x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/ToolViewInputVoice@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/ToolViewInputVoice@2x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/ToolViewInputVoice@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/ToolViewInputVoice@3x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/ToolViewInputVoiceHL@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/ToolViewInputVoiceHL@2x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/ToolViewInputVoiceHL@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/ToolViewInputVoiceHL@3x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/ToolViewKeyboard@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/ToolViewKeyboard@2x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/ToolViewKeyboard@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/ToolViewKeyboard@3x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/ToolViewKeyboardHL@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/ToolViewKeyboardHL@2x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/ToolViewKeyboardHL@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/ToolViewKeyboardHL@3x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/TypeSelectorBtnHL_Black@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/TypeSelectorBtnHL_Black@2x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/TypeSelectorBtnHL_Black@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/TypeSelectorBtnHL_Black@3x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/TypeSelectorBtn_Black@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/TypeSelectorBtn_Black@2x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/TypeSelectorBtn_Black@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/TypeSelectorBtn_Black@3x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/chat_bar_icons_camera@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/chat_bar_icons_camera@3x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/chat_bar_icons_location@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/chat_bar_icons_location@3x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/chat_bar_icons_pic@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/chat_bar_icons_pic@3x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/dialog_bubble_other@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/dialog_bubble_other@2x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/header_male@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/header_male@2x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/news-bg-card-me@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/news-bg-card-me@2x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/news-bg-me@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/news-bg-me@2x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/refresh_icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/refresh_icon@2x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/Resource/WBUI.bundle/refresh_icon@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/Resource/WBUI.bundle/refresh_icon@3x.png -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ServiceSDK/Core/Base/Protocol/WBDBCreater.h: -------------------------------------------------------------------------------- 1 | // 2 | // OPDBCreater.h 3 | 4 | #import 5 | 6 | @protocol WBDBCreater 7 | 8 | @required 9 | // 初次创建数据库表 10 | - (BOOL)createDBTable; 11 | 12 | @optional 13 | - (BOOL)expandDBTable:(int)oldVersion; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ServiceSDK/Core/Base/Protocol/WBTerminateHandler.h: -------------------------------------------------------------------------------- 1 | // 2 | // OPTerminateHandler.h 3 | 4 | #import 5 | 6 | @protocol WBTerminateHandler 7 | 8 | @required 9 | - (void)onApplicationWillTerminateTask; 10 | 11 | @end 12 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ServiceSDK/Core/Base/WBCoreRegister.h: -------------------------------------------------------------------------------- 1 | // 2 | // WBCoreRegister.h 3 | 4 | #import 5 | #import "WBSynthesizeSingleton.h" 6 | 7 | @interface WBCoreRegister : NSObject 8 | 9 | WB_SYNTHESIZE_SINGLETON_FOR_CLASS_HEADER(WBCoreRegister) 10 | 11 | @end 12 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ServiceSDK/Core/Base/WBCoreRegister.m: -------------------------------------------------------------------------------- 1 | // 2 | // WBCoreRegister.m 3 | 4 | #import "WBCoreRegister.h" 5 | #import "WBDBClient.h" 6 | #import "WBManagerHeaders.h" 7 | 8 | @implementation WBCoreRegister 9 | 10 | WB_SYNTHESIZE_SINGLETON_FOR_CLASS(WBCoreRegister) 11 | 12 | - (instancetype)init 13 | { 14 | self = [super init]; 15 | if (self) { 16 | 17 | // 创建表 18 | [self registerCreater]; 19 | 20 | // 程序终止后需要处理的事项 21 | [self registerTerminateHandler]; 22 | } 23 | return self; 24 | } 25 | 26 | 27 | - (void)registerCreater{ 28 | [[WBDBClient sharedInstance] registerDBCreater:[WBChatListManager sharedInstance]]; 29 | [[WBDBClient sharedInstance] registerDBCreater:[WBChatManager sharedInstance]]; 30 | } 31 | 32 | - (void)registerTerminateHandler{ 33 | 34 | 35 | } 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ServiceSDK/Core/Base/WBDBClient.h: -------------------------------------------------------------------------------- 1 | // 2 | // OPDBClient.h 3 | 4 | #import 5 | #import 6 | #import 7 | #import "WBSynthesizeSingleton.h" 8 | #import "WBCoreConfiguration.h" 9 | 10 | #define WBDBClientSqlQueue [WBDBClient sharedInstance].sqliteQueue 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | @interface WBDBClient : NSObject 14 | @property (nonatomic, strong) dispatch_queue_t sqliteQueue; 15 | 16 | @property (nonatomic, strong) FMDatabaseQueue *dbQueue; 17 | 18 | 19 | @property (nonatomic, strong) NSMutableArray *dbCreaters; // OPDBCreater 20 | @property (nonatomic, strong) NSMutableArray *terminateHandlers; // OPTerminateHandler 21 | 22 | // 创建单利 23 | WB_SYNTHESIZE_SINGLETON_FOR_CLASS_HEADER(WBDBClient); 24 | 25 | 26 | #pragma mark - About DB 27 | 28 | - (void)openDB:(NSString *)userId; 29 | 30 | - (void)closeDB; 31 | 32 | 33 | #pragma mark - Start 34 | - (void)createTable; 35 | - (void)extendTable:(int)version; 36 | 37 | - (void)registerDBCreater:(id)creater; 38 | - (void)registerTerminateHandler:(id)handler; 39 | 40 | -(void)doTerminateHandlerTask; 41 | @end 42 | 43 | NS_ASSUME_NONNULL_END 44 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ServiceSDK/Core/Base/WBUserManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // WBUserManager.h 3 | 4 | #import 5 | #import "WBSynthesizeSingleton.h" 6 | 7 | @interface WBUserManager : NSObject 8 | 9 | WB_SYNTHESIZE_SINGLETON_FOR_CLASS_HEADER(WBUserManager) 10 | 11 | @property (nonatomic, copy) NSString * _Nullable clientId; 12 | 13 | 14 | /** 15 | 打开数据库 16 | */ 17 | - (void)openDB; 18 | 19 | 20 | /** 21 | 关闭数据库 22 | */ 23 | - (void)closeDB; 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ServiceSDK/Core/Base/WBUserManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // WBUserManager.m 3 | 4 | 5 | #import "WBUserManager.h" 6 | #import "WBCoreConfiguration.h" 7 | #import "WBBackgroundManager.h" 8 | 9 | @implementation WBUserManager 10 | 11 | WB_SYNTHESIZE_SINGLETON_FOR_CLASS(WBUserManager) 12 | 13 | - (instancetype)init 14 | { 15 | self = [super init]; 16 | if (self) { 17 | [WBCoreRegister sharedInstance]; 18 | [WBBackgroundManager sharedInstance]; 19 | } 20 | return self; 21 | } 22 | 23 | #pragma mark - DB 24 | - (void)openDB{ 25 | 26 | if (!self.clientId.length) { 27 | return; 28 | } 29 | 30 | [[WBDBClient sharedInstance] openDB:self.clientId]; 31 | [[WBDBClient sharedInstance] createTable]; 32 | } 33 | 34 | - (void)closeDB{ 35 | [[WBDBClient sharedInstance] closeDB]; 36 | } 37 | 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ServiceSDK/Core/Category/AVCategory/AVIMConversation+WBExtension.h: -------------------------------------------------------------------------------- 1 | // 2 | // AVIMConversation+WBExtension.h 3 | // AVOSCloud 4 | // 5 | // Created by RedRain on 2018/3/14. 6 | // 7 | 8 | #import 9 | #import "WBIMDefine.h" 10 | @interface AVIMConversation (WBExtension) 11 | 12 | /** 13 | 得到会话的类型 14 | 15 | @return 会话类型 16 | */ 17 | - (WBConversationType)wb_conversationType; 18 | @end 19 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ServiceSDK/Core/Category/AVCategory/AVIMConversation+WBExtension.m: -------------------------------------------------------------------------------- 1 | // 2 | // AVIMConversation+WBExtension.m 3 | // AVOSCloud 4 | // 5 | // Created by RedRain on 2018/3/14. 6 | // 7 | 8 | #import "AVIMConversation+WBExtension.h" 9 | 10 | 11 | @implementation AVIMConversation (WBExtension) 12 | - (WBConversationType)wb_conversationType{ 13 | NSNumber *type = self.attributes[WBIM_CONVERSATION_TYPE]; 14 | return type ? type.integerValue : WBConversationTypeSingle; 15 | } 16 | @end 17 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ServiceSDK/Core/Category/AVCategory/AVIMMessage+WBExtension.h: -------------------------------------------------------------------------------- 1 | // 2 | // AVIMMessage+WBExtension.h 3 | 4 | 5 | #import 6 | 7 | @interface AVIMMessage (WBExtension) 8 | 9 | - (AVIMTypedMessage *)wb_getValidTypedMessage; 10 | - (BOOL)wb_isValidMessage; 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ServiceSDK/Core/Category/AVCategory/AVIMMessage+WBExtension.m: -------------------------------------------------------------------------------- 1 | // 2 | // AVIMMessage+WBExtension.m 3 | 4 | #import "AVIMMessage+WBExtension.h" 5 | #import "NSBundle+LCCKExtension.h" 6 | #import "WBIMDefine.h" 7 | #import "WBServiceSDKHeaders.h" 8 | 9 | 10 | @implementation AVIMMessage (WBExtension) 11 | 12 | - (BOOL)wb_isValidMessage { 13 | id messageToCheck = (id)self; 14 | if (!messageToCheck || messageToCheck == [NSNull null]) { 15 | return NO; 16 | } 17 | return YES; 18 | } 19 | 20 | - (AVIMTypedMessage *)wb_getValidTypedMessage { 21 | if (!self.wb_isValidMessage) { 22 | return nil; 23 | } 24 | if ([self isKindOfClass:[AVIMTypedMessage class]]) { 25 | return (AVIMTypedMessage *)self; 26 | } 27 | NSString *messageText; 28 | NSDictionary *attr; 29 | if ([[self class] isSubclassOfClass:[AVIMMessage class]]) { 30 | //当存在无法识别的自定义消息,SDK会返回 AVIMMessage 类型 31 | AVIMMessage *message = self; 32 | NSString *jsonString = message.content; 33 | NSDictionary *json = [jsonString wb_JSONValue]; 34 | do { 35 | NSString *customMessageDegradeKey = [json valueForKey:@"_lctext"]; 36 | if (customMessageDegradeKey.length > 0) { 37 | messageText = customMessageDegradeKey; 38 | break; 39 | } 40 | attr = [json valueForKey:@"_lcattrs"]; 41 | NSString *customMessageAttrDegradeKey = [attr valueForKey:WBIMCustomMessageDegradeKey]; 42 | if (customMessageAttrDegradeKey.length > 0) { 43 | messageText = customMessageAttrDegradeKey; 44 | break; 45 | } 46 | messageText = WBIMLocalizedStrings(@"unknownMessage"); 47 | break; 48 | } while (NO); 49 | } 50 | AVIMTextMessage *typedMessage = [AVIMTextMessage messageWithText:messageText attributes:attr]; 51 | [typedMessage setValue:self.conversationId forKey:@"conversationId"]; 52 | [typedMessage setValue:self.messageId forKey:@"messageId"]; 53 | [typedMessage setValue:@(self.sendTimestamp) forKey:@"sendTimestamp"]; 54 | [typedMessage setValue:self.clientId forKey:@"clientId"]; 55 | 56 | [typedMessage wb_setAttributesObject:@(YES) forKey:WBIMCustomMessageIsCustomKey]; 57 | return typedMessage; 58 | } 59 | @end 60 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ServiceSDK/Core/Category/AVCategory/AVIMTypedMessage+WBExtension.h: -------------------------------------------------------------------------------- 1 | // 2 | // AVIMTypedMessage+WBExtension.h 3 | // WBChat 4 | 5 | #import 6 | #import "WBMessageModel.h" 7 | @interface AVIMTypedMessage (WBExtension) 8 | 9 | - (void)wb_setAttributesObject:(id)object forKey:(NSString *)key; 10 | 11 | - (WBChatMessageType)messageType_wb; 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ServiceSDK/Core/Category/AVCategory/AVIMTypedMessage+WBExtension.m: -------------------------------------------------------------------------------- 1 | // 2 | // AVIMTypedMessage+WBExtension.m 3 | 4 | #import "AVIMTypedMessage+WBExtension.h" 5 | 6 | @implementation AVIMTypedMessage (WBExtension) 7 | - (void)wb_setAttributesObject:(id)object forKey:(NSString *)key { 8 | NSMutableDictionary *attributes = [NSMutableDictionary dictionary]; 9 | [attributes setObject:object forKey:key]; 10 | if (self.attributes == nil) { 11 | self.attributes = attributes; 12 | } else { 13 | [attributes addEntriesFromDictionary:self.attributes]; 14 | self.attributes = attributes; 15 | } 16 | self.attributes = attributes; 17 | } 18 | 19 | - (WBChatMessageType)messageType_wb{ 20 | return self.mediaType; 21 | } 22 | @end 23 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ServiceSDK/Core/Category/Foundation/FMDatabase+WBAutoSql.h: -------------------------------------------------------------------------------- 1 | // 2 | // FMDatabase+WBAutoSql.h 3 | // WBChat 4 | // 5 | // Created by RedRain on 2018/1/17. 6 | // Copyright © 2018年 RedRain. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface FMDatabase (WBAutoSql) 12 | 13 | - (BOOL)creatTableByTableName:(NSString *)tableName Model:(id)model; 14 | - (BOOL)creatTableByTableName:(NSString *)tableName Model:(id)model othersFields:(NSArray *)fieldsArray; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ServiceSDK/Core/Category/Foundation/FMDatabase+WBAutoSql.m: -------------------------------------------------------------------------------- 1 | // 2 | // FMDatabase+WBAutoSql.m 3 | // WBChat 4 | // 5 | // Created by RedRain on 2018/1/17. 6 | // Copyright © 2018年 RedRain. All rights reserved. 7 | // 8 | 9 | #import "FMDatabase+WBAutoSql.h" 10 | #import 11 | 12 | @implementation FMDatabase (WBAutoSql) 13 | 14 | 15 | /** 16 | 根据model,新建表格 17 | */ 18 | - (BOOL)creatTableByTableName:(NSString *)tableName Model:(id)model 19 | { 20 | 21 | return [self creatTableByTableName:tableName Model:model othersFields:nil]; 22 | 23 | } 24 | 25 | - (BOOL)creatTableByTableName:(NSString *)tableName Model:(id)model othersFields:(NSArray *)fieldsArray 26 | { 27 | NSArray * attrArray = [self getAllProperties:model]; 28 | //创建表格 29 | NSMutableDictionary *dic = [NSMutableDictionary dictionary]; 30 | 31 | for (id value in attrArray) { 32 | [dic setObject:@"TEXT" forKey:value]; 33 | } 34 | 35 | if (fieldsArray != nil) { 36 | for (NSDictionary *field in fieldsArray) { 37 | NSString *key = field.allKeys.firstObject; 38 | id value = field[key]; 39 | if (key && value) { 40 | [dic setObject:value forKey:key]; 41 | } 42 | } 43 | } 44 | 45 | BOOL result = [self createDatabaseTales:tableName field:dic]; 46 | 47 | return result; 48 | } 49 | 50 | 51 | //获取本类所有属性 52 | - (NSArray *)getAllProperties:(id)model 53 | { 54 | u_int count; 55 | 56 | objc_property_t *properties =class_copyPropertyList([model class], &count); 57 | 58 | NSMutableArray *propertiesArray = [NSMutableArray arrayWithCapacity:count]; 59 | 60 | for (int i = 0; i < count ; i++) 61 | { 62 | const char* propertyName =property_getName(properties[i]); 63 | [propertiesArray addObject: [NSString stringWithUTF8String: propertyName]]; 64 | } 65 | 66 | free(properties); 67 | 68 | return propertiesArray; 69 | } 70 | 71 | // 创建数据库表格 72 | - (BOOL)createDatabaseTales:(NSString *)tableName field:(NSDictionary *)field{ 73 | 74 | NSMutableString *sql = [NSMutableString stringWithFormat:@"CREATE TABLE IF NOT EXISTS %@ (keyId integer PRIMARY KEY AUTOINCREMENT",tableName]; 75 | 76 | NSArray *arr = [field allKeys]; 77 | 78 | for (NSInteger i = 0; i < arr.count; i++) { 79 | 80 | if (i == arr.count-1) { 81 | NSString *value = [field valueForKey:arr[i]]; 82 | 83 | NSString *str = [NSString stringWithFormat:@",%@ %@)",arr[i],value]; 84 | 85 | [sql appendString:str]; 86 | 87 | }else{ 88 | 89 | NSString *value = [field valueForKey:arr[i]]; 90 | 91 | NSString *str = [NSString stringWithFormat:@",%@ %@",arr[i],value]; 92 | [sql appendString:str]; 93 | } 94 | } 95 | if (self.open) { 96 | BOOL b =[self executeUpdate:sql]; 97 | 98 | if (b) { 99 | 100 | return YES; 101 | } 102 | } 103 | 104 | //OPLog(@"表格创建失败"); 105 | 106 | return NO; 107 | } 108 | @end 109 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ServiceSDK/Core/Category/Foundation/NSBundle+LCCKExtension.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSBundle+LCCKExtension.h 3 | 4 | #import 5 | 6 | @interface NSBundle (LCCKExtension) 7 | 8 | + (NSBundle *)lcck_bundleForName:(NSString *)bundleName class:(Class)aClass; 9 | 10 | @end 11 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ServiceSDK/Core/Category/Foundation/NSBundle+LCCKExtension.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSBundle+LCCKExtension.m 3 | 4 | #import "NSBundle+LCCKExtension.h" 5 | 6 | @implementation NSBundle (LCCKExtension) 7 | 8 | + (NSString *)lcck_bundlePathForBundleName:(NSString *)bundleName class:(Class)aClass { 9 | NSString *pathComponent = [NSString stringWithFormat:@"%@.bundle", bundleName]; 10 | NSString *bundlePath =[[[NSBundle bundleForClass:aClass] resourcePath] stringByAppendingPathComponent:pathComponent]; 11 | return bundlePath; 12 | } 13 | 14 | + (NSString *)lcck_customizedBundlePathForBundleName:(NSString *)bundleName { 15 | NSString *customizedBundlePathComponent = [NSString stringWithFormat:@"CustomizedChatKit.%@.bundle", bundleName]; 16 | NSString *customizedBundlePath =[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:customizedBundlePathComponent]; 17 | return customizedBundlePath; 18 | } 19 | 20 | + (NSBundle *)lcck_bundleForName:(NSString *)bundleName class:(Class)aClass { 21 | NSString *customizedBundlePath = [NSBundle lcck_customizedBundlePathForBundleName:bundleName]; 22 | NSBundle *customizedBundle = [NSBundle bundleWithPath:customizedBundlePath]; 23 | if (customizedBundle) { 24 | return customizedBundle; 25 | } 26 | NSString *bundlePath = [NSBundle lcck_bundlePathForBundleName:bundleName class:aClass]; 27 | NSBundle *bundle = [NSBundle bundleWithPath:bundlePath]; 28 | return bundle; 29 | } 30 | 31 | @end 32 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ServiceSDK/Core/Category/Foundation/NSDate+WBExt.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSDate+WBExt.h 3 | // WBChat 4 | // 5 | // Created by RedRain on 2018/1/17. 6 | // Copyright © 2018年 RedRain. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSDate (WBExt) 12 | + (NSString *)wb_currentTimeStamp; 13 | - (NSString *)wb_currentTimeStamp; 14 | @end 15 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ServiceSDK/Core/Category/Foundation/NSDate+WBExt.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSDate+WBExt.m 3 | // WBChat 4 | // 5 | // Created by RedRain on 2018/1/17. 6 | // Copyright © 2018年 RedRain. All rights reserved. 7 | // 8 | 9 | #import "NSDate+WBExt.h" 10 | 11 | @implementation NSDate (WBExt) 12 | + (NSString *)wb_currentTimeStamp{ 13 | return @([[NSDate date]timeIntervalSince1970] * 1000).stringValue; 14 | } 15 | - (NSString *)wb_currentTimeStamp{ 16 | return @([self timeIntervalSince1970] * 1000).stringValue; 17 | } 18 | @end 19 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ServiceSDK/Core/Category/Foundation/NSError+WBError.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSError+WBError.h 3 | 4 | 5 | #import 6 | 7 | @interface NSError (WBError) 8 | + (instancetype)wb_description:(NSString *)desc; 9 | - (NSString *)wb_localizedDesc; 10 | @end 11 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ServiceSDK/Core/Category/Foundation/NSError+WBError.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSError+WBError.m 3 | 4 | #import "NSError+WBError.h" 5 | 6 | @implementation NSError (WBError) 7 | + (instancetype)wb_description:(NSString *)desc{ 8 | desc = desc ? : @"发生了未知的错误"; 9 | return [NSError errorWithDomain:@"WBChatKitErrorDomain" 10 | code:0 11 | userInfo:@{NSLocalizedDescriptionKey:desc}]; 12 | } 13 | 14 | - (NSString *)wb_localizedDesc{ 15 | return self.userInfo[NSLocalizedDescriptionKey]; 16 | } 17 | @end 18 | 19 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ServiceSDK/Core/Category/Foundation/NSObject+WBExtension.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSObject+WBExtension.h 3 | 4 | #import 5 | 6 | @interface NSObject (WBExtension) 7 | 8 | - (NSDictionary *)wb_JSONValue; 9 | 10 | @end 11 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ServiceSDK/Core/Category/Foundation/NSObject+WBExtension.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSObject+WBExtension.m 3 | 4 | 5 | #import "NSObject+WBExtension.h" 6 | 7 | @implementation NSObject (WBExtension) 8 | 9 | - (NSDictionary *)wb_JSONValue { 10 | if (!self) { return nil; } 11 | id result = nil; 12 | NSError* error = nil; 13 | if ([self isKindOfClass:[NSString class]]) { 14 | if ([(NSString *)self length] == 0) { return nil; } 15 | NSData *dataToBeParsed = [(NSString *)self dataUsingEncoding:NSUTF8StringEncoding]; 16 | result = [NSJSONSerialization JSONObjectWithData:dataToBeParsed options:kNilOptions error:&error]; 17 | } else { 18 | result = [NSJSONSerialization JSONObjectWithData:(NSData *)self options:kNilOptions error:&error]; 19 | } 20 | if (![result isKindOfClass:[NSDictionary class]]) { 21 | return nil; 22 | } 23 | return result; 24 | } 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ServiceSDK/Core/Category/Foundation/UIImage+WBScaleExtension.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+LCCKExtension.h 3 | // LeanCloudChatKit-iOS 4 | // 5 | // v0.8.5 Created by ElonChan on 16/5/7. 6 | // Copyright © 2016年 LeanCloud. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIImage (WBScaleExtension) 12 | 13 | - (UIImage *)wb_imageByScalingAspectFill; 14 | /*! 15 | * @attention This will invoke `CGSize kMaxImageViewSize = {.width = 200, .height = 200};`. 16 | */ 17 | - (UIImage *)wb_imageByScalingAspectFillWithOriginSize:(CGSize)originSize; 18 | 19 | - (UIImage *)wb_imageByScalingAspectFillWithOriginSize:(CGSize)originSize 20 | limitSize:(CGSize)limitSize; 21 | 22 | 23 | - (UIImage *)wb_scalingPatternImageToSize:(CGSize)size; 24 | 25 | 26 | - (NSData *)wb_compressWithMaxKBytes:(NSUInteger)maxLength; 27 | @end 28 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ServiceSDK/Core/Tool/WBCoreConfiguration.h: -------------------------------------------------------------------------------- 1 | // 2 | // WBCoreConfiguration.h 3 | 4 | #ifndef WBCoreConfiguration_h 5 | #define WBCoreConfiguration_h 6 | 7 | // 分类 8 | #import "NSError+WBError.h" 9 | #import "AVIMMessage+WBExtension.h" 10 | #import "AVIMTypedMessage+WBExtension.h" 11 | #import "NSObject+WBExtension.h" 12 | #import "NSDate+WBExt.h" 13 | 14 | 15 | 16 | #import "WBDBCreater.h" 17 | #import "WBTerminateHandler.h" 18 | 19 | #import "WBDBClient.h" 20 | #import "WBCoreRegister.h" 21 | #import "WBUserManager.h" 22 | #import "WBSynthesizeSingleton.h" 23 | #import "FMDatabase+WBAutoSql.h" 24 | 25 | #endif /* WBCoreConfiguration_h */ 26 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ServiceSDK/Core/Tool/WBManagerHeaders.h: -------------------------------------------------------------------------------- 1 | // 2 | // WBManagerHeaders.h 3 | 4 | #ifndef WBManagerHeaders_h 5 | #define WBManagerHeaders_h 6 | 7 | #import "WBCoreConfiguration.h" 8 | 9 | #import "WBUserManager.h" 10 | 11 | #import "WBChatListModel.h" 12 | #import "WBChatListManager.h" 13 | 14 | #import "WBMessageModel.h" 15 | #import "WBChatManager.h" 16 | #import "WBBackgroundManager.h" 17 | #import "WBChatInfoModel.h" 18 | 19 | // 收到消息后处理类 20 | #import "WBMessageManager.h" 21 | 22 | // 文件处理 23 | #import "WBFileManager.h" 24 | #import "WBPathManager.h" 25 | #import "WBNamedTool.h" 26 | 27 | 28 | #endif /* WBManagerHeaders_h */ 29 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ServiceSDK/Core/Tool/WBSynthesizeSingleton.h: -------------------------------------------------------------------------------- 1 | // 2 | // WBSynthesizeSingleton.h 3 | 4 | #if __has_feature(objc_arc) 5 | 6 | #define WB_SYNTHESIZE_SINGLETON_FOR_CLASS_HEADER(classname) \ 7 | \ 8 | + (classname * _Nullable)sharedInstance; 9 | 10 | #define WB_SYNTHESIZE_SINGLETON_FOR_CLASS(classname) \ 11 | \ 12 | static classname *shared##classname = nil; \ 13 | \ 14 | + (classname *)sharedInstance \ 15 | { \ 16 | static dispatch_once_t pred; \ 17 | dispatch_once(&pred, ^{ shared##classname = [[classname alloc] init]; }); \ 18 | return shared##classname; \ 19 | } 20 | 21 | #else 22 | 23 | #define WB_SYNTHESIZE_SINGLETON_FOR_CLASS_HEADER(classname) \ 24 | \ 25 | + (classname *)sharedInstance; 26 | 27 | #define SYNTHESIZE_SINGLETON_FOR_CLASS(classname) \ 28 | \ 29 | static classname *shared##classname = nil; \ 30 | \ 31 | + (classname *)sharedInstance \ 32 | { \ 33 | static dispatch_once_t pred; \ 34 | dispatch_once(&pred, ^{ shared##classname = [[classname alloc] init]; }); \ 35 | return shared##classname; \ 36 | } \ 37 | \ 38 | - (id)copyWithZone:(NSZone *)zone \ 39 | { \ 40 | return self; \ 41 | } \ 42 | \ 43 | - (id)retain \ 44 | { \ 45 | return self; \ 46 | } \ 47 | \ 48 | - (NSUInteger)retainCount \ 49 | { \ 50 | return NSUIntegerMax; \ 51 | } \ 52 | \ 53 | - (oneway void)release \ 54 | { \ 55 | } \ 56 | \ 57 | - (id)autorelease \ 58 | { \ 59 | return self; \ 60 | } 61 | 62 | #endif 63 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ServiceSDK/Core/Tool/WBUserDefaults.h: -------------------------------------------------------------------------------- 1 | // 2 | // WBUserDefaults.h 3 | 4 | #import 5 | 6 | @interface WBUserDefaults : NSObject 7 | 8 | /** 9 | 是否可以使用摇一摇显示VC信息 10 | */ 11 | + (void)saveShakeState:(BOOL)isShaked; 12 | + (BOOL)getShakeState; 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ServiceSDK/Core/Tool/WBUserDefaults.m: -------------------------------------------------------------------------------- 1 | // 2 | // WBUserDefaults.m 3 | #import "WBUserDefaults.h" 4 | 5 | #define kWBShakeState @"kWBShakeState" 6 | 7 | #define WBStandardUserDefaults ([NSUserDefaults standardUserDefaults]) 8 | 9 | @implementation WBUserDefaults 10 | 11 | /** 12 | 是否可以使用摇一摇显示VC信息 13 | */ 14 | + (void)saveShakeState:(BOOL)isShaked{ 15 | [WBStandardUserDefaults setBool:isShaked forKey:kWBShakeState]; 16 | } 17 | + (BOOL)getShakeState{ 18 | return [WBStandardUserDefaults boolForKey:kWBShakeState]; 19 | } 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ServiceSDK/Manager/Background/WBBackgroundManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // WBBackgroundManager.h 3 | // WBChat 4 | // 5 | // Created by RedRain on 2018/1/16. 6 | // Copyright © 2018年 RedRain. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "WBServiceSDKHeaders.h" 11 | 12 | 13 | 14 | @interface WBBackgroundManager : NSObject 15 | WB_SYNTHESIZE_SINGLETON_FOR_CLASS_HEADER(WBBackgroundManager) 16 | 17 | 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ServiceSDK/Manager/Background/WBBackgroundManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // WBBackgroundManager.m 3 | // WBChat 4 | // 5 | // Created by RedRain on 2018/1/16. 6 | // Copyright © 2018年 RedRain. All rights reserved. 7 | // 8 | 9 | #import "WBBackgroundManager.h" 10 | 11 | @implementation WBBackgroundManager 12 | WB_SYNTHESIZE_SINGLETON_FOR_CLASS(WBBackgroundManager) 13 | 14 | - (instancetype)init 15 | { 16 | self = [super init]; 17 | if (self) { 18 | [self notificationName:WBIMNotificationConnectivityUpdated action:@selector(connectivityUpdated)]; 19 | } 20 | return self; 21 | } 22 | 23 | - (void)notificationName:(NSString *)name action:(SEL)action{ 24 | [[NSNotificationCenter defaultCenter] addObserver:self selector:action name:name object:nil]; 25 | } 26 | 27 | - (void)pushNotificationName:(NSString *)name{ 28 | [[NSNotificationCenter defaultCenter] postNotificationName:name object:nil userInfo:nil]; 29 | } 30 | 31 | #pragma mark - Notification Action 32 | - (void)connectivityUpdated{ 33 | 34 | if ([WBChatKit sharedInstance].connectStatus == AVIMClientStatusOpened) { 35 | 36 | // [[WBChatListManager sharedInstance] fetchAllConversationsFromServer:^(NSArray * _Nullable conersations, 37 | // NSError * _Nullable error) 38 | // { 39 | // if (error == nil) { 40 | // } 41 | // }]; 42 | } 43 | } 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ServiceSDK/Manager/Chat/Dao/WBChatInfoDao.h: -------------------------------------------------------------------------------- 1 | // 2 | // WBChatInfoDao.h 3 | // WBChat 4 | // 5 | // Created by RedRain on 2018/1/18. 6 | // Copyright © 2018年 RedRain. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "WBCoreConfiguration.h" 11 | #import "WBChatInfoModel.h" 12 | 13 | #define WBChatInfoDaoTableName @"t_ChatInfo" 14 | #define WBChatInfoDaoKeyDraft @"draft" 15 | #define WBChatInfoDaoKeyTopTime @"topTime" 16 | #define WBChatInfoDaoKeyId @"conversationID" 17 | #define WBChatInfoDaoKeyBGFileID @"conversationBGFileID" 18 | #define WBChatInfoDaoKeyExtend @"extend" 19 | 20 | NS_ASSUME_NONNULL_BEGIN 21 | @interface WBChatInfoDao : NSObject 22 | WB_SYNTHESIZE_SINGLETON_FOR_CLASS_HEADER(WBChatInfoDao) 23 | 24 | - (BOOL)createDBTable; 25 | 26 | /** 27 | 根据conversationId,删除一个本地的会话 28 | */ 29 | - (BOOL)deleteConversation:(NSString *)conversationId; 30 | 31 | - (WBChatInfoModel *)chatInfoWithID:(NSString *)conversationId; 32 | 33 | - (BOOL)saveConversation:(NSString *)conversationId draft:(NSString *)draft; 34 | 35 | @end 36 | NS_ASSUME_NONNULL_END 37 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ServiceSDK/Manager/Chat/WBChatManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // WBChatManager.h 3 | // WBChat 4 | // 5 | // Created by RedRain on 2018/1/16. 6 | // Copyright © 2018年 RedRain. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "WBCoreConfiguration.h" 11 | #import 12 | #import 13 | #import "WBChatInfoModel.h" 14 | 15 | @class WBMessageModel; 16 | 17 | NS_ASSUME_NONNULL_BEGIN 18 | 19 | @interface WBChatManager : NSObject 20 | WB_SYNTHESIZE_SINGLETON_FOR_CLASS_HEADER(WBChatManager) 21 | 22 | #pragma mark - 创建一个Conversation 23 | 24 | /** 25 | 根据传入姓名和成员,获取到相应的Conversation对象 26 | 27 | @param name 会话的名称 28 | @param members 成员clientId的数组 29 | @param reuseConversation 是否复用 `AVIMConversation` 30 | */ 31 | - (void)createConversationWithName:(NSString *)name 32 | members:(NSArray *)members 33 | reuseConversation:(BOOL)reuseConversation 34 | callback:(AVIMConversationResultBlock)callback; 35 | 36 | #pragma mark - 往对话中发送消息。 37 | /*! 38 | 往对话中发送消息。 39 | @param message - 消息对象 40 | @param callback - 结果回调 41 | */ 42 | - (void)sendTargetConversation:(AVIMConversation *)targetConversation 43 | message:(WBMessageModel *)message 44 | callback:(AVIMBooleanResultBlock)callback; 45 | 46 | 47 | #pragma mark - 加载聊天记录 48 | /** 49 | 加载聊天记录 50 | 51 | @param conversation 对应的会话 52 | @param queryMessage 锚点message, 如果是nil:(该方法能确保在有网络时总是从服务端拉取最新的消息,首次拉取必须使用是nil或者sendTimestamp为0) 53 | @param limit 拉取的条数 54 | */ 55 | - (void)queryTypedMessagesWithConversation:(AVIMConversation *)conversation 56 | queryMessage:(AVIMMessage * _Nullable)queryMessage 57 | limit:(NSInteger)limit 58 | block:(AVIMArrayResultBlock)block; 59 | 60 | #pragma mark - 获取会话的信息 61 | - (WBChatInfoModel *)chatInfoWithID:(NSString *)conversationId; 62 | 63 | #pragma mark - 草稿 64 | - (BOOL)saveConversation:(NSString *)conversationId draft:(NSString *)draft; 65 | @end 66 | NS_ASSUME_NONNULL_END 67 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ServiceSDK/Manager/Chat/WBMessageModel/WBChatInfoModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // WBChatInfoModel.h 3 | // WBChat 4 | // 5 | // Created by RedRain on 2018/3/9. 6 | // Copyright © 2018年 RedRain. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface WBChatInfoModel : NSObject 12 | 13 | @property (nonatomic, copy) NSString *conversationID; ///< 会话ID 14 | @property (nonatomic, copy) NSString *draft; ///< 会话 草稿 15 | @property (nonatomic, strong) NSString *conversationBGFileID; // 会话页面背景图片 16 | @property (nonatomic, assign) NSTimeInterval topTime; ///< 置顶的时间 17 | @property (nonatomic, copy) NSString *extend; ///< 扩展使用 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ServiceSDK/Manager/Chat/WBMessageModel/WBChatInfoModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // WBChatInfoModel.m 3 | // WBChat 4 | // 5 | // Created by RedRain on 2018/3/9. 6 | // Copyright © 2018年 RedRain. All rights reserved. 7 | // 8 | 9 | #import "WBChatInfoModel.h" 10 | 11 | @implementation WBChatInfoModel 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ServiceSDK/Manager/Chat/WBMessageModel/WBMessageModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // WBMessageModel.h 3 | // WBChat 4 | // 5 | // Created by RedRain on 2018/1/26. 6 | // Copyright © 2018年 RedRain. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | typedef NS_ENUM(NSUInteger, WBChatMessageType) { 13 | WBChatMessageTypeUnknow = 0, 14 | WBChatMessageTypeText = -1, 15 | WBChatMessageTypeImage = -2 , 16 | WBChatMessageTypeAudio = -3, 17 | WBChatMessageTypeVideo = -4, 18 | WBChatMessageTypeLocation = -5, 19 | WBChatMessageTypeFile = -6, 20 | WBChatMessageTypeRecalled = -127,// 回撤消息 21 | 22 | WBChatMessageTypeTime = 50, // 时间 23 | WBChatMessageTypeNoMoreMessage = 51, // 没有更多消息了 24 | WBChatMessageTypeUnderLineNewMessage = 52, // 以下是最新消息 25 | WBChatMessageTypeNotification = 53, // 通知类 26 | WBChatMessageTypeCallHint = 54, // 提示 27 | WBChatMessageTypeCardInfo = 55, // 个人名片 28 | WBChatMessageTypePSRichContent = 56, // 公众号单图文 29 | WBChatMessageTypePSMultiRichContent = 57, // 公众号多图文 30 | WBChatMessageTypeRichContent = 58 // 单链接 31 | }; 32 | 33 | @interface WBMessageModel : NSObject 34 | 35 | @property (nonatomic, assign) WBChatMessageType messageType; 36 | /*! 37 | * 表示消息状态 38 | */ 39 | @property (nonatomic, assign) AVIMMessageStatus status; 40 | 41 | 42 | @property (nonatomic, strong) AVIMTypedMessage *content; 43 | 44 | 45 | 46 | + (instancetype)createWithTypedMessage:(AVIMTypedMessage *)message; 47 | 48 | 49 | 50 | /** 51 | 发送消息时,创建模型 52 | 53 | @param text 发送内容 54 | */ 55 | + (instancetype)createWithText:(NSString *)text; 56 | 57 | 58 | 59 | /** 60 | 生成适配的发送model 61 | 62 | @param image 需要发送的image 63 | */ 64 | + (instancetype)createWithImage:(UIImage *)image; 65 | 66 | @property (nonatomic, strong) UIImage *thumbImage; 67 | @property (nonatomic, copy) NSString *imagePath; 68 | 69 | 70 | /** 71 | 生成音频model 72 | 73 | @param audioPath 音频路径 74 | */ 75 | + (instancetype)createWithAudioPath:(NSString *)audioPath duration:(NSNumber *)duration; 76 | @property (nonatomic, copy) NSString *audioPath; 77 | @property (nonatomic, copy) NSString *voiceDuration; 78 | 79 | @end 80 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ServiceSDK/Manager/ChatList/Dao/WBChatListDao.h: -------------------------------------------------------------------------------- 1 | // 2 | // WBChatListDao.h 3 | // WBChat 4 | // 5 | // Created by RedRain on 2018/1/17. 6 | // Copyright © 2018年 RedRain. All rights reserved. 7 | // 8 | 9 | 10 | #import 11 | #import "WBCoreConfiguration.h" 12 | #import "WBChatListModel.h" 13 | 14 | NS_ASSUME_NONNULL_BEGIN 15 | 16 | // 此张表记录的数据, 均是AVOS提供的数据, 17 | // 客户端产生的行为数据如: 草稿,置顶等信息存放在 WBChatInfoDao 中 18 | @interface WBChatListDao : NSObject 19 | WB_SYNTHESIZE_SINGLETON_FOR_CLASS_HEADER(WBChatListDao) 20 | 21 | - (BOOL)createDBTable; 22 | 23 | /** 24 | 插入会话信息 25 | */ 26 | - (void)insertChatListModel:(WBChatListModel *)chatListModel; 27 | 28 | /** 29 | 插入会话信息 30 | */ 31 | - (void)insertChatListModelArray:(NSArray * )chatListModelArray; 32 | 33 | /** 34 | 加载本地会话列表 35 | */ 36 | - (void)loadChatListWithClient:(AVIMClient *)client result:(void (^)(NSArray *modelArray))resultBlock; 37 | 38 | /** 39 | 查询一个本地是否有某个会话 40 | */ 41 | - (BOOL)isExistWithConversationId:(NSString *)conversationId; 42 | 43 | /** 44 | 根据conversationId,删除一个本地的会话 45 | */ 46 | - (BOOL)deleteConversation:(NSString *)conversationId; 47 | #pragma mark - 获取到一个AVIMConversation 48 | 49 | /** 50 | 单独获取某个WBChatListModel对象 51 | */ 52 | - (WBChatListModel *)chatListModelWithConversationId:(NSString *)conversationId client:(AVIMClient *)client; 53 | 54 | @end 55 | NS_ASSUME_NONNULL_END 56 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ServiceSDK/Manager/ChatList/Model/WBChatListModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // WBChatListModel.h 3 | // WBChat 4 | // 5 | // Created by RedRain on 2018/1/17. 6 | // Copyright © 2018年 RedRain. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "WBIMDefine.h" 11 | @class AVIMConversation; 12 | @class AVIMMessage; 13 | 14 | @interface WBChatListModel : NSObject 15 | 16 | @property (nonatomic, copy) NSString *conversationID; ///< 会话ID 17 | @property (nonatomic, strong) AVIMConversation *conversation;///< 扩展使用 18 | @property (nonatomic, assign) NSInteger unreadCount;///< 会话消息未读数 19 | @property (nonatomic, assign) NSTimeInterval lastMessageAt; // 最后一条消息的时间 20 | @property (nonatomic, assign) BOOL mentioned;///< 是否有人@当前用户 21 | @property (nonatomic, copy) NSString *draft;///< 会话 草稿 22 | @property (nonatomic, assign) BOOL isTop;///< 会话是否置顶 23 | @property (nonatomic, assign) NSTimeInterval topTime;///< 置顶的时间 24 | @property (nonatomic, copy) NSString *extend;///< 扩展使用 25 | 26 | 27 | 28 | /** 29 | 快速通过 IM 对象的到 list对象 30 | */ 31 | + (instancetype)createWithConversation:(AVIMConversation *)conversation; 32 | 33 | @end 34 | 35 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ServiceSDK/Manager/ChatList/Model/WBChatListModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // WBChatListModel.m 3 | // WBChat 4 | // 5 | // Created by RedRain on 2018/1/17. 6 | // Copyright © 2018年 RedRain. All rights reserved. 7 | // 8 | 9 | #import "WBChatListModel.h" 10 | #import "NSDate+WBExt.h" 11 | 12 | @implementation WBChatListModel 13 | 14 | + (instancetype)createWithConversation:(AVIMConversation *)conversation{ 15 | WBChatListModel *list = [WBChatListModel new]; 16 | list.conversationID = conversation.conversationId; 17 | list.conversation = conversation; 18 | list.unreadCount = conversation.unreadMessagesCount; 19 | list.lastMessageAt = conversation.lastMessageAt.wb_currentTimeStamp.integerValue; 20 | list.mentioned = conversation.lastMessage.mentioned; 21 | return list; 22 | } 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ServiceSDK/Manager/ChatList/WBChatListManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // WBChatListManager.h 3 | // WBChat 4 | // 5 | // Created by RedRain on 2018/1/16. 6 | // Copyright © 2018年 RedRain. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "WBServiceSDKHeaders.h" 11 | 12 | #define WBChatListUpdateNotification @"WBChatListUpdateNotification" 13 | 14 | NS_ASSUME_NONNULL_BEGIN 15 | @interface WBChatListManager : NSObject 16 | 17 | WB_SYNTHESIZE_SINGLETON_FOR_CLASS_HEADER(WBChatListManager) 18 | 19 | #pragma mark - 拉取服务器端的所有对话 20 | /** 21 | 拉取服务器端的所有对话 22 | */ 23 | - (void)fetchAllConversationsFromServer:(void(^_Nullable)(NSArray * _Nullable conversations, 24 | NSError * _Nullable error))block; 25 | #pragma mark - 拉取本地的所有对话 26 | 27 | /** 28 | 拉取服务器端的所有对话 29 | */ 30 | - (void)fetchAllConversationsFromLocal:(void(^_Nullable)(NSArray * _Nullable conversations, 31 | NSError * _Nullable error))block; 32 | #pragma mark - 根据 conversationId 获取对话 33 | /** 34 | * 根据 conversationId 获取对话 35 | * @param conversationId 对话的 id 36 | */ 37 | - (void)fetchConversationWithConversationId:(NSString *)conversationId 38 | callback:(void (^_Nullable)(AVIMConversation * _Nullable conversation, 39 | NSError * _Nullable error))callback; 40 | #pragma mark - 根据 conversationId集合 获取对话 41 | /** 42 | * 根据 conversationId数组 获取多个指定的会话信息 43 | */ 44 | - (void)fetchConversationsWithConversationIds:(NSSet *)conversationIds 45 | callback:(void (^_Nullable)(NSArray * _Nullable conversations, 46 | NSError * _Nullable error))callback; 47 | 48 | 49 | #pragma mark - 更新最近一条消息记录到List 50 | /** 51 | 更新最近一条消息记录到List 52 | 53 | @param conversation 最近的会话信息 54 | */ 55 | - (void)insertConversationToList:(AVIMConversation *)conversation; 56 | 57 | 58 | /** 59 | 根据conversationId, 判断本地有没有对应的会话信息 60 | 61 | @param conversationId conversationId 62 | @return 是否已经存在 63 | */ 64 | - (BOOL)isExistWithConversationId:(NSString *)conversationId; 65 | 66 | #pragma mark - 删除一个会话 67 | /** 68 | 删除一个会话 69 | 70 | @param conversationId 会话id 71 | */ 72 | - (void)deleteConversation:(NSString *)conversationId; 73 | 74 | #pragma mark - 改变某个会话的会话状态 75 | /** 76 | 阅读了某个会话 77 | 78 | @param conversation 被阅读的会话 79 | */ 80 | - (void)readConversation:(AVIMConversation *)conversation; 81 | 82 | 83 | @end 84 | NS_ASSUME_NONNULL_END 85 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ServiceSDK/Manager/File/WBFileManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // WBFileManager.h 3 | // WBChat 4 | // 5 | // Created by RedRain on 2018/2/2. 6 | // Copyright © 2018年 RedRain. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "WBCoreConfiguration.h" 11 | 12 | @interface WBFileManager : NSObject 13 | 14 | + (BOOL)saveImageData:(NSData *)data toImagePath:(NSString *)imagePath; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ServiceSDK/Manager/File/WBFileManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // WBFileManager.m 3 | // WBChat 4 | // 5 | // Created by RedRain on 2018/2/2. 6 | // Copyright © 2018年 RedRain. All rights reserved. 7 | // 8 | 9 | #import "WBFileManager.h" 10 | 11 | @implementation WBFileManager 12 | 13 | + (BOOL)saveImageData:(NSData *)data toImagePath:(NSString *)imagePath{ 14 | BOOL ret = YES; 15 | ret = [self createFileWithPath:imagePath]; 16 | if (ret) { 17 | ret = [data writeToFile:imagePath atomically:YES]; 18 | } 19 | return ret; 20 | } 21 | 22 | 23 | + (BOOL)createFileWithPath:(NSString*)filePath{ 24 | 25 | // 1. 先判断文件路径文件是否存在 26 | if([[NSFileManager defaultManager] fileExistsAtPath:filePath]){ 27 | return YES; 28 | } 29 | 30 | 31 | // 2.先创建对应目录 32 | BOOL result = YES; 33 | NSString *finalPath = [filePath stringByDeletingLastPathComponent]; 34 | result = [[NSFileManager defaultManager] createDirectoryAtPath:finalPath withIntermediateDirectories:YES attributes:nil error:nil]; 35 | if(!result){ 36 | return result; 37 | } 38 | 39 | // 3.创建对应的文件对象 40 | result = [[NSFileManager defaultManager] createFileAtPath:filePath contents:nil attributes:nil]; 41 | return result; 42 | } 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ServiceSDK/Manager/File/WBNamedTool.h: -------------------------------------------------------------------------------- 1 | // 2 | // WBNamedTool.h 3 | // WBChat 4 | // 5 | // Created by RedRain on 2018/2/2. 6 | // Copyright © 2018年 RedRain. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | typedef NS_ENUM(NSUInteger, WBResNamedType) { 12 | WBResNamedTypeImage, 13 | WBResNamedTypeImageThumb, 14 | WBResNamedTypeImageOrigin, 15 | WBResNamedTypeSound, 16 | WBResNamedTypeVideo, 17 | WBResNamedTypeVideoThumb, 18 | WBResNamedTypeLocation, 19 | WBResNamedTypeLocationThumb, 20 | WBResNamedTypeFile 21 | }; 22 | 23 | @interface WBNamedTool : NSObject 24 | 25 | + (NSString *)namedWithType:(WBResNamedType)type; 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ServiceSDK/Manager/File/WBNamedTool.m: -------------------------------------------------------------------------------- 1 | // 2 | // WBNamedTool.m 3 | // WBChat 4 | // 5 | // Created by RedRain on 2018/2/2. 6 | // Copyright © 2018年 RedRain. All rights reserved. 7 | // 8 | 9 | #import "WBNamedTool.h" 10 | 11 | @implementation WBNamedTool 12 | 13 | + (NSString *)namedWithType:(WBResNamedType)type{ 14 | NSString *leadingString = [self UUID]; 15 | switch (type) { 16 | case WBResNamedTypeImage:{ 17 | return [leadingString stringByAppendingString:@"_Image.jpg"]; 18 | } 19 | break; 20 | case WBResNamedTypeImageThumb:{ 21 | return [leadingString stringByAppendingString:@"_ImageThumb.jpg"]; 22 | } 23 | break; 24 | case WBResNamedTypeImageOrigin:{ 25 | return [leadingString stringByAppendingString:@"_ImageOrigin.jpg"]; 26 | } 27 | 28 | default: 29 | return leadingString; 30 | break; 31 | } 32 | } 33 | + (NSString *)UUID{ 34 | return [[NSUUID UUID] UUIDString]; 35 | } 36 | @end 37 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ServiceSDK/Manager/File/WBPathManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // WBPathManager.h 3 | // WBChat 4 | // 5 | // Created by RedRain on 2018/2/2. 6 | // Copyright © 2018年 RedRain. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "WBCoreConfiguration.h" 11 | 12 | @interface WBPathManager : NSObject 13 | 14 | + (NSString *)imagePath; 15 | 16 | + (NSString *)voicePath; 17 | 18 | + (NSString *)videoPath; 19 | 20 | + (NSString *)filePath; 21 | 22 | + (NSString *)userResourcePath; 23 | 24 | + (NSString *)userPath; 25 | 26 | + (NSString *)libraryPath; 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ServiceSDK/Manager/File/WBPathManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // WBPathManager.m 3 | // WBChat 4 | // 5 | // Created by RedRain on 2018/2/2. 6 | // Copyright © 2018年 RedRain. All rights reserved. 7 | // 8 | 9 | #import "WBPathManager.h" 10 | #import "WBUserManager.h" 11 | 12 | #define kWBResourcePathName @"resource" 13 | #define kWBImagePathName @"images" 14 | #define kWBVoicePathName @"voices" 15 | #define kWBVideoPathName @"videos" 16 | #define kWBFilePathName @"files" 17 | 18 | @implementation WBPathManager 19 | 20 | + (NSString *)imagePath{ 21 | return [[self userResourcePath] stringByAppendingPathComponent:kWBImagePathName]; 22 | } 23 | 24 | + (NSString *)voicePath{ 25 | return [[self userResourcePath] stringByAppendingPathComponent:kWBVoicePathName]; 26 | } 27 | 28 | + (NSString *)videoPath{ 29 | return [[self userResourcePath] stringByAppendingPathComponent:kWBVideoPathName]; 30 | } 31 | 32 | + (NSString *)filePath{ 33 | return [[self userResourcePath] stringByAppendingPathComponent:kWBFilePathName]; 34 | } 35 | 36 | + (NSString *)userResourcePath{ 37 | return [[self userPath] stringByAppendingPathComponent:kWBResourcePathName]; 38 | } 39 | 40 | + (NSString *)userPath{ 41 | return [[self appFinderPath] stringByAppendingPathComponent:[WBUserManager sharedInstance].clientId]; 42 | } 43 | 44 | + (NSString *)appFinderPath{ 45 | return [[self libraryPath] stringByAppendingPathComponent:@"WBChatKit"]; 46 | } 47 | 48 | + (NSString *)libraryPath{ 49 | return NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES).firstObject; 50 | } 51 | 52 | @end 53 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ServiceSDK/Manager/Message/WBMessageManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // WBMessageManager.h 3 | // WBChat 4 | // 5 | // Created by RedRain on 2018/1/27. 6 | // Copyright © 2018年 RedRain. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "WBCoreConfiguration.h" 11 | #import 12 | #import 13 | 14 | #define WBMessageConversationKey @"conversation" 15 | #define WBMessageMessageKey @"message" 16 | 17 | 18 | #define WBMessageNewReceiveNotification @"WBMessageNewReceiveNotification" 19 | 20 | 21 | NS_ASSUME_NONNULL_BEGIN 22 | 23 | @interface WBMessageManager : NSObject 24 | WB_SYNTHESIZE_SINGLETON_FOR_CLASS_HEADER(WBMessageManager) 25 | 26 | 27 | /** 28 | 收到新的消息 29 | */ 30 | - (void)conversation:(AVIMConversation *)conversation didReceiveTypedMessage:(AVIMTypedMessage *)message; 31 | 32 | @end 33 | NS_ASSUME_NONNULL_END 34 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ServiceSDK/Manager/Message/WBMessageManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // WBMessageManager.m 3 | // WBChat 4 | // 5 | // Created by RedRain on 2018/1/27. 6 | // Copyright © 2018年 RedRain. All rights reserved. 7 | // 8 | 9 | #import "WBMessageManager.h" 10 | #import "WBManagerHeaders.h" 11 | 12 | @implementation WBMessageManager 13 | WB_SYNTHESIZE_SINGLETON_FOR_CLASS(WBMessageManager) 14 | 15 | - (void)conversation:(AVIMConversation *)conversation didReceiveTypedMessage:(AVIMTypedMessage *)message{ 16 | if (conversation == nil || 17 | message == nil) { 18 | return; 19 | } 20 | 21 | 22 | // 如果本地没有信息 23 | if (!conversation.createAt && 24 | ![[WBChatListManager sharedInstance] 25 | isExistWithConversationId:conversation.conversationId]) { 26 | 27 | // 拉取服务器最新数据。 28 | [conversation fetchWithCallback:^(BOOL succeeded, NSError *error) { 29 | if (succeeded) { 30 | 31 | [self receiveMessage:message conversation:conversation]; 32 | 33 | return; 34 | } 35 | 36 | }]; 37 | } 38 | 39 | // 本地有该会话的信息 40 | else{ 41 | [self receiveMessage:message conversation:conversation]; 42 | } 43 | } 44 | 45 | #pragma mark - Private 46 | - (void)receiveMessage:(AVIMTypedMessage *)message 47 | conversation:(AVIMConversation *)conversation { 48 | 49 | NSMutableDictionary *mDic = [NSMutableDictionary new]; 50 | if (conversation) { 51 | mDic[WBMessageConversationKey] = conversation; 52 | } 53 | if (message) { 54 | mDic[WBMessageMessageKey] = message; 55 | } 56 | 57 | [[NSNotificationCenter defaultCenter] 58 | postNotificationName:WBMessageNewReceiveNotification object:nil 59 | userInfo:mDic]; 60 | } 61 | 62 | @end 63 | 64 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ServiceSDK/MessageSubclass/WBGroupNotificationMessage.h: -------------------------------------------------------------------------------- 1 | // 2 | // WBGroupNotificationMessage.h 3 | // AVOSCloud 4 | // 5 | // Created by RedRain on 2018/3/14. 6 | // 7 | 8 | #import 9 | 10 | @interface WBGroupNotificationMessage : AVIMTypedMessage 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ServiceSDK/MessageSubclass/WBGroupNotificationMessage.m: -------------------------------------------------------------------------------- 1 | // 2 | // WBGroupNotificationMessage.m 3 | // AVOSCloud 4 | // 5 | // Created by RedRain on 2018/3/14. 6 | // 7 | 8 | #import "WBGroupNotificationMessage.h" 9 | #import "WBMessageModel.h" 10 | 11 | 12 | @implementation WBGroupNotificationMessage 13 | + (void)load{ 14 | [self registerSubclass]; 15 | } 16 | 17 | #pragma mark - AVIMTypedMessageSubclassing 18 | + (AVIMMessageMediaType)classMediaType{ 19 | return (int8_t)(WBChatMessageTypeNotification); 20 | } 21 | @end 22 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ServiceSDK/WBChatKitProtocol.h: -------------------------------------------------------------------------------- 1 | // 2 | // WBChatKitProtocol.h 3 | // Pods 4 | // 5 | // Created by RedRain on 2018/3/14. 6 | // 7 | 8 | #ifndef WBChatKitProtocol_h 9 | #define WBChatKitProtocol_h 10 | 11 | #import 12 | 13 | @protocol WBChatKitProtocol 14 | 15 | - (NSString *)memberNameWithClientID:(NSString *)clientId; 16 | 17 | 18 | /** 19 | 根据ClientId设置头像 20 | 21 | @param imageView 需要设置头像的View 22 | @param clientId 区分id 23 | @param placeholdImage 占位图片 24 | */ 25 | - (void)imageView:(UIImageView *)imageView 26 | clientID:(NSString *)clientId 27 | placeholdImage:(UIImage *)placeholdImage; 28 | 29 | 30 | /** 31 | 根据会话id设置列表头像 32 | 33 | @param imageView 需要设置头像的View 34 | @param conversationId 会话的id 35 | @param placeholdImage 占位图片 36 | */ 37 | - (void)imageView:(UIImageView *)imageView 38 | conversationId:(NSString *)conversationId 39 | placeholdImage:(UIImage *)placeholdImage; 40 | 41 | @end 42 | 43 | #endif /* WBChatKitProtocol_h */ 44 | 45 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ServiceSDK/WBDefine/WBIMDefine.h: -------------------------------------------------------------------------------- 1 | // 2 | // WBDefine.h 3 | // WBChat 4 | // 5 | // Created by RedRain on 2018/1/15. 6 | // Copyright © 2018年 RedRain. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #ifndef WBIMDefine 12 | #define WBIMDefine 13 | 14 | 15 | #import 16 | #import 17 | 18 | 19 | #define WBIMConversationFindErrorDomain @"WBIMConversationFindErrorDomain" ///< 查询会话信息 20 | 21 | 22 | #define WBIM_CONVERSATION_TYPE @"type" 23 | #define WBIMCustomMessageDegradeKey @"degrade" 24 | #define WBIMCustomMessageIsCustomKey @"isCustom" 25 | 26 | 27 | typedef NS_ENUM(NSUInteger, WBChatListCellType) { 28 | // 防止未明确赋值 29 | WBChatListCellTypeNone = 0, 30 | // 默认样式 31 | WBChatListCellTypeNormal = 1 32 | }; 33 | 34 | typedef NS_ENUM(NSUInteger, WBConversationType) { 35 | // 防止未明确赋值 36 | WBConversationTypeNone = 0, 37 | // 单聊 38 | WBConversationTypeSingle = 1, 39 | // 讨论组 40 | WBConversationTypeDiscussion = 2, 41 | // 群组 42 | WBConversationTypeGroup = 3, 43 | // 聊天室 44 | WBConversationTypeChatRoom = 4 45 | }; 46 | 47 | typedef NS_ENUM(NSUInteger, WBReceivedStatus) { 48 | // 防止未明确赋值 49 | WBReceivedStatusNone = 0, 50 | // 未读 51 | WBReceivedStatusUnread = 1, 52 | // 已读 53 | WBReceivedStatusRead = 2, 54 | // 语音已读 55 | WBReceivedStatusListened = 3 56 | }; 57 | 58 | typedef NS_ENUM(NSUInteger, WBSentStatus) { 59 | // 防止未明确赋值 60 | WBSentStatusNone = 0, 61 | // 发送中 62 | WBSentStatusSending = 1, 63 | // 发送失败 64 | WBSentStatusFailed = 2, 65 | // 发送成功 66 | WBSentStatusSended = 3 67 | }; 68 | 69 | typedef NS_ENUM(NSUInteger, WBMessageDirection) { 70 | // 防止未明确赋值 71 | WBMessageDirectionNone = 0, 72 | // 发送 73 | WBMessageDirectionSent = 1, 74 | // 接收 75 | WBMessageDirectionReceived = 2 76 | }; 77 | 78 | 79 | 80 | /** 81 | 用户使用国际化文件,展示UI界面 82 | 83 | @param key 统一key值 84 | @return 根据环境返回的字符串 85 | */ 86 | #ifndef WBIMLocalizedStrings 87 | #define WBIMLocalizedStrings(key) \ 88 | NSLocalizedStringFromTableInBundle(key, @"LCChatKitString", [NSBundle lcck_bundleForName:@"Other" class:[self class]], nil) 89 | #endif 90 | 91 | 92 | #ifdef DEBUG 93 | #define WBIMLog(fmt, ...) NSLog((@"\n%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ## __VA_ARGS__); 94 | #else 95 | #define WBIMLog(...) 96 | #endif 97 | 98 | 99 | 100 | #endif /* WBConfig_pch */ 101 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ServiceSDK/WBIMClientDelegateImp.h: -------------------------------------------------------------------------------- 1 | // 2 | // WBIMClientDelegateImp.h 3 | // WBChat 4 | // 5 | // Created by RedRain on 2018/1/15. 6 | // Copyright © 2018年 RedRain. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | #define kIMClientClosedInError @"kIMClientClosedInError" 13 | 14 | @interface WBIMClientDelegateImp : NSObject 15 | 16 | @property (nonatomic, copy, readonly) NSString *clientId; 17 | 18 | /*! 19 | * AVIMClient 实例 20 | */ 21 | @property (nonatomic, strong, readonly) AVIMClient *client; 22 | 23 | /** 24 | * 是否和聊天服务器连通 25 | */ 26 | @property (nonatomic, assign, readonly) BOOL connect; 27 | 28 | 29 | 30 | /** 31 | 使用ClientId连接服务器 32 | 33 | @param clientId 用户IM身份的标识 34 | */ 35 | - (void)openWithClientId:(NSString *)clientId 36 | success:(void (^)(NSString *clientId))successBlock 37 | error:(void (^)(NSError *error))errorBlock; 38 | 39 | 40 | /** 41 | 使用ClientId连接服务器 42 | 43 | @param clientId 用户IM身份的标识 44 | @param force Just for Single Sign On 45 | */ 46 | - (void)openWithClientId:(NSString *)clientId 47 | force:(BOOL)force 48 | success:(void (^)(NSString *clientId))successBlock 49 | error:(void (^)(NSError *error))errorBlock; 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/ServiceSDK/WBServiceSDKHeaders.h: -------------------------------------------------------------------------------- 1 | // 2 | // WBServiceSDKHeaders.h 3 | 4 | 5 | #ifndef WBServiceSDKHeaders_h 6 | #define WBServiceSDKHeaders_h 7 | 8 | #import "UIImage+WBScaleExtension.h" 9 | #import "AVIMConversation+WBExtension.h" 10 | 11 | 12 | #import "WBIMDefine.h" 13 | 14 | #import "WBManagerHeaders.h" 15 | 16 | #import "WBChatKit.h" 17 | 18 | 19 | #endif /* WBServiceSDKHeaders_h */ 20 | -------------------------------------------------------------------------------- /WBChatIMKit/Classes/VoiceLib/lame.framework/lame: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxdxxxx/WBChatIMKit/33a02d0c958b7df73f7602ec07d7cd3440f849c4/WBChatIMKit/Classes/VoiceLib/lame.framework/lame -------------------------------------------------------------------------------- /WBChatIMKit/Classes/WBChatIMKit.h: -------------------------------------------------------------------------------- 1 | // 2 | // WBChatIMKit.h 3 | // Pods 4 | // 5 | // Created by RedRain on 2018/3/13. 6 | // 7 | 8 | #ifndef WBChatIMKit_h 9 | #define WBChatIMKit_h 10 | 11 | 12 | #import "WBChatMessageBaseCell.h" 13 | #import "WBChatMessageHintCell.h" 14 | #import "WBChatMessageImageCell.h" 15 | #import "WBChatMessageTextCell.h" 16 | #import "WBChatMessageTimeCell.h" 17 | #import "WBChatMessageVoiceCell.h" 18 | #import "WBChatMessageBaseCellModel.h" 19 | #import "WBChatMessageImageCellModel.h" 20 | #import "WBChatMessageRecallCellModel.h" 21 | #import "WBChatMessageTextCellModel.h" 22 | #import "WBChatMessageTimeCellModel.h" 23 | #import "WBChatMessageVoiceCellModel.h" 24 | #import "UITableView+WBScrollToIndexPath.h" 25 | #import "WBChatCellConfig.h" 26 | #import "WBShowBigImageTool.h" 27 | #import "WBVoicePlayer.h" 28 | #import "WBImageBrowserCell.h" 29 | #import "WBImageBrowserView.h" 30 | #import "WBChatViewController+Extension.h" 31 | #import "WBChatViewController.h" 32 | #import "WBChatListCell.h" 33 | #import "WBChatListCellModel.h" 34 | #import "WBBadgeButton.h" 35 | #import "WBChatListController.h" 36 | #import "WBBaseController.h" 37 | #import "NSDate+Extension.h" 38 | #import "NSString+OPSize.h" 39 | #import "UIImage+WBImage.h" 40 | #import "UIView+Frame.h" 41 | #import "UIView+NextResponder.h" 42 | #import "WBConfig.h" 43 | #import "WBConst.h" 44 | #import "UIView+WBToast.h" 45 | #import "WBHUD.h" 46 | #import "WBEmojiKeyBoardCell.h" 47 | #import "WBEmojiGroupCell.h" 48 | #import "WBEmojiGroupControl.h" 49 | #import "WBEmotionPageModel.h" 50 | #import "WBEmotionDisplayBoard.h" 51 | #import "WBTLAudioPlayer.h" 52 | #import "WBTLAudioRecorder.h" 53 | #import "WBPlusBoardCell.h" 54 | #import "WBPlusDisplayBoard.h" 55 | #import "WBTLTalkButton.h" 56 | #import "WBTLRecorderIndicatorView.h" 57 | #import "WBChatBarConst.h" 58 | #import "WBChatBarView.h" 59 | #import "WBKeyBoardTextView.h" 60 | #import "UIScrollView+WBRefresh.h" 61 | #import "WBRefreshHeaderView.h" 62 | #import "WBImageLoad.h" 63 | #import "WBSelectPhotoTool.h" 64 | #import "WBTools.h" 65 | #import "WBDBCreater.h" 66 | #import "WBTerminateHandler.h" 67 | #import "WBCoreRegister.h" 68 | #import "WBDBClient.h" 69 | #import "WBUserManager.h" 70 | #import "AVIMConversation+WBExtension.h" 71 | #import "AVIMMessage+WBExtension.h" 72 | #import "AVIMTypedMessage+WBExtension.h" 73 | #import "FMDatabase+WBAutoSql.h" 74 | #import "NSBundle+LCCKExtension.h" 75 | #import "NSDate+WBExt.h" 76 | #import "NSError+WBError.h" 77 | #import "NSObject+WBExtension.h" 78 | #import "UIImage+WBScaleExtension.h" 79 | #import "WBCoreConfiguration.h" 80 | #import "WBManagerHeaders.h" 81 | #import "WBSynthesizeSingleton.h" 82 | #import "WBUserDefaults.h" 83 | #import "WBBackgroundManager.h" 84 | #import "WBChatInfoDao.h" 85 | #import "WBChatManager.h" 86 | #import "WBChatInfoModel.h" 87 | #import "WBMessageModel.h" 88 | #import "WBChatListDao.h" 89 | #import "WBChatListModel.h" 90 | #import "WBChatListManager.h" 91 | #import "WBFileManager.h" 92 | #import "WBNamedTool.h" 93 | #import "WBPathManager.h" 94 | #import "WBMessageManager.h" 95 | #import "WBGroupNotificationMessage.h" 96 | #import "WBChatKit.h" 97 | #import "WBChatKitProtocol.h" 98 | #import "WBIMDefine.h" 99 | #import "WBIMClientDelegateImp.h" 100 | #import "WBServiceSDKHeaders.h" 101 | #import "WBChatIMKit.h" 102 | 103 | #endif /* WBChatIMKit_h */ 104 | -------------------------------------------------------------------------------- /_Pods.xcodeproj: -------------------------------------------------------------------------------- 1 | Example/Pods/Pods.xcodeproj --------------------------------------------------------------------------------