From a409ed34ce425ae102b231085d4b19eb1de16f28 Mon Sep 17 00:00:00 2001 From: nixzhu Date: Fri, 5 Jun 2015 17:20:01 +0800 Subject: [PATCH 1/7] split sendMessage... --- Yep/Services/YepService.swift | 263 ++++++++++++++++++---------------- 1 file changed, 136 insertions(+), 127 deletions(-) diff --git a/Yep/Services/YepService.swift b/Yep/Services/YepService.swift index 4d609903..b13ad555 100644 --- a/Yep/Services/YepService.swift +++ b/Yep/Services/YepService.swift @@ -1042,22 +1042,22 @@ func sendText(text: String, toRecipient recipientID: String, #recipientType: Str moreInfo["text_content"] = text return moreInfo } - sendMessageWithMediaType(.Text, inFilePath: nil, orFileData: nil, metaData: nil, fillMoreInfo: fillMoreInfo, toRecipient: recipientID, recipientType: recipientType, afterCreatedMessage: afterCreatedMessage, failureHandler: failureHandler, completion: completion) + createAndSendMessageWithMediaType(.Text, inFilePath: nil, orFileData: nil, metaData: nil, fillMoreInfo: fillMoreInfo, toRecipient: recipientID, recipientType: recipientType, afterCreatedMessage: afterCreatedMessage, failureHandler: failureHandler, completion: completion) } func sendImageInFilePath(filePath: String?, orFileData fileData: NSData?, #metaData: String?, toRecipient recipientID: String, #recipientType: String, #afterCreatedMessage: (Message) -> Void, #failureHandler: ((Reason, String?) -> Void)?, #completion: (success: Bool) -> Void) { - sendMessageWithMediaType(.Image, inFilePath: filePath, orFileData: fileData, metaData: metaData, fillMoreInfo: nil, toRecipient: recipientID, recipientType: recipientType, afterCreatedMessage: afterCreatedMessage, failureHandler: failureHandler, completion: completion) + createAndSendMessageWithMediaType(.Image, inFilePath: filePath, orFileData: fileData, metaData: metaData, fillMoreInfo: nil, toRecipient: recipientID, recipientType: recipientType, afterCreatedMessage: afterCreatedMessage, failureHandler: failureHandler, completion: completion) } func sendAudioInFilePath(filePath: String?, orFileData fileData: NSData?, #metaData: String?, toRecipient recipientID: String, #recipientType: String, #afterCreatedMessage: (Message) -> Void, #failureHandler: ((Reason, String?) -> Void)?, #completion: (success: Bool) -> Void) { - sendMessageWithMediaType(.Audio, inFilePath: filePath, orFileData: fileData, metaData: metaData, fillMoreInfo: nil, toRecipient: recipientID, recipientType: recipientType, afterCreatedMessage: afterCreatedMessage, failureHandler: failureHandler, completion: completion) + createAndSendMessageWithMediaType(.Audio, inFilePath: filePath, orFileData: fileData, metaData: metaData, fillMoreInfo: nil, toRecipient: recipientID, recipientType: recipientType, afterCreatedMessage: afterCreatedMessage, failureHandler: failureHandler, completion: completion) } func sendVideoInFilePath(filePath: String?, orFileData fileData: NSData?, #metaData: String?, toRecipient recipientID: String, #recipientType: String, #afterCreatedMessage: (Message) -> Void, #failureHandler: ((Reason, String?) -> Void)?, #completion: (success: Bool) -> Void) { - sendMessageWithMediaType(.Video, inFilePath: filePath, orFileData: fileData, metaData: metaData, fillMoreInfo: nil, toRecipient: recipientID, recipientType: recipientType, afterCreatedMessage: afterCreatedMessage, failureHandler: failureHandler, completion: completion) + createAndSendMessageWithMediaType(.Video, inFilePath: filePath, orFileData: fileData, metaData: metaData, fillMoreInfo: nil, toRecipient: recipientID, recipientType: recipientType, afterCreatedMessage: afterCreatedMessage, failureHandler: failureHandler, completion: completion) } func sendLocationWithCoordinate(coordinate: CLLocationCoordinate2D, toRecipient recipientID: String, #recipientType: String, #afterCreatedMessage: (Message) -> Void, #failureHandler: ((Reason, String?) -> Void)?, #completion: (success: Bool) -> Void) { @@ -1069,11 +1069,10 @@ func sendLocationWithCoordinate(coordinate: CLLocationCoordinate2D, toRecipient return moreInfo } - sendMessageWithMediaType(.Location, inFilePath: nil, orFileData: nil, metaData: nil, fillMoreInfo: fillMoreInfo, toRecipient: recipientID, recipientType: recipientType, afterCreatedMessage: afterCreatedMessage, failureHandler: failureHandler, completion: completion) + createAndSendMessageWithMediaType(.Location, inFilePath: nil, orFileData: nil, metaData: nil, fillMoreInfo: fillMoreInfo, toRecipient: recipientID, recipientType: recipientType, afterCreatedMessage: afterCreatedMessage, failureHandler: failureHandler, completion: completion) } - -func sendMessageWithMediaType(mediaType: MessageMediaType, inFilePath filePath: String?, orFileData fileData: NSData?, #metaData: String?, #fillMoreInfo: (JSONDictionary -> JSONDictionary)?, toRecipient recipientID: String, #recipientType: String, #afterCreatedMessage: (Message) -> Void, #failureHandler: ((Reason, String?) -> Void)?, #completion: (success: Bool) -> Void) { +func createAndSendMessageWithMediaType(mediaType: MessageMediaType, inFilePath filePath: String?, orFileData fileData: NSData?, #metaData: String?, #fillMoreInfo: (JSONDictionary -> JSONDictionary)?, toRecipient recipientID: String, #recipientType: String, #afterCreatedMessage: (Message) -> Void, #failureHandler: ((Reason, String?) -> Void)?, #completion: (success: Bool) -> Void) { // 因为 message_id 必须来自远端,线程无法切换,所以这里暂时没用 realmQueue // TOOD: 也许有办法 let realm = Realm() @@ -1148,12 +1147,6 @@ func sendMessageWithMediaType(mediaType: MessageMediaType, inFilePath filePath: realm.commitWrite() - // 发出之前就显示 Message - afterCreatedMessage(message) - - - // 下面开始真正的消息发送 - var messageInfo: JSONDictionary = [ "recipient_id": recipientID, "recipient_type": recipientType, @@ -1182,143 +1175,159 @@ func sendMessageWithMediaType(mediaType: MessageMediaType, inFilePath filePath: realm.commitWrite() - switch mediaType { - case .Text, .Location: - createMessageWithMessageInfo(messageInfo, failureHandler: { (reason, errorMessage) in - if let failureHandler = failureHandler { - failureHandler(reason, errorMessage) - } + // 发出之前就显示 Message + afterCreatedMessage(message) - dispatch_async(dispatch_get_main_queue()) { - - realm.beginWrite() - message.sendState = MessageSendState.Failed.rawValue - realm.commitWrite() - } + // 下面开始真正的消息发送 + sendMessage(message, inFilePath: filePath, orFileData: fileData, metaData: metaData, fillMoreInfo: fillMoreInfo, toRecipient: recipientID, recipientType: recipientType, failureHandler: failureHandler, completion: completion) +} - }, completion: { messageID in +func sendMessage(message: Message, inFilePath filePath: String?, orFileData fileData: NSData?, #metaData: String?, #fillMoreInfo: (JSONDictionary -> JSONDictionary)?, toRecipient recipientID: String, #recipientType: String, #failureHandler: ((Reason, String?) -> Void)?, #completion: (success: Bool) -> Void) { - - dispatch_async(dispatch_get_main_queue()) { - //Add to queue - -// var operation = MessageStateOperation(type: .Sent, messageID: messageID) -// -// ConversationOperationQueue.sharedManager.addNewQperationQueue(operation) - - realm.beginWrite() - message.messageID = messageID - message.sendState = MessageSendState.Successed.rawValue - realm.commitWrite() - - completion(success: true) + if let mediaType = MessageMediaType(rawValue: message.mediaType) { - NSNotificationCenter.defaultCenter().postNotificationName(MessageNotification.MessageStateChanged, object: nil) - } - }) + var messageInfo: JSONDictionary = [ + "recipient_id": recipientID, + "recipient_type": recipientType, + "media_type": mediaType.description, + ] - default: + if let fillMoreInfo = fillMoreInfo { + messageInfo = fillMoreInfo(messageInfo) + } - s3PrivateUploadParams(failureHandler: nil) { s3UploadParams in - uploadFileToS3(inFilePath: filePath, orFileData: fileData, mimeType: mediaType.mineType(), s3UploadParams: s3UploadParams) { (result, error) in + switch mediaType { - // TODO: attachments - switch mediaType { - case .Image: - if let metaData = metaData { - let attachments = ["image": [["file": s3UploadParams.key, "metadata": metaData]]] - messageInfo["attachments"] = attachments - - } else { - let attachments = ["image": [["file": s3UploadParams.key]]] - messageInfo["attachments"] = attachments - } - - case .Audio: - if let metaData = metaData { - let attachments = ["audio": [["file": s3UploadParams.key, "metadata": metaData]]] - messageInfo["attachments"] = attachments - - } else { - let attachments = ["audio": [["file": s3UploadParams.key]]] - messageInfo["attachments"] = attachments - } - - default: - break + case .Text, .Location: + createMessageWithMessageInfo(messageInfo, failureHandler: { (reason, errorMessage) in + if let failureHandler = failureHandler { + failureHandler(reason, errorMessage) } - let doCreateMessage = { - createMessageWithMessageInfo(messageInfo, failureHandler: { (reason, errorMessage) in - if let failureHandler = failureHandler { - failureHandler(reason, errorMessage) - } + dispatch_async(dispatch_get_main_queue()) { - dispatch_async(dispatch_get_main_queue()) { - realm.beginWrite() - message.sendState = MessageSendState.Failed.rawValue - realm.commitWrite() - } + let realm = message.realm - }, completion: { messageID in - dispatch_async(dispatch_get_main_queue()) { - realm.beginWrite() - message.messageID = messageID - message.sendState = MessageSendState.Successed.rawValue - realm.commitWrite() - -// var operation = MessageStateOperation(type: .Sent, messageID: messageID) -// -// ConversationOperationQueue.sharedManager.addNewQperationQueue(operation) - - completion(success: true) - - NSNotificationCenter.defaultCenter().postNotificationName(MessageNotification.MessageStateChanged, object: nil) - } - - }) + realm?.write { + message.sendState = MessageSendState.Failed.rawValue + } } - // 对于 Video 还要再传 thumbnail,…… - if mediaType == .Video { + }, completion: { messageID in - var thumbnailData: NSData? - - if - let filePath = filePath, - let image = thumbnailImageOfVideoInVideoURL(NSURL(fileURLWithPath: filePath)!) { - thumbnailData = UIImageJPEGRepresentation(image, YepConfig.messageImageCompressionQuality()) + dispatch_async(dispatch_get_main_queue()) { + let realm = message.realm + realm?.write { + message.messageID = messageID + message.sendState = MessageSendState.Successed.rawValue } - s3PrivateUploadParams(failureHandler: nil) { thumbnailS3UploadParams in - uploadFileToS3(inFilePath: nil, orFileData: thumbnailData, mimeType: MessageMediaType.Image.mineType(), s3UploadParams: thumbnailS3UploadParams) { (result, error) in + completion(success: true) - if let metaData = metaData { - let attachments = [ - "video": [ - ["file": s3UploadParams.key, "metadata": metaData] - ], - "thumbnail": [["file": thumbnailS3UploadParams.key]] - ] - messageInfo["attachments"] = attachments + NSNotificationCenter.defaultCenter().postNotificationName(MessageNotification.MessageStateChanged, object: nil) + } + }) - } else { - let attachments = [ - "video": [ - ["file": s3UploadParams.key] - ], - "thumbnail": [["file": thumbnailS3UploadParams.key]] - ] - messageInfo["attachments"] = attachments + default: + + s3PrivateUploadParams(failureHandler: nil) { s3UploadParams in + uploadFileToS3(inFilePath: filePath, orFileData: fileData, mimeType: mediaType.mineType(), s3UploadParams: s3UploadParams) { (result, error) in + + // TODO: attachments + switch mediaType { + case .Image: + if let metaData = metaData { + let attachments = ["image": [["file": s3UploadParams.key, "metadata": metaData]]] + messageInfo["attachments"] = attachments + + } else { + let attachments = ["image": [["file": s3UploadParams.key]]] + messageInfo["attachments"] = attachments + } + + case .Audio: + if let metaData = metaData { + let attachments = ["audio": [["file": s3UploadParams.key, "metadata": metaData]]] + messageInfo["attachments"] = attachments + + } else { + let attachments = ["audio": [["file": s3UploadParams.key]]] + messageInfo["attachments"] = attachments + } + + default: + break + } + + let doCreateMessage = { + createMessageWithMessageInfo(messageInfo, failureHandler: { (reason, errorMessage) in + if let failureHandler = failureHandler { + failureHandler(reason, errorMessage) } - doCreateMessage() - } + dispatch_async(dispatch_get_main_queue()) { + let realm = message.realm + realm?.write { + message.sendState = MessageSendState.Failed.rawValue + } + } + + }, completion: { messageID in + dispatch_async(dispatch_get_main_queue()) { + let realm = message.realm + realm?.write { + message.messageID = messageID + message.sendState = MessageSendState.Successed.rawValue + } + + completion(success: true) + + NSNotificationCenter.defaultCenter().postNotificationName(MessageNotification.MessageStateChanged, object: nil) + } + }) } - } else { - doCreateMessage() + // 对于 Video 还要再传 thumbnail,…… + if mediaType == .Video { + + var thumbnailData: NSData? + + if + let filePath = filePath, + let image = thumbnailImageOfVideoInVideoURL(NSURL(fileURLWithPath: filePath)!) { + thumbnailData = UIImageJPEGRepresentation(image, YepConfig.messageImageCompressionQuality()) + } + + s3PrivateUploadParams(failureHandler: nil) { thumbnailS3UploadParams in + uploadFileToS3(inFilePath: nil, orFileData: thumbnailData, mimeType: MessageMediaType.Image.mineType(), s3UploadParams: thumbnailS3UploadParams) { (result, error) in + + if let metaData = metaData { + let attachments = [ + "video": [ + ["file": s3UploadParams.key, "metadata": metaData] + ], + "thumbnail": [["file": thumbnailS3UploadParams.key]] + ] + messageInfo["attachments"] = attachments + + } else { + let attachments = [ + "video": [ + ["file": s3UploadParams.key] + ], + "thumbnail": [["file": thumbnailS3UploadParams.key]] + ] + messageInfo["attachments"] = attachments + } + + doCreateMessage() + } + } + + } else { + doCreateMessage() + } } } } From 40d43186c45a9ba7f1c8345d15767b2e846142fc Mon Sep 17 00:00:00 2001 From: nixzhu Date: Fri, 5 Jun 2015 17:42:47 +0800 Subject: [PATCH 2/7] resendMessage for text & image --- Yep/Realm/Models.swift | 9 ++++ Yep/Services/YepService.swift | 51 +++++++++++++++++++ .../ConversationViewController.swift | 13 ++++- 3 files changed, 72 insertions(+), 1 deletion(-) diff --git a/Yep/Realm/Models.swift b/Yep/Realm/Models.swift index f4037955..01974c07 100644 --- a/Yep/Realm/Models.swift +++ b/Yep/Realm/Models.swift @@ -238,6 +238,15 @@ class Draft: Object { enum ConversationType: Int { case OneToOne = 0 // 一对一对话 case Group = 1 // 群组对话 + + var nameForServer: String { + switch self { + case .OneToOne: + return "User" + case .Group: + return "Circle" + } + } } class Conversation: Object { diff --git a/Yep/Services/YepService.swift b/Yep/Services/YepService.swift index b13ad555..cf50ccb6 100644 --- a/Yep/Services/YepService.swift +++ b/Yep/Services/YepService.swift @@ -1334,6 +1334,57 @@ func sendMessage(message: Message, inFilePath filePath: String?, orFileData file } } +func resendMessage(message: Message, #failureHandler: ((Reason, String?) -> Void)?, #completion: (success: Bool) -> Void) { + + var recipientID: String? + var recipientType: String? + + if let conversation = message.conversation { + if conversation.type == ConversationType.OneToOne.rawValue { + recipientID = conversation.withFriend?.userID + recipientType = ConversationType.OneToOne.nameForServer + + } else if conversation.type == ConversationType.Group.rawValue { + recipientID = conversation.withGroup?.groupID + recipientType = ConversationType.Group.nameForServer + } + } + + if let + recipientID = recipientID, + recipientType = recipientType, + messageMediaType = MessageMediaType(rawValue: message.mediaType) { + + switch messageMediaType { + + case .Text: + + let fillMoreInfo: JSONDictionary -> JSONDictionary = { info in + var moreInfo = info + moreInfo["text_content"] = message.textContent + return moreInfo + } + + sendMessage(message, inFilePath: nil, orFileData: nil, metaData: nil, fillMoreInfo: fillMoreInfo, toRecipient: recipientID, recipientType: recipientType, failureHandler: failureHandler, completion: completion) + + case .Image: + let filePath = NSFileManager.yepMessageImageURLWithName(message.localAttachmentName)?.path + + sendMessage(message, inFilePath: filePath, orFileData: nil, metaData: message.metaData, fillMoreInfo: nil, toRecipient: recipientID, recipientType: recipientType, failureHandler: failureHandler, completion: completion) + + default: + break + // case Text = 0 + // case Image = 1 + // case Video = 2 + // case Audio = 3 + // case Sticker = 4 + // case Location = 5 + // case SectionDate = 6 + } + } +} + func markAsReadMessage(message: Message ,#failureHandler: ((Reason, String?) -> Void)?, #completion: (Bool) -> Void) { if message.readed || message.messageID.isEmpty { diff --git a/Yep/ViewControllers/Conversation/ConversationViewController.swift b/Yep/ViewControllers/Conversation/ConversationViewController.swift index 503585be..aa564aaf 100644 --- a/Yep/ViewControllers/Conversation/ConversationViewController.swift +++ b/Yep/ViewControllers/Conversation/ConversationViewController.swift @@ -1640,7 +1640,18 @@ extension ConversationViewController: UICollectionViewDataSource, UICollectionVi cell.configureWithMessage(message, messageImagePreferredWidth: messageImagePreferredWidth, messageImagePreferredHeight: messageImagePreferredHeight, messageImagePreferredAspectRatio: messageImagePreferredAspectRatio, mediaTapAction: { - self.performSegueWithIdentifier("showMessageMedia", sender: message) + if message.sendState == MessageSendState.Failed.rawValue { + resendMessage(message, failureHandler: { (reason, errorMessage) in + defaultFailureHandler(reason, errorMessage) + // TODO: resendText 错误提醒 + + }, completion: { success in + println("resendText: \(success)") + }) + + } else { + self.performSegueWithIdentifier("showMessageMedia", sender: message) + } }) return cell From 01246317d9ee16934ea645eefb8a20bb68f73b1d Mon Sep 17 00:00:00 2001 From: nixzhu Date: Fri, 5 Jun 2015 17:55:34 +0800 Subject: [PATCH 3/7] resendMessage for Text --- .../ConversationViewController.swift | 18 +++++++++++++++--- .../ChatRightText/ChatRightTextCell.swift | 18 ++++++++++++++++-- 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/Yep/ViewControllers/Conversation/ConversationViewController.swift b/Yep/ViewControllers/Conversation/ConversationViewController.swift index aa564aaf..b8cc57f3 100644 --- a/Yep/ViewControllers/Conversation/ConversationViewController.swift +++ b/Yep/ViewControllers/Conversation/ConversationViewController.swift @@ -1643,10 +1643,10 @@ extension ConversationViewController: UICollectionViewDataSource, UICollectionVi if message.sendState == MessageSendState.Failed.rawValue { resendMessage(message, failureHandler: { (reason, errorMessage) in defaultFailureHandler(reason, errorMessage) - // TODO: resendText 错误提醒 + // TODO: resendImage 错误提醒 }, completion: { success in - println("resendText: \(success)") + println("resendImage: \(success)") }) } else { @@ -1698,7 +1698,19 @@ extension ConversationViewController: UICollectionViewDataSource, UICollectionVi default: let cell = collectionView.dequeueReusableCellWithReuseIdentifier(chatRightTextCellIdentifier, forIndexPath: indexPath) as! ChatRightTextCell - cell.configureWithMessage(message, textContentLabelWidth: textContentLabelWidthOfMessage(message)) + cell.configureWithMessage(message, textContentLabelWidth: textContentLabelWidthOfMessage(message), mediaTapAction: { + + if message.sendState == MessageSendState.Failed.rawValue { + + resendMessage(message, failureHandler: { (reason, errorMessage) in + defaultFailureHandler(reason, errorMessage) + // TODO: resendText 错误提醒 + + }, completion: { success in + println("resendText: \(success)") + }) + } + }) return cell } diff --git a/Yep/Views/Cells/ChatRightText/ChatRightTextCell.swift b/Yep/Views/Cells/ChatRightText/ChatRightTextCell.swift index d1889398..3427b1a2 100644 --- a/Yep/Views/Cells/ChatRightText/ChatRightTextCell.swift +++ b/Yep/Views/Cells/ChatRightText/ChatRightTextCell.swift @@ -22,6 +22,9 @@ class ChatRightTextCell: ChatRightBaseCell { @IBOutlet weak var textContentLabelTrailingConstraint: NSLayoutConstraint! @IBOutlet weak var textContentLabelLeadingConstraint: NSLayoutConstraint! @IBOutlet weak var textContentLabelWidthConstraint: NSLayoutConstraint! + + typealias MediaTapAction = () -> Void + var mediaTapAction: MediaTapAction? override func awakeFromNib() { super.awakeFromNib() @@ -48,11 +51,22 @@ class ChatRightTextCell: ChatRightBaseCell { bubbleBodyImageView.tintColor = UIColor.rightBubbleTintColor() bubbleTailImageView.tintColor = UIColor.rightBubbleTintColor() + + bubbleBodyImageView.userInteractionEnabled = true + let tap = UITapGestureRecognizer(target: self, action: "tapMediaView") + bubbleBodyImageView.addGestureRecognizer(tap) + } + + func tapMediaView() { + mediaTapAction?() } - func configureWithMessage(message: Message, textContentLabelWidth: CGFloat) { + func configureWithMessage(message: Message, textContentLabelWidth: CGFloat, mediaTapAction: MediaTapAction?) { + self.message = message - + + self.mediaTapAction = mediaTapAction + textContentLabel.text = message.textContent textContentLabelWidthConstraint.constant = max(YepConfig.minMessageTextLabelWidth, textContentLabelWidth) From e0a6111e0133a8b3c1c2360084a70803e0211597 Mon Sep 17 00:00:00 2001 From: nixzhu Date: Fri, 5 Jun 2015 18:29:32 +0800 Subject: [PATCH 4/7] confirmOrCancel for resendMessage --- .../ConversationViewController.swift | 31 +++++++++++++------ 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/Yep/ViewControllers/Conversation/ConversationViewController.swift b/Yep/ViewControllers/Conversation/ConversationViewController.swift index b8cc57f3..dad5bf65 100644 --- a/Yep/ViewControllers/Conversation/ConversationViewController.swift +++ b/Yep/ViewControllers/Conversation/ConversationViewController.swift @@ -1641,12 +1641,18 @@ extension ConversationViewController: UICollectionViewDataSource, UICollectionVi cell.configureWithMessage(message, messageImagePreferredWidth: messageImagePreferredWidth, messageImagePreferredHeight: messageImagePreferredHeight, messageImagePreferredAspectRatio: messageImagePreferredAspectRatio, mediaTapAction: { if message.sendState == MessageSendState.Failed.rawValue { - resendMessage(message, failureHandler: { (reason, errorMessage) in - defaultFailureHandler(reason, errorMessage) - // TODO: resendImage 错误提醒 - }, completion: { success in - println("resendImage: \(success)") + YepAlert.confirmOrCancel(title: NSLocalizedString("Resend", comment: ""), message: NSLocalizedString("Resend text?", comment: ""), confirmTitle: NSLocalizedString("Resend", comment: ""), cancelTitle: NSLocalizedString("Cancel", comment: ""), inViewController: self, withConfirmAction: { + + resendMessage(message, failureHandler: { (reason, errorMessage) in + defaultFailureHandler(reason, errorMessage) + // TODO: resendImage 错误提醒 + + }, completion: { success in + println("resendImage: \(success)") + }) + + }, cancelAction: { }) } else { @@ -1702,12 +1708,17 @@ extension ConversationViewController: UICollectionViewDataSource, UICollectionVi if message.sendState == MessageSendState.Failed.rawValue { - resendMessage(message, failureHandler: { (reason, errorMessage) in - defaultFailureHandler(reason, errorMessage) - // TODO: resendText 错误提醒 + YepAlert.confirmOrCancel(title: NSLocalizedString("Resend", comment: ""), message: NSLocalizedString("Resend text?", comment: ""), confirmTitle: NSLocalizedString("Resend", comment: ""), cancelTitle: NSLocalizedString("Cancel", comment: ""), inViewController: self, withConfirmAction: { - }, completion: { success in - println("resendText: \(success)") + resendMessage(message, failureHandler: { (reason, errorMessage) in + defaultFailureHandler(reason, errorMessage) + // TODO: resendText 错误提醒 + + }, completion: { success in + println("resendText: \(success)") + }) + + }, cancelAction: { }) } }) From 047c7eba33a75c88772a32fce485d9b3f182891d Mon Sep 17 00:00:00 2001 From: nixzhu Date: Fri, 5 Jun 2015 18:51:13 +0800 Subject: [PATCH 5/7] more resendMessage type --- Yep/Services/YepService.swift | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/Yep/Services/YepService.swift b/Yep/Services/YepService.swift index cf50ccb6..ac825bc0 100644 --- a/Yep/Services/YepService.swift +++ b/Yep/Services/YepService.swift @@ -1368,19 +1368,34 @@ func resendMessage(message: Message, #failureHandler: ((Reason, String?) -> Void sendMessage(message, inFilePath: nil, orFileData: nil, metaData: nil, fillMoreInfo: fillMoreInfo, toRecipient: recipientID, recipientType: recipientType, failureHandler: failureHandler, completion: completion) case .Image: - let filePath = NSFileManager.yepMessageImageURLWithName(message.localAttachmentName)?.path + let filePath = NSFileManager.yepMessageImageURLWithName(message.localAttachmentName)?.path sendMessage(message, inFilePath: filePath, orFileData: nil, metaData: message.metaData, fillMoreInfo: nil, toRecipient: recipientID, recipientType: recipientType, failureHandler: failureHandler, completion: completion) + case .Video: + let filePath = NSFileManager.yepMessageVideoURLWithName(message.localAttachmentName)?.path + + sendMessage(message, inFilePath: filePath, orFileData: nil, metaData: message.metaData, fillMoreInfo: nil, toRecipient: recipientID, recipientType: recipientType, failureHandler: failureHandler, completion: completion) + + case .Audio: + let filePath = NSFileManager.yepMessageAudioURLWithName(message.localAttachmentName)?.path + + sendMessage(message, inFilePath: filePath, orFileData: nil, metaData: message.metaData, fillMoreInfo: nil, toRecipient: recipientID, recipientType: recipientType, failureHandler: failureHandler, completion: completion) + + case .Location: + if let coordinate = message.coordinate { + let fillMoreInfo: JSONDictionary -> JSONDictionary = { info in + var moreInfo = info + moreInfo["longitude"] = coordinate.longitude + moreInfo["latitude"] = coordinate.latitude + return moreInfo + } + + sendMessage(message, inFilePath: nil, orFileData: nil, metaData: nil, fillMoreInfo: fillMoreInfo, toRecipient: recipientID, recipientType: recipientType, failureHandler: failureHandler, completion: completion) + } + default: break - // case Text = 0 - // case Image = 1 - // case Video = 2 - // case Audio = 3 - // case Sticker = 4 - // case Location = 5 - // case SectionDate = 6 } } } From c907678120bcca42ef0c3cd63e65c3da46e00b9c Mon Sep 17 00:00:00 2001 From: nixzhu Date: Fri, 5 Jun 2015 18:52:00 +0800 Subject: [PATCH 6/7] resend Action for more Messages --- .../ConversationViewController.swift | 77 ++++++++++++++++--- 1 file changed, 66 insertions(+), 11 deletions(-) diff --git a/Yep/ViewControllers/Conversation/ConversationViewController.swift b/Yep/ViewControllers/Conversation/ConversationViewController.swift index dad5bf65..43e3bbb5 100644 --- a/Yep/ViewControllers/Conversation/ConversationViewController.swift +++ b/Yep/ViewControllers/Conversation/ConversationViewController.swift @@ -1642,7 +1642,7 @@ extension ConversationViewController: UICollectionViewDataSource, UICollectionVi if message.sendState == MessageSendState.Failed.rawValue { - YepAlert.confirmOrCancel(title: NSLocalizedString("Resend", comment: ""), message: NSLocalizedString("Resend text?", comment: ""), confirmTitle: NSLocalizedString("Resend", comment: ""), cancelTitle: NSLocalizedString("Cancel", comment: ""), inViewController: self, withConfirmAction: { + YepAlert.confirmOrCancel(title: NSLocalizedString("Action", comment: ""), message: NSLocalizedString("Resend image?", comment: ""), confirmTitle: NSLocalizedString("Resend", comment: ""), cancelTitle: NSLocalizedString("Cancel", comment: ""), inViewController: self, withConfirmAction: { resendMessage(message, failureHandler: { (reason, errorMessage) in defaultFailureHandler(reason, errorMessage) @@ -1669,6 +1669,26 @@ extension ConversationViewController: UICollectionViewDataSource, UICollectionVi cell.configureWithMessage(message, audioPlayedDuration: audioPlayedDuration, audioBubbleTapAction: { message in + if let message = message { + if message.sendState == MessageSendState.Failed.rawValue { + + YepAlert.confirmOrCancel(title: NSLocalizedString("Action", comment: ""), message: NSLocalizedString("Resend audio?", comment: ""), confirmTitle: NSLocalizedString("Resend", comment: ""), cancelTitle: NSLocalizedString("Cancel", comment: ""), inViewController: self, withConfirmAction: { + + resendMessage(message, failureHandler: { (reason, errorMessage) in + defaultFailureHandler(reason, errorMessage) + // TODO: resendAudio 错误提醒 + + }, completion: { success in + println("resendAudio: \(success)") + }) + + }, cancelAction: { + }) + + return + } + } + self.playMessageAudioWithMessage(message) }) @@ -1679,7 +1699,24 @@ extension ConversationViewController: UICollectionViewDataSource, UICollectionVi cell.configureWithMessage(message, messageImagePreferredWidth: messageImagePreferredWidth, messageImagePreferredHeight: messageImagePreferredHeight, messageImagePreferredAspectRatio: messageImagePreferredAspectRatio, mediaTapAction: { - self.performSegueWithIdentifier("showMessageMedia", sender: message) + if message.sendState == MessageSendState.Failed.rawValue { + + YepAlert.confirmOrCancel(title: NSLocalizedString("Action", comment: ""), message: NSLocalizedString("Resend video?", comment: ""), confirmTitle: NSLocalizedString("Resend", comment: ""), cancelTitle: NSLocalizedString("Cancel", comment: ""), inViewController: self, withConfirmAction: { + + resendMessage(message, failureHandler: { (reason, errorMessage) in + defaultFailureHandler(reason, errorMessage) + // TODO: resendVideo 错误提醒 + + }, completion: { success in + println("resendVideo: \(success)") + }) + + }, cancelAction: { + }) + + } else { + self.performSegueWithIdentifier("showMessageMedia", sender: message) + } }) return cell @@ -1688,14 +1725,32 @@ extension ConversationViewController: UICollectionViewDataSource, UICollectionVi let cell = collectionView.dequeueReusableCellWithReuseIdentifier(chatRightLocationCellIdentifier, forIndexPath: indexPath) as! ChatRightLocationCell cell.configureWithMessage(message, mediaTapAction: { - if let coordinate = message.coordinate { - let locationCoordinate = CLLocationCoordinate2D(latitude: coordinate.latitude, longitude: coordinate.longitude) - let mapItem = MKMapItem(placemark: MKPlacemark(coordinate: locationCoordinate, addressDictionary: nil)) - /* - let launchOptions = [MKLaunchOptionsDirectionsModeKey: MKLaunchOptionsDirectionsModeDriving] - mapItem.openInMapsWithLaunchOptions(launchOptions) - */ - mapItem.openInMapsWithLaunchOptions(nil) + + if message.sendState == MessageSendState.Failed.rawValue { + + YepAlert.confirmOrCancel(title: NSLocalizedString("Action", comment: ""), message: NSLocalizedString("Resend location?", comment: ""), confirmTitle: NSLocalizedString("Resend", comment: ""), cancelTitle: NSLocalizedString("Cancel", comment: ""), inViewController: self, withConfirmAction: { + + resendMessage(message, failureHandler: { (reason, errorMessage) in + defaultFailureHandler(reason, errorMessage) + // TODO: resendLocation 错误提醒 + + }, completion: { success in + println("resendLocation: \(success)") + }) + + }, cancelAction: { + }) + + } else { + if let coordinate = message.coordinate { + let locationCoordinate = CLLocationCoordinate2D(latitude: coordinate.latitude, longitude: coordinate.longitude) + let mapItem = MKMapItem(placemark: MKPlacemark(coordinate: locationCoordinate, addressDictionary: nil)) + /* + let launchOptions = [MKLaunchOptionsDirectionsModeKey: MKLaunchOptionsDirectionsModeDriving] + mapItem.openInMapsWithLaunchOptions(launchOptions) + */ + mapItem.openInMapsWithLaunchOptions(nil) + } } }) @@ -1708,7 +1763,7 @@ extension ConversationViewController: UICollectionViewDataSource, UICollectionVi if message.sendState == MessageSendState.Failed.rawValue { - YepAlert.confirmOrCancel(title: NSLocalizedString("Resend", comment: ""), message: NSLocalizedString("Resend text?", comment: ""), confirmTitle: NSLocalizedString("Resend", comment: ""), cancelTitle: NSLocalizedString("Cancel", comment: ""), inViewController: self, withConfirmAction: { + YepAlert.confirmOrCancel(title: NSLocalizedString("Action", comment: ""), message: NSLocalizedString("Resend text?", comment: ""), confirmTitle: NSLocalizedString("Resend", comment: ""), cancelTitle: NSLocalizedString("Cancel", comment: ""), inViewController: self, withConfirmAction: { resendMessage(message, failureHandler: { (reason, errorMessage) in defaultFailureHandler(reason, errorMessage) From ff4a23432bdce25f4d02292e92640d25bfde6d58 Mon Sep 17 00:00:00 2001 From: nixzhu Date: Fri, 5 Jun 2015 19:01:26 +0800 Subject: [PATCH 7/7] post MessageStateChanged when createMessageWithMessageInfo failed; show redDot on cell --- .../icon_dot_failed.imageset/Contents.json | 12 ++++++++++++ .../icon_dot_failed.imageset/icon_dot_failed.pdf | Bin 0 -> 3922 bytes Yep/Services/YepService.swift | 4 ++++ .../ConversationViewController.swift | 2 -- .../Cells/ChatRightBase/ChatRightBaseCell.swift | 3 ++- 5 files changed, 18 insertions(+), 3 deletions(-) create mode 100644 Yep/Images.xcassets/icon_dot_failed.imageset/Contents.json create mode 100644 Yep/Images.xcassets/icon_dot_failed.imageset/icon_dot_failed.pdf diff --git a/Yep/Images.xcassets/icon_dot_failed.imageset/Contents.json b/Yep/Images.xcassets/icon_dot_failed.imageset/Contents.json new file mode 100644 index 00000000..42ea4073 --- /dev/null +++ b/Yep/Images.xcassets/icon_dot_failed.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "icon_dot_failed.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Yep/Images.xcassets/icon_dot_failed.imageset/icon_dot_failed.pdf b/Yep/Images.xcassets/icon_dot_failed.imageset/icon_dot_failed.pdf new file mode 100644 index 0000000000000000000000000000000000000000..9058d72e3477a8c49a8cfad31b2b41f31d43d313 GIT binary patch literal 3922 zcmai%c|25Y8^39eybC&Q+gVW-Z-U}mGNj6sI)@;{ zG#)*(36yZMK@LTbx~gecIy07wI$}=YrND_yN`sxV}7#fVR1Y1^%+@!^@u!C|MR zfWc}e(=Q>Q29hOn5IoD0_rrX>&He)&P3tTNd6>B^nO{seI)acJdMtfk$m*%74^Fm} zuYHgY!qtq()|pCr59|cSiz(}h?`8t)_bZ*aCMiH=NwO$!7F65;yyn`+-VBbntMsi@B@_#twIg^4|>N%c9AJ9<;qIfKbB&uJ z_?pGGdYeD(+_K~XB||$V12yix@KAxw&$K3Pb>~odZSpy$3Xk1d)QN{CO90c#E~bjH zyPpn+yW1r+z2lPNj9yr9_h!y?lRx%enU)zscv%;&x}Mtcfp%UkPe3#H4?{i}UZ0wm zpJ$}k*~!J7LcwjX^XyE%P<8pMy;1gV<_m%4u=nT8-Y0Q{MmpDood~wPDUSn(2KG+` z9#oQI6TFu0#_N2^o+%(q)wIfxt&O10r27Y}xTmH+OTfG}4;0*1``o!WzSKKT(f{kr zmMEu9l;?!8wwT5A8dn^SD3L8Im@^*gUeB`sCL8G<7#=JSVUcy%BN7DjVjTmRLW557 zu-;;oKgr^v1$wNlF~kJch7K|NTzBI?So2Av5}^4e_!y6|F;7bjN`QVSejZv-0xo86KR4j#Q;n5Ao~zWN7A zsG8mO`qn+RZUDY}n>iqK-))v&^qwK6r$NJIY9j2&hK{#-etdV?1YV3xoT}p2;I3>C zm=ONRBpYVmkjSpp#?IPfV974LtfzC+Qk;3;5x01;T$Td;w429Bg7n|U-ac(sR^2I+%qA$?DzcW81GWZ-g@tk zn5#!>!GR)yhsWbYTk524a#(@fLiQfH1&F(gpXCu^pJCq)-PZs&3w~fi5)0?K++>51 zd30k)`?;ZrXPImiS5U6Na8`1mYqq7cqU*ku{S}} zG)Y>L*W{FlzRvI&)l<*3E^A%Zy>GtffoGp(;qB^lD-*I_z^MQQWFjo(Q_5s}abi)t zTk?F$6$z81!4%&Vd-+T$`y+v;zUFgFND*B$h z%7K@_TT`W}B2*!2`AhTN4G@P7n7QEnn8cWxn7B{y>1UKl%7{{_i`~w1ndHr*o=2}H zizPcIGbhIt8lNNd^Y*6~dK8-UL0lzW(XPX;w0`-bSV}&{H-nOH58s*k5;0d+9qC`S z<@&jCPJJ#>C{3tVNKojUPzt;SA(-Zw)}BU9n}N4hI9qW(0a;P4W}etVl2bo)o^_Nc zk5(R&^EmAMWJ}9?z$~jZsb-*@3-db6^(x%eFSI5Li!BWA#)NCnB!z{Bn zGq(;|XC3(RMK|!;AzJ%R{e!HitU7cCI%fj=M`3(X&(R#K9JLk|?9+=;%Nmo`l4X(U zh6#qT?WZk<`o_*WR8uM_TyE3OlJFu#O>1`98x-oH!N5J$#uIHl;&oO4QLH_oy3-R<&921DK3y3_o-V9P)oBd z8|AM#Q$tzfUK689(x7bW5q=S5?)4#(k919FK>xn^_Y+lJ%Q2H|QdguN^%~}nr=z-L zy7qMCaB>NJ6zG#XNbI>dQ6)l*m&eJ+*!y{9^_?3@p0t|Z>O4IdJLA*j(KI@wKD=E; zJGR$oZ#*)(H7P%FMu@^`_h(A!h4>4ll?m&ZCD)~VjpG`T8nGG&YJF;p0u(mT+br8Y zTce)_KhA6o(o8@qpobjq!MPv<(0MiuPDPIWyDotm>zV6oLPQl_*^Ars@w4cB(e(*C z!GYki<=gT;C@%|tD7kRC>YU#-KVOg>Mqf|2spe!{+p9KYbS%FSzpp_%vRS_$d0PL9 zeu}7e99okDh9|?=NA>`yCUvGELeXvY7{ZK@D4orK^|svt9;=#@d>q{gHm$S zz8-b)=wV^eL*qOmv~T0=;P2Hy_6=~ zNUULrA)nzSi;4D=x0fEmlO|MR+O?h@4 zYX8(uyM}N?_+E0V_4yk9r5^FYjk`E(pu}e6*%@Ek`s#_#wexWvfXB(H(8i#pBo(HzA zo4OTido-ipOgwC)%xBM4*Et2+2kI@JT#lz8!;tq|8{#hYtMv^kKTu9mYKTo}c{F*k zm9YKxv+k7xMYE=`oM#&#l_RRl?^-uRmom6c3}224D4dnr&Rl!iZ53seHSlI2@@cM; z%N64*4&-w$!Xr%xw;y&mYP=n(#ePt-^F+Lj%udwwH2L~u;u7Tfr#T5NE+1@ zQ?JrX%1XvMf>TQEmY)#|M#!`;=TeHCN>pvt0@4G>i{aa`1BYueZrLwfbD4dzX9LEzd)Ny0+G%$Bt86=O zV;3f~rNAafGYU0}xBE8+9Sg{-3-<;cDCK`T#f4YtD(ob0mYOu~q7+b$8B`d|A&Zfe zn9Z0`|3|CMA3I`FdMCr`WWGLKPwpwoyyi+7gwvCz417J0kGzP?N1j5SpQ_=zq#A{|B*BUkuT9%9118Hx!}C% z=*)n2daPgY7|Ouz|Ba`MCZXL4PTzsv`v=MY4b)KRj~UXZ(OAI509bAf-b#vBDoMe^%%hZEheLdAmD!e{(Gl>M7$#y0zhG4$bTql>Y%n1Z~eK2Z(E~KHSBY|El-^Y6N zaybFPLLA{3hzb;fgToOpI8GU%3V~su2rOO+0at-(fdAd)d%1a&=%w*3Aut340hW-^ IH!%SJ2kQZ#P5=M^ literal 0 HcmV?d00001 diff --git a/Yep/Services/YepService.swift b/Yep/Services/YepService.swift index ac825bc0..62a3783d 100644 --- a/Yep/Services/YepService.swift +++ b/Yep/Services/YepService.swift @@ -1212,6 +1212,8 @@ func sendMessage(message: Message, inFilePath filePath: String?, orFileData file realm?.write { message.sendState = MessageSendState.Failed.rawValue } + + NSNotificationCenter.defaultCenter().postNotificationName(MessageNotification.MessageStateChanged, object: nil) } }, completion: { messageID in @@ -1271,6 +1273,8 @@ func sendMessage(message: Message, inFilePath filePath: String?, orFileData file realm?.write { message.sendState = MessageSendState.Failed.rawValue } + + NSNotificationCenter.defaultCenter().postNotificationName(MessageNotification.MessageStateChanged, object: nil) } }, completion: { messageID in diff --git a/Yep/ViewControllers/Conversation/ConversationViewController.swift b/Yep/ViewControllers/Conversation/ConversationViewController.swift index 43e3bbb5..1f8b3a44 100644 --- a/Yep/ViewControllers/Conversation/ConversationViewController.swift +++ b/Yep/ViewControllers/Conversation/ConversationViewController.swift @@ -14,8 +14,6 @@ import MapKit struct MessageNotification { - static let MessageSent = "MessageSentNotification" - static let MessageRead = "MessageReadNotification" static let MessageStateChanged = "MessageStateChangedNotification" } diff --git a/Yep/Views/Cells/ChatRightBase/ChatRightBaseCell.swift b/Yep/Views/Cells/ChatRightBase/ChatRightBaseCell.swift index 2ca53067..23c56d78 100644 --- a/Yep/Views/Cells/ChatRightBase/ChatRightBaseCell.swift +++ b/Yep/Views/Cells/ChatRightBase/ChatRightBaseCell.swift @@ -35,7 +35,8 @@ class ChatRightBaseCell: UICollectionViewCell { removeSendingAnimation() case MessageSendState.Failed: - dotImageView.hidden = true + dotImageView.image = UIImage(named: "icon_dot_failed") + dotImageView.hidden = false removeSendingAnimation()