Model/ConversationTransport.swift
/* |
Copyright (C) 2018 Apple Inc. All Rights Reserved. |
See LICENSE.txt for this sample’s licensing information |
Abstract: |
Represents a conversation backed by a TCPTransport. |
*/ |
import Foundation |
/// This class represents a conversation that is backed by a TCPTransport, which |
/// updates the conversation as events happen on the network. |
class ConversationTransport : TCPTransportDelegate { |
/// Create an object, starting with a fresh conversation that’s then updated |
/// by the transport. |
/// |
/// - Parameters: |
/// - localizedName: The name of the new conversation. |
/// - transport: The transport that updates it. At this point this object |
/// effectively owns the transport, becoming its delegate. |
required init(localizedName: String, transport: TCPTransport) { |
self.transport = transport |
self.conversation = Conversation( |
localizedName: localizedName, |
messages: [], |
state: .offline(localizedStatus: transport.localizedTransportState) |
) |
self.transport.delegate = self |
} |
/// The value passed to the initialiser. |
let transport: TCPTransport |
/// The current state of the conversation; the object posts the |
/// `conversationDidChange` notification after updating this. |
private(set) var conversation: Conversation { |
didSet { |
NotificationCenter.default.post(name: ConversationTransport.conversationDidChange, object: self, userInfo: nil) |
} |
} |
/// Starts the transport. |
func start() { |
self.transport.start() |
} |
/// Stops the transport. |
func stop() { |
self.transport.stop() |
} |
/// Sends a message over the transport. It's only safe to call this when |
/// the conversation in online. |
/// |
/// - Parameter message: The message to send; this shouldn’t contain any |
/// line breaks but the presence of line breaks won’t cause a failure. |
func send(message: String) { |
guard case .started = self.transport.transportState else { fatalError() } |
self.add(message: |
Message(text: message, date: Date(), direction: .outgoing) |
) |
self.transport.send(message: message) |
} |
/// Adds a message, either incoming or outgoing, to the conversation. |
private func add(message: Message) { |
self.conversation.messages.append(message) |
} |
func didStart(transport: TCPTransport) { |
self.conversation.state = .online |
} |
func didReceive(message: String, transport: TCPTransport) { |
self.add(message: |
Message(text: message, date: Date(), direction: .incoming) |
) |
} |
func didStop(transport: TCPTransport) { |
self.conversation.state = .offline(localizedStatus: self.transport.localizedTransportState) |
} |
/// Posted after the `conversation` property has been changed, including |
/// online/offline state changes and the addition of both incoming and |
/// outgoing messages. |
static let conversationDidChange = Notification.Name("ConversationTransport.conversationDidChange") |
} |
private extension TCPTransport { |
/// Returns a localised interpretation of the transport’s state. |
var localizedTransportState: String { |
switch self.transportState { |
case .initialised: return NSLocalizedString("_not_started_", comment: "Connection status associated with the conversation.") |
case .starting: return NSLocalizedString("_connecting_", comment: "Connection status associated with the conversation.") |
case .started: return NSLocalizedString("_connected_", comment: "Connection status associated with the conversation.") |
case .stopped(nil): return NSLocalizedString("_stopped_", comment: "Connection status associated with the conversation.") |
case .stopped(_): return NSLocalizedString("_failed_", comment: "Connection status associated with the conversation.") |
} |
} |
} |
Copyright © 2018 Apple Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2018-05-10