Makes it so we don't have to wait for all servers to be connected before fetching

This commit is contained in:
2020-04-30 23:36:37 -07:00
parent 1bad5ae5b0
commit 1cfdf3552f
4 changed files with 42 additions and 49 deletions

View File

@@ -272,6 +272,7 @@
CreatedOnToolsVersion = 7.2;
DevelopmentTeam = F7W5R35V7L;
LastSwiftMigration = 1010;
ProvisioningStyle = Manual;
};
};
};
@@ -471,14 +472,16 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_IDENTITY = "Apple Distribution: Charles Magahern (F7W5R35V7L)";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Distribution: Charles Magahern (F7W5R35V7L)";
CODE_SIGN_STYLE = Manual;
DEVELOPMENT_TEAM = F7W5R35V7L;
INFOPLIST_FILE = "$(SRCROOT)/XIONControlPanel/SupportingFiles/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.zanneth.XIONControlPanel;
PRODUCT_NAME = XION;
PROVISIONING_PROFILE = "";
PROVISIONING_PROFILE_SPECIFIER = "Octahedron II";
SWIFT_OBJC_BRIDGING_HEADER = "XIONControlPanel/SupportingFiles/XIONControlPanel-Bridging-Header.h";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
@@ -490,14 +493,16 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_IDENTITY = "Apple Distribution: Charles Magahern (F7W5R35V7L)";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Distribution: Charles Magahern (F7W5R35V7L)";
CODE_SIGN_STYLE = Manual;
DEVELOPMENT_TEAM = F7W5R35V7L;
INFOPLIST_FILE = "$(SRCROOT)/XIONControlPanel/SupportingFiles/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.zanneth.XIONControlPanel;
PRODUCT_NAME = XION;
PROVISIONING_PROFILE = "";
PROVISIONING_PROFILE_SPECIFIER = "Octahedron II";
SWIFT_OBJC_BRIDGING_HEADER = "XIONControlPanel/SupportingFiles/XIONControlPanel-Bridging-Header.h";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";

View File

@@ -52,7 +52,10 @@ public class HubitatServer : Server
.decode(type: [HubitatDevice].self, decoder: JSONDecoder())
.sink(receiveCompletion: { completion in
if case let Subscribers.Completion.failure(error) = completion {
self.connected = false
fetchCompletion(.failure(error))
} else {
self.connected = true
}
}) { (devices: [HubitatDevice]) in
self.devices = devices

View File

@@ -54,10 +54,6 @@ class ServerMultiplex
public func refreshDevices()
{
ensureConnection { (error: Error?) in
if let error = error {
self.handleError(error)
} else {
self.servers.forEach { (server: Server) in
server.fetchDevices { (result: Result<[AnyDevice], Error>) in
self.handleServerFetchResult(result)
@@ -65,30 +61,9 @@ class ServerMultiplex
}
}
}
}
}
extension ServerMultiplex
{
private func ensureConnection(then: @escaping (Error?) -> Void)
{
let disconnectedServers = servers.filter { $0.connected == false }
var disconnectedServerCount = disconnectedServers.count
if disconnectedServerCount > 0 {
disconnectedServers.forEach { (server: Server) in
server.connect { (error: Error?) in
disconnectedServerCount -= 1
if disconnectedServerCount == 0 {
then(error)
}
}
}
} else {
then(nil)
}
}
private func handleServerFetchResult(_ result: Result<[AnyDevice], Error>)
{
switch result {

View File

@@ -26,8 +26,10 @@ class WemoServer : Server
{
private var devices: [WemoDevice] = []
public var connected: Bool { get { return self.connectionStatus == .connected } }
fileprivate(set) var baseURL: URL
fileprivate(set) var connected: Bool = false
fileprivate(set) var connectionStatus: ConnectionStatus = .disconnected
fileprivate var _urlSession: URLSession
fileprivate var _errorStream: StandardErrorOutputStream = StandardErrorOutputStream()
@@ -45,15 +47,16 @@ class WemoServer : Server
func connect(_ completion: @escaping (Error?) -> Void)
{
if (!self.connected) {
if (self.connectionStatus == .disconnected) {
let op = ConnectOperation(baseURL: self.baseURL, session: _urlSession)
weak var weakOp = op
op.completionBlock = {
guard let strongOp = weakOp else { completion(nil) ; return }
if let error = strongOp.error {
self._logError("Error connecting to server", error: error)
self.connectionStatus = .disconnected
} else {
self.connected = true
self.connectionStatus = .connected
}
completion(strongOp.error)
@@ -66,13 +69,12 @@ class WemoServer : Server
func disconnect(_ completion: (Error?) -> Void)
{
self.connected = false
self.connectionStatus = .disconnected
completion(nil)
}
func fetchDevices(_ completion: @escaping (Result<[AnyDevice], Error>) -> Void)
{
if (self.connected) {
let op = FetchDevicesOperation(baseURL: self.baseURL, session: _urlSession)
weak var weakOp = op
op.completionBlock = {
@@ -87,6 +89,14 @@ class WemoServer : Server
self.devices = strongOp.devices
completion(.success(self.devices.map { AnyDevice($0) }))
}
if self.connectionStatus == .disconnected {
connect { error in
if error == nil {
self._operationQueue.addOperation(op)
}
}
} else if self.connectionStatus == .connected {
_operationQueue.addOperation(op)
} else {
completion(.failure(ConnectionError.serverUnavailable))