Created
May 18, 2018 08:18
-
-
Save kraigspear/666c44e6d06615c97aadfb2aaa5915a7 to your computer and use it in GitHub Desktop.
Mac App to show logs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // | |
| // LogFetcher.swift | |
| // LogQuery | |
| // | |
| // Created by Kraig Spear on 5/13/18. | |
| // Copyright © 2018 spearware. All rights reserved. | |
| // | |
| import Foundation | |
| import SpearSwiftLibmacOS | |
| protocol LogFetchable { | |
| func fetch(completed: @escaping (LogResult) -> Void) | |
| } | |
| typealias LogResult = NetworkResult<[Log]> | |
| struct LogRequest {} | |
| enum LogFetchError: Error { | |
| case failedToParse | |
| } | |
| extension LogRequest: RequestBuildable { | |
| var request: URLRequest { | |
| var url = URL(string: "")! | |
| url = url.add(code: "", max: "100") | |
| var request = URLRequest(url: url) | |
| request.httpMethod = "GET" | |
| return request | |
| } | |
| } | |
| final class LogFetcher: LogFetchable { | |
| func fetch(completed: @escaping (LogResult) -> Void) { | |
| let logRequest = LogRequest() | |
| let sessionConfig = URLSessionConfiguration.default | |
| let session = URLSession(configuration: sessionConfig) | |
| let task = session.dataTask(with: logRequest.request) { data, response, error in | |
| if let error = error { | |
| print(error) | |
| DispatchQueue.main.async { | |
| completed(NetworkResult.error(error: error)) | |
| } | |
| return | |
| } | |
| let statusCode = (response as! HTTPURLResponse).statusCode | |
| if statusCode != 200 { | |
| DispatchQueue.main.async { | |
| completed(LogResult.response(code: statusCode)) | |
| } | |
| return | |
| } | |
| if let data = data { | |
| do { | |
| let logs = try JSONDecoder().decode([Log].self, from: data) | |
| DispatchQueue.main.async { | |
| completed(LogResult.success(result: logs)) | |
| } | |
| } catch let error { | |
| DispatchQueue.main.async { | |
| completed(LogResult.error(error: error)) | |
| } | |
| } | |
| } else { | |
| preconditionFailure("Invalid state, not code, error or data") | |
| } | |
| } | |
| task.resume() | |
| session.finishTasksAndInvalidate() | |
| } | |
| } | |
| private extension URL { | |
| func add(code: String, max: String) -> URL { | |
| var params: NetworkParameterType = NetworkParameters() | |
| params = params.addParam("code", value: code) | |
| let url = params.NSURLByAppendingQueryParameters(self) | |
| return url | |
| } | |
| } | |
| // ViewModel | |
| // | |
| // MainViewModel.swift | |
| // LogQuery | |
| // | |
| // Created by Kraig Spear on 5/13/18. | |
| // Copyright © 2018 spearware. All rights reserved. | |
| // | |
| import Foundation | |
| import SpearSwiftLibmacOS | |
| final class MainViewModel { | |
| private let logFetcher: LogFetchable | |
| init(logFetchable: LogFetchable) { | |
| self.logFetcher = logFetchable | |
| } | |
| convenience init() { | |
| self.init(logFetchable: LogFetcher()) | |
| } | |
| private let logsObservable = Observable<[Log]>(value: []) | |
| private let busyObservable = Observable<Bool>(value: false) | |
| var logs: AnySubscribeable<[Log]> { | |
| return logsObservable.asSubscribeable | |
| } | |
| var isBusy: AnySubscribeable<Bool> { | |
| return busyObservable.asSubscribeable | |
| } | |
| func reload() { | |
| busyObservable.value = true | |
| logFetcher.fetch { [weak self] result in | |
| guard let mySelf = self else { return } | |
| switch result { | |
| case let .success(result: logs): | |
| mySelf.logsObservable.value = logs | |
| default: | |
| break | |
| } | |
| mySelf.busyObservable.value = false | |
| } | |
| } | |
| } | |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Note
The observable is not Rx, but my own simple class that allows multiple listeners on a property (similar to Rx without the baggage and complexity) A standard delegate pattern would work fine.