mirror of
https://github.com/Toxblh/MTMR.git
synced 2026-01-11 09:28:38 +00:00
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
187 lines
6.5 KiB
Swift
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()
|
|
}
|
|
}
|