Skip to content

Instantly share code, notes, and snippets.

@kraigspear
Created May 18, 2018 08:18
Show Gist options
  • Select an option

  • Save kraigspear/666c44e6d06615c97aadfb2aaa5915a7 to your computer and use it in GitHub Desktop.

Select an option

Save kraigspear/666c44e6d06615c97aadfb2aaa5915a7 to your computer and use it in GitHub Desktop.
Mac App to show logs
//
// 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
}
}
}
@kraigspear
Copy link
Author

  1. Code to fetch logs
  2. ViewModel that calls

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment