Skip to content
This repository has been archived by the owner on Jun 7, 2020. It is now read-only.

[NEW] Send messages via HTTP + WebSockets fallback #1053

Merged
merged 5 commits into from
Dec 7, 2017
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions Rocket.Chat.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,9 @@
77C2612E1F97453600724A1F /* TextFieldSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 77C2612B1F97453600724A1F /* TextFieldSpec.swift */; };
77CCB6BE1F8D0597004BBF67 /* DictionaryExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 77CCB6BD1F8D0597004BBF67 /* DictionaryExtensions.swift */; };
7DE1B07114BBD1D46E9CC71B /* Pods_Rocket_Chat.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0F5191CD6C53AEA006C82524 /* Pods_Rocket_Chat.framework */; };
80054CF11FD9505A00F5ECF9 /* SendMessageRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 80054CF01FD9505A00F5ECF9 /* SendMessageRequest.swift */; };
80054CF31FD951B100F5ECF9 /* MessagesClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 80054CF21FD951B100F5ECF9 /* MessagesClient.swift */; };
80054CF51FD96AFE00F5ECF9 /* MessagesClientSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 80054CF41FD96AFE00F5ECF9 /* MessagesClientSpec.swift */; };
800E22841F8500A200DA84F1 /* MessagesListViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 800E22831F8500A200DA84F1 /* MessagesListViewController.swift */; };
800E22861F8507E400DA84F1 /* SubscriptionMessagesRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 800E22851F8507E400DA84F1 /* SubscriptionMessagesRequest.swift */; };
800FCD3E1F72893E00D9A692 /* MembersListViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 800FCD3D1F72893E00D9A692 /* MembersListViewController.swift */; };
Expand Down Expand Up @@ -512,6 +515,9 @@
77C2612A1F97453600724A1F /* SelectFieldSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SelectFieldSpec.swift; sourceTree = "<group>"; };
77C2612B1F97453600724A1F /* TextFieldSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextFieldSpec.swift; sourceTree = "<group>"; };
77CCB6BD1F8D0597004BBF67 /* DictionaryExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DictionaryExtensions.swift; sourceTree = "<group>"; };
80054CF01FD9505A00F5ECF9 /* SendMessageRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SendMessageRequest.swift; sourceTree = "<group>"; };
80054CF21FD951B100F5ECF9 /* MessagesClient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessagesClient.swift; sourceTree = "<group>"; };
80054CF41FD96AFE00F5ECF9 /* MessagesClientSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessagesClientSpec.swift; sourceTree = "<group>"; };
800E22831F8500A200DA84F1 /* MessagesListViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = MessagesListViewController.swift; path = Controllers/Chat/MessagesListViewController.swift; sourceTree = "<group>"; };
800E22851F8507E400DA84F1 /* SubscriptionMessagesRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubscriptionMessagesRequest.swift; sourceTree = "<group>"; };
800FCD3D1F72893E00D9A692 /* MembersListViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = MembersListViewController.swift; path = Controllers/Chat/MembersListViewController.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1307,6 +1313,7 @@
8013F86E1FD6B59D00EE1A4E /* Clients */ = {
isa = PBXGroup;
children = (
80054CF21FD951B100F5ECF9 /* MessagesClient.swift */,
8013F8701FD6B5B000EE1A4E /* CommandsClient.swift */,
8013F86F1FD6B5B000EE1A4E /* InfoClient.swift */,
);
Expand All @@ -1332,6 +1339,7 @@
8013F87E1FD6B66900EE1A4E /* Clients */ = {
isa = PBXGroup;
children = (
80054CF41FD96AFE00F5ECF9 /* MessagesClientSpec.swift */,
8013F87F1FD6B6C600EE1A4E /* CommandsClientSpec.swift */,
8013F8801FD6B6C600EE1A4E /* InfoClientSpec.swift */,
);
Expand Down Expand Up @@ -1407,6 +1415,7 @@
isa = PBXGroup;
children = (
806C59A11FBB0BD600C32D0A /* PostMessageRequest.swift */,
80054CF01FD9505A00F5ECF9 /* SendMessageRequest.swift */,
);
path = Message;
sourceTree = "<group>";
Expand Down Expand Up @@ -2107,6 +2116,7 @@
80113DF81F98330C0048F2C2 /* OAuthViewController.swift in Sources */,
41BD37E11E290F2900CBC4C2 /* UserModelMapping.swift in Sources */,
412BCC871E55C6B800F7F4EE /* ChatMessageTextView.swift in Sources */,
80054CF31FD951B100F5ECF9 /* MessagesClient.swift in Sources */,
8013F86D1FD6B59A00EE1A4E /* APIClient.swift in Sources */,
414D99161EA0E7CB0020F7E9 /* SignupViewController.swift in Sources */,
800FCD4F1F728EC800D9A692 /* ChannelInfoUserCell.swift in Sources */,
Expand Down Expand Up @@ -2189,6 +2199,7 @@
D32E28251DFD86C300D6019C /* LauncherProtocol.swift in Sources */,
41DF76E31D2C50710028DBF8 /* AppDelegate.swift in Sources */,
D18675EC1F716A0D00406FB4 /* LoginRequest.swift in Sources */,
80054CF11FD9505A00F5ECF9 /* SendMessageRequest.swift in Sources */,
4174CB131D2D99960086DAC8 /* BaseViewController.swift in Sources */,
897083D31F8CF08100233561 /* CheckTableViewCell.swift in Sources */,
597ECBA21E3708A50041C5C5 /* DataExtension.swift in Sources */,
Expand Down Expand Up @@ -2257,6 +2268,7 @@
418C74451FA3820F00499577 /* CompoundPickerViewDelegateSpec.swift in Sources */,
8013F8821FD6B6C600EE1A4E /* InfoClientSpec.swift in Sources */,
77C261251F97445300724A1F /* AuthSettingsSpec.swift in Sources */,
80054CF51FD96AFE00F5ECF9 /* MessagesClientSpec.swift in Sources */,
411498E51FC7B8D500D66542 /* AttachmentSpec.swift in Sources */,
8013F87C1FD6B64500EE1A4E /* MockAPI.swift in Sources */,
41DC7A221D386B4700896FC0 /* StringExtensionSpec.swift in Sources */,
Expand Down
56 changes: 56 additions & 0 deletions Rocket.Chat/API/Clients/MessagesClient.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
//
// MessagesClient.swift
// Rocket.Chat
//
// Created by Matheus Cardoso on 12/7/17.
// Copyright © 2017 Rocket.Chat. All rights reserved.
//

import RealmSwift
import SwiftyJSON

struct MessagesClient: APIClient {
let api: AnyAPIFetcher

func sendMessage(text: String, subscription: Subscription, id: String = String.random(18), user: User? = AuthManager.currentUser(), realm: Realm? = Realm.shared) {
let message = Message()
message.internalType = ""
message.createdAt = Date.serverDate
message.text = text
message.subscription = subscription
message.user = user
message.identifier = id
message.temporary = true

try? realm?.write {
realm?.add(message)
}

func updateMessage(json: JSON) {
DispatchQueue.main.async {
try? realm?.write {
message.temporary = false
message.map(json, realm: realm)
realm?.add(message, update: true)
}

MessageTextCacheManager.shared.update(for: message, completion: nil)
}
}

api.fetch(SendMessageRequest(id: id, roomId: subscription.rid, text: text), succeeded: { result in
guard let message = result.raw?["message"] else { return }
updateMessage(json: message)
}, errored: { error in
switch error {
case .version:
// old server version: fallback to web sockets
SubscriptionManager.sendTextMessage(message, completion: { response in
updateMessage(json: response.result["result"])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's add the TODO here?👌

})
default:
break
}
})
}
}
43 changes: 43 additions & 0 deletions Rocket.Chat/API/Requests/Message/SendMessageRequest.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
//
// SendMessageRequest.swift
// Rocket.Chat
//
// Created by Matheus Cardoso on 12/7/17.
// Copyright © 2017 Rocket.Chat. All rights reserved.
//

import SwiftyJSON

typealias SendMessageResult = APIResult<SendMessageRequest>

class SendMessageRequest: APIRequest {
let method = "POST"
let path = "/api/v1/chat.sendMessage"
let requiredVersion = Version(0, 60, 0)

let id: String
let roomId: String
let text: String

init(id: String, roomId: String, text: String) {
self.id = id
self.roomId = roomId
self.text = text
}

func body() -> Data? {
let body = JSON([
"message": [
"_id": id,
"rid": roomId,
"msg": text
]
])

return body.rawString()?.data(using: .utf8)
}
}

extension APIResult where T == SendMessageRequest {

}
29 changes: 2 additions & 27 deletions Rocket.Chat/Controllers/Chat/ChatViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -384,33 +384,8 @@ final class ChatViewController: SLKTextViewController, Alerter {
return
}

var message: Message?
Realm.executeOnMainThread({ (realm) in
message = Message()
message?.internalType = ""
message?.createdAt = Date.serverDate
message?.text = text
message?.subscription = subscription
message?.identifier = String.random(18)
message?.temporary = true
message?.user = AuthManager.currentUser()

if let message = message {
realm.add(message)
}
})

if let message = message {
SubscriptionManager.sendTextMessage(message) { response in
Realm.executeOnMainThread({ (realm) in
message.temporary = false
message.map(response.result["result"], realm: realm)
realm.add(message, update: true)

MessageTextCacheManager.shared.update(for: message, completion: nil)
})
}
}
guard let client = API.current()?.client(MessagesClient.self) else { return }
client.sendMessage(text: text, subscription: subscription)
}

fileprivate func updateCellForMessage(identifier: String) {
Expand Down
55 changes: 55 additions & 0 deletions Rocket.ChatTests/API/Clients/MessagesClientSpec.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
//
// MessagesClientSpec.swift
// Rocket.ChatTests
//
// Created by Matheus Cardoso on 12/7/17.
// Copyright © 2017 Rocket.Chat. All rights reserved.
//

import XCTest
import SwiftyJSON

@testable import Rocket_Chat

class MessagesClientSpec: XCTestCase, RealmTestCase {
func testSendMessage() {
let api = MockAPI()
let realm = testRealm()
let client = MessagesClient(api: api)

api.nextResult = JSON([
"success": true,
"message": [
"mentions": [],
"_id": "a43SYFpMdjEAdM0mrH",
"_updatedAt": "2017-12-07T12:30:38.384Z",
"channels": [],
"rid": "GENERAL",
"u": [
"name": "Matheus Cardoso",
"username": "matheus.cardoso",
"_id": "ERoZg2xpgcDnXbCJu"
],
"ts": "2017-12-07T12:30:38.382Z",
"msg": "Test"
]
])

let user = User.testInstance()
let subscription = Subscription.testInstance()

client.sendMessage(text: "test", subscription: subscription, id: "a43SYFpMdjEAdM0mrH", user: user, realm: realm)

let messages = realm.objects(Message.self)
XCTAssertEqual(messages.count, 1)
XCTAssertEqual(realm.objects(Message.self).first?.temporary, true)

let expectation = XCTestExpectation(description: "message updated in realm")
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0, execute: {
if realm.objects(Message.self).first?.temporary == false {
expectation.fulfill()
}
})
wait(for: [expectation], timeout: 1.1)
}
}