1
0
mirror of https://github.com/Toxblh/MTMR.git synced 2026-01-11 09:28:38 +00:00
MTMR/MTMR/Widgets/WeatherBarItem.swift
Fedor Zaitsev 101a81bf3b Refactored parsing
Rewrote presets parsing. Instead of parsing presets in a separate file using bunch of huge enums it is now parsed inside each object.

To implement a new class:
1. Derive your class from CustomTouchBarItem (for static) or CustomButtonTouchBarItem (for buttons)
2. Override class var typeIdentifier with your object identificator
3. Override init(from decoder: Decoder) and read all custom json params you need
4. Don't forget to call super.init(identifier: CustomTouchBarItem.createIdentifier(type)) in the init() function
5. Add your new class to BarItemDefinition.types in ItemParsing.swift

Good example is PomodoroBarItem

If you want to inherid from some other NS class (NSSlider or NSPopoverTouchBarItem or other) then look into GroupBarItem and BrightnessViewController
2020-04-30 22:16:24 -07:00

187 lines
6.5 KiB
Swift

//
// WeatherBarItem.swift
// MTMR
//
// Created by Daniel Apatin on 18.04.2018.
// Copyright © 2018 Anton Palgunov. All rights reserved.
//
import Cocoa
import CoreLocation
class WeatherBarItem: CustomButtonTouchBarItem, CLLocationManagerDelegate {
private let activity: NSBackgroundActivityScheduler
private var units: String
private var api_key: String
private var units_str = "°F"
private var prev_location: CLLocation!
private var location: CLLocation!
private let iconsImages = ["01d": "☀️", "01n": "☀️", "02d": "⛅️", "02n": "⛅️", "03d": "☁️", "03n": "☁️", "04d": "☁️", "04n": "☁️", "09d": "⛅️", "09n": "⛅️", "10d": "🌦", "10n": "🌦", "11d": "🌩", "11n": "🌩", "13d": "❄️", "13n": "❄️", "50d": "🌫", "50n": "🌫"]
private let iconsText = ["01d": "", "01n": "", "02d": "", "02n": "", "03d": "", "03n": "", "04d": "", "04n": "", "09d": "", "09n": "", "10d": "", "10n": "", "11d": "", "11n": "", "13d": "", "13n": "", "50d": "", "50n": ""]
private var iconsSource: Dictionary<String, String>
private var manager: CLLocationManager!
override class var typeIdentifier: String {
return "weather"
}
private enum CodingKeys: String, CodingKey {
case refreshInterval
case units
case api_key
case icon_type
}
init(identifier: NSTouchBarItem.Identifier, interval: TimeInterval, units: String, api_key: String, icon_type: String? = "text") {
self.activity = NSBackgroundActivityScheduler(identifier: "\(identifier.rawValue).updatecheck")
self.activity.interval = interval
self.units = units
self.api_key = api_key
if self.units == "metric" {
units_str = "°C"
}
if self.units == "imperial" {
units_str = "°F"
}
if icon_type == "images" {
iconsSource = iconsImages
} else {
iconsSource = iconsText
}
super.init(identifier: identifier, title: "")
self.setup()
}
required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let icon_type = try container.decodeIfPresent(String.self, forKey: .icon_type) ?? "text"
self.activity = NSBackgroundActivityScheduler(identifier: CustomTouchBarItem.createIdentifier("Weather.updatecheck").rawValue)
self.activity.interval = try container.decodeIfPresent(Double.self, forKey: .refreshInterval) ?? 1800.0
self.units = try container.decodeIfPresent(String.self, forKey: .units) ?? "metric"
self.api_key = try container.decodeIfPresent(String.self, forKey: .api_key) ?? "32c4256d09a4c52b38aecddba7a078f6"
if self.units == "metric" {
units_str = "°C"
}
if self.units == "imperial" {
units_str = "°F"
}
if icon_type == "images" {
iconsSource = iconsImages
} else {
iconsSource = iconsText
}
try super.init(from: decoder)
self.setup()
}
required init?(coder _: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func setup() {
let status = CLLocationManager.authorizationStatus()
if status == .restricted || status == .denied {
print("User permission not given")
return
}
if !CLLocationManager.locationServicesEnabled() {
print("Location services not enabled")
return
}
activity.repeats = true
activity.qualityOfService = .utility
activity.schedule { (completion: NSBackgroundActivityScheduler.CompletionHandler) in
self.updateWeather()
completion(NSBackgroundActivityScheduler.Result.finished)
}
updateWeather()
manager = CLLocationManager()
manager.delegate = self
manager.desiredAccuracy = kCLLocationAccuracyHundredMeters
manager.startUpdatingLocation()
}
@objc func updateWeather() {
if location != nil {
let urlRequest = URLRequest(url: URL(string: "https://api.openweathermap.org/data/2.5/weather?lat=\(location.coordinate.latitude)&lon=\(location.coordinate.longitude)&units=\(units)&appid=\(api_key)")!)
let task = URLSession.shared.dataTask(with: urlRequest) { data, _, error in
if error == nil {
do {
let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as! [String: AnyObject]
// print(json)
var temperature: Int!
var condition_icon = ""
if let main = json["main"] as? [String: AnyObject] {
if let temp = main["temp"] as? Double {
temperature = Int(temp)
}
}
if let weather = json["weather"] as? NSArray, let item = weather[0] as? NSDictionary {
let icon = item["icon"] as! String
if let test = self.iconsSource[icon] {
condition_icon = test
}
}
if temperature != nil {
DispatchQueue.main.async {
self.setWeather(text: "\(condition_icon) \(temperature!)\(self.units_str)")
}
}
} catch let jsonError {
print(jsonError.localizedDescription)
}
}
}
task.resume()
}
}
func setWeather(text: String) {
title = text
}
func locationManager(_: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let lastLocation = locations.last!
location = lastLocation
if prev_location == nil {
updateWeather()
}
prev_location = lastLocation
}
func locationManager(_: CLLocationManager, didFailWithError error: Error) {
print(error)
}
func locationManager(_: CLLocationManager, didChangeAuthorization _: CLAuthorizationStatus) {
// print("inside didChangeAuthorization ");
updateWeather()
}
deinit {
activity.invalidate()
}
}