Retry delaying servers loading
This commit is contained in:
parent
02a169205d
commit
045f2084cd
|
@ -25,51 +25,11 @@ protocol ServersLoading {
|
|||
final class ServersLoader: NSObject {
|
||||
@Dependency private var database: ServersDatabase
|
||||
|
||||
private let session: WCSession
|
||||
private let session: WatchSessionProtocol
|
||||
|
||||
init(session: WCSession) {
|
||||
init(session: WatchSessionProtocol = RetriableWatchSession()) {
|
||||
self.session = session
|
||||
super.init()
|
||||
session.delegate = self
|
||||
session.activate()
|
||||
}
|
||||
|
||||
private func sendMessage(completionHandler: @escaping (Result<WatchMessage, ServersLoadingError>) -> Void) {
|
||||
print("sendMessage")
|
||||
|
||||
guard session.activationState == .activated else {
|
||||
completionHandler(.failure(.unactive))
|
||||
return
|
||||
}
|
||||
|
||||
guard !session.iOSDeviceNeedsUnlockAfterRebootForReachability else {
|
||||
completionHandler(.failure(.locked))
|
||||
return
|
||||
}
|
||||
|
||||
guard session.isReachable else {
|
||||
completionHandler(.failure(.unreachable))
|
||||
return
|
||||
}
|
||||
|
||||
session.sendMessage([:]) { dictionary in
|
||||
do {
|
||||
let data = try JSONSerialization.data(withJSONObject: dictionary)
|
||||
let message = try JSONDecoder().decode(WatchMessage.self, from: data)
|
||||
|
||||
completionHandler(.success(message))
|
||||
} catch {
|
||||
completionHandler(.failure(.undecodable(error)))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - WCSessionDelegate
|
||||
|
||||
extension ServersLoader: WCSessionDelegate {
|
||||
func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -78,7 +38,7 @@ extension ServersLoader: WCSessionDelegate {
|
|||
extension ServersLoader: ServersLoading {
|
||||
func loadServers() -> AnyPublisher<Void, ServersLoadingError> {
|
||||
Future<Void, ServersLoadingError> { [self] promise in
|
||||
sendMessage { result in
|
||||
session.sendMessage { result in
|
||||
switch result {
|
||||
case .success(let message):
|
||||
for server in message.servers {
|
||||
|
|
|
@ -0,0 +1,98 @@
|
|||
import WatchConnectivity
|
||||
|
||||
protocol WatchSessionProtocol {
|
||||
func sendMessage(completionHandler: @escaping (Result<WatchMessage, ServersLoadingError>) -> Void)
|
||||
}
|
||||
|
||||
/// Default WatchSession protocol implementation.
|
||||
final class WatchSession: NSObject, WatchSessionProtocol, WCSessionDelegate {
|
||||
private let session: WCSession
|
||||
|
||||
init(session: WCSession) {
|
||||
self.session = session
|
||||
super.init()
|
||||
session.delegate = self
|
||||
session.activate()
|
||||
}
|
||||
|
||||
func sendMessage(completionHandler: @escaping (Result<WatchMessage, ServersLoadingError>) -> Void) {
|
||||
guard session.activationState == .activated else {
|
||||
completionHandler(.failure(.unactive))
|
||||
return
|
||||
}
|
||||
|
||||
guard !session.iOSDeviceNeedsUnlockAfterRebootForReachability else {
|
||||
completionHandler(.failure(.locked))
|
||||
return
|
||||
}
|
||||
|
||||
guard session.isReachable else {
|
||||
completionHandler(.failure(.unreachable))
|
||||
return
|
||||
}
|
||||
|
||||
session.sendMessage([:]) { dictionary in
|
||||
do {
|
||||
let data = try JSONSerialization.data(withJSONObject: dictionary)
|
||||
let message = try JSONDecoder().decode(WatchMessage.self, from: data)
|
||||
|
||||
completionHandler(.success(message))
|
||||
} catch {
|
||||
completionHandler(.failure(.undecodable(error)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/// Retry decorator for WatchSession protocol.
|
||||
final class RetriableWatchSession: WatchSessionProtocol {
|
||||
private let session: WatchSessionProtocol
|
||||
private let retries: Int
|
||||
|
||||
init(session: WatchSessionProtocol = DelayableWatchSession(session: WatchSession(session: .default)), retries: Int = 3) {
|
||||
self.session = session
|
||||
self.retries = retries
|
||||
}
|
||||
|
||||
func sendMessage(completionHandler: @escaping (Result<WatchMessage, ServersLoadingError>) -> Void) {
|
||||
session.sendMessage { [weak self] result in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
|
||||
switch result {
|
||||
case .success(let message):
|
||||
completionHandler(.success(message))
|
||||
case .failure where retries > 0:
|
||||
session.sendMessage(completionHandler: completionHandler)
|
||||
case .failure(let error):
|
||||
completionHandler(.failure(error))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Delay decorator for WatchSession protocol.
|
||||
final class DelayableWatchSession: WatchSessionProtocol {
|
||||
private let delay: TimeInterval
|
||||
private let session: WatchSessionProtocol
|
||||
|
||||
init(delay: TimeInterval = 1, session: WatchSessionProtocol) {
|
||||
self.delay = delay
|
||||
self.session = session
|
||||
}
|
||||
|
||||
func sendMessage(completionHandler: @escaping (Result<WatchMessage, ServersLoadingError>) -> Void) {
|
||||
Timer.scheduledTimer(withTimeInterval: 1, repeats: false) { [weak self] _ in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
|
||||
self.session.sendMessage(completionHandler: completionHandler)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -11,7 +11,7 @@ struct RocketChat_Watch_AppApp: App {
|
|||
private func registerDependencies() {
|
||||
Store.register(AppRouting.self, factory: router)
|
||||
Store.register(ServersDatabase.self, factory: DefaultDatabase())
|
||||
Store.register(ServersLoading.self, factory: ServersLoader(session: .default))
|
||||
Store.register(ServersLoading.self, factory: ServersLoader())
|
||||
Store.register(MessagesLoading.self, factory: MessagesLoader())
|
||||
Store.register(RoomsLoading.self, factory: RoomsLoader())
|
||||
}
|
||||
|
|
|
@ -113,6 +113,7 @@
|
|||
1E76CBD825152C870067298C /* Request.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E680ED82512990700C9257A /* Request.swift */; };
|
||||
1E76CBD925152C8C0067298C /* Push.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E2F61652512958900871711 /* Push.swift */; };
|
||||
1E76CBDA25152C8E0067298C /* SendMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E598AE825151A63002BDFBD /* SendMessage.swift */; };
|
||||
1E8979472B6063FC001D99F0 /* WatchSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E8979462B6063FC001D99F0 /* WatchSession.swift */; };
|
||||
1E9A71692B59B6E100477BA2 /* MessageSender.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E9A71682B59B6E100477BA2 /* MessageSender.swift */; };
|
||||
1E9A716F2B59CBCA00477BA2 /* AttachmentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E9A716E2B59CBCA00477BA2 /* AttachmentView.swift */; };
|
||||
1E9A71712B59CC1300477BA2 /* Attachment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E9A71702B59CC1300477BA2 /* Attachment.swift */; };
|
||||
|
@ -404,6 +405,7 @@
|
|||
1E6737FF24DC52660009E081 /* NotificationService-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NotificationService-Bridging-Header.h"; sourceTree = "<group>"; };
|
||||
1E67380324DC529B0009E081 /* String+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+Extensions.swift"; sourceTree = "<group>"; };
|
||||
1E680ED82512990700C9257A /* Request.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Request.swift; sourceTree = "<group>"; };
|
||||
1E8979462B6063FC001D99F0 /* WatchSession.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchSession.swift; sourceTree = "<group>"; };
|
||||
1E9A71682B59B6E100477BA2 /* MessageSender.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageSender.swift; sourceTree = "<group>"; };
|
||||
1E9A716E2B59CBCA00477BA2 /* AttachmentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttachmentView.swift; sourceTree = "<group>"; };
|
||||
1E9A71702B59CC1300477BA2 /* Attachment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Attachment.swift; sourceTree = "<group>"; };
|
||||
|
@ -865,6 +867,7 @@
|
|||
1EDFD1052B58A66E002FEE5F /* CancelBag.swift */,
|
||||
1EDFD1072B58AA77002FEE5F /* RoomsLoader.swift */,
|
||||
1E9A71682B59B6E100477BA2 /* MessageSender.swift */,
|
||||
1E8979462B6063FC001D99F0 /* WatchSession.swift */,
|
||||
);
|
||||
path = Loaders;
|
||||
sourceTree = "<group>";
|
||||
|
@ -1185,7 +1188,6 @@
|
|||
};
|
||||
1ED0388D2B507B4B00C007D4 = {
|
||||
CreatedOnToolsVersion = 15.0;
|
||||
DevelopmentTeam = S6UPZG7ZR3;
|
||||
ProvisioningStyle = Automatic;
|
||||
};
|
||||
1EFEB5942493B6640072EDC0 = {
|
||||
|
@ -1876,6 +1878,7 @@
|
|||
1ED033CD2B55D671004F4930 /* RocketChatDatabase.swift in Sources */,
|
||||
1E29A3122B5866090093C03C /* Room.swift in Sources */,
|
||||
1E29A3032B585B070093C03C /* FailableDecodable.swift in Sources */,
|
||||
1E8979472B6063FC001D99F0 /* WatchSession.swift in Sources */,
|
||||
1E29A2FE2B585B070093C03C /* ReadRequest.swift in Sources */,
|
||||
1E9A71692B59B6E100477BA2 /* MessageSender.swift in Sources */,
|
||||
1E29A3072B585B070093C03C /* RocketChatError.swift in Sources */,
|
||||
|
@ -2307,7 +2310,7 @@
|
|||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
DEVELOPMENT_ASSET_PATHS = "\"RocketChat Watch App/Preview Content\"";
|
||||
DEVELOPMENT_TEAM = S6UPZG7ZR3;
|
||||
DEVELOPMENT_TEAM = "";
|
||||
ENABLE_PREVIEWS = YES;
|
||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu17;
|
||||
|
|
Loading…
Reference in New Issue