Commit 4758da0a by Demid Merzlyakov

WdtLocation added. A bunch of stuff from the main project.

parent e6583de2
...@@ -8,6 +8,10 @@ ...@@ -8,6 +8,10 @@
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
34EAFD887EF2D1D7449A016C /* Pods_1Weather.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6B543196B99BA697763514F6 /* Pods_1Weather.framework */; }; 34EAFD887EF2D1D7449A016C /* Pods_1Weather.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6B543196B99BA697763514F6 /* Pods_1Weather.framework */; };
8708801C2578DDD50076BFB1 /* WdtLocation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8708801B2578DDD50076BFB1 /* WdtLocation.swift */; };
870880212578ED190076BFB1 /* WdtDaySummary.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8708801E2578ED190076BFB1 /* WdtDaySummary.swift */; };
870880222578ED190076BFB1 /* WdtHourSummary.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8708801F2578ED190076BFB1 /* WdtHourSummary.swift */; };
870880232578ED190076BFB1 /* WdtCondition.swift in Sources */ = {isa = PBXBuildFile; fileRef = 870880202578ED190076BFB1 /* WdtCondition.swift */; };
CD1237C3255D5C5900C98139 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD1237C2255D5C5900C98139 /* AppDelegate.swift */; }; CD1237C3255D5C5900C98139 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD1237C2255D5C5900C98139 /* AppDelegate.swift */; };
CD1237C7255D5C5900C98139 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD1237C6255D5C5900C98139 /* ViewController.swift */; }; CD1237C7255D5C5900C98139 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD1237C6255D5C5900C98139 /* ViewController.swift */; };
CD1237CC255D5C5C00C98139 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = CD1237CB255D5C5C00C98139 /* Assets.xcassets */; }; CD1237CC255D5C5C00C98139 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = CD1237CB255D5C5C00C98139 /* Assets.xcassets */; };
...@@ -32,6 +36,10 @@ ...@@ -32,6 +36,10 @@
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
6B543196B99BA697763514F6 /* Pods_1Weather.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_1Weather.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 6B543196B99BA697763514F6 /* Pods_1Weather.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_1Weather.framework; sourceTree = BUILT_PRODUCTS_DIR; };
8708801B2578DDD50076BFB1 /* WdtLocation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WdtLocation.swift; sourceTree = "<group>"; };
8708801E2578ED190076BFB1 /* WdtDaySummary.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WdtDaySummary.swift; sourceTree = "<group>"; };
8708801F2578ED190076BFB1 /* WdtHourSummary.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WdtHourSummary.swift; sourceTree = "<group>"; };
870880202578ED190076BFB1 /* WdtCondition.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WdtCondition.swift; sourceTree = "<group>"; };
C8C576F6184B547435CFF0F3 /* Pods-1Weather.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-1Weather.debug.xcconfig"; path = "Target Support Files/Pods-1Weather/Pods-1Weather.debug.xcconfig"; sourceTree = "<group>"; }; C8C576F6184B547435CFF0F3 /* Pods-1Weather.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-1Weather.debug.xcconfig"; path = "Target Support Files/Pods-1Weather/Pods-1Weather.debug.xcconfig"; sourceTree = "<group>"; };
CD1237BF255D5C5900C98139 /* 1Weather.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = 1Weather.app; sourceTree = BUILT_PRODUCTS_DIR; }; CD1237BF255D5C5900C98139 /* 1Weather.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = 1Weather.app; sourceTree = BUILT_PRODUCTS_DIR; };
CD1237C2255D5C5900C98139 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; }; CD1237C2255D5C5900C98139 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
...@@ -169,6 +177,10 @@ ...@@ -169,6 +177,10 @@
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
CDA69B2F257500E200CB6409 /* GeoNamesPlace.swift */, CDA69B2F257500E200CB6409 /* GeoNamesPlace.swift */,
8708801B2578DDD50076BFB1 /* WdtLocation.swift */,
870880202578ED190076BFB1 /* WdtCondition.swift */,
8708801E2578ED190076BFB1 /* WdtDaySummary.swift */,
8708801F2578ED190076BFB1 /* WdtHourSummary.swift */,
); );
path = Models; path = Models;
sourceTree = "<group>"; sourceTree = "<group>";
...@@ -349,14 +361,18 @@ ...@@ -349,14 +361,18 @@
CDD0F1DF2572403E00CF5017 /* LocationViewController.swift in Sources */, CDD0F1DF2572403E00CF5017 /* LocationViewController.swift in Sources */,
CDCC480E255EA8D2003EA8A7 /* CurrentForecastDetailsCell.swift in Sources */, CDCC480E255EA8D2003EA8A7 /* CurrentForecastDetailsCell.swift in Sources */,
CDA69B30257500E200CB6409 /* GeoNamesPlace.swift in Sources */, CDA69B30257500E200CB6409 /* GeoNamesPlace.swift in Sources */,
870880232578ED190076BFB1 /* WdtCondition.swift in Sources */,
CD1237C7255D5C5900C98139 /* ViewController.swift in Sources */, CD1237C7255D5C5900C98139 /* ViewController.swift in Sources */,
CD1237F1255D83C500C98139 /* UIColor+Hex.swift in Sources */, CD1237F1255D83C500C98139 /* UIColor+Hex.swift in Sources */,
870880212578ED190076BFB1 /* WdtDaySummary.swift in Sources */,
8708801C2578DDD50076BFB1 /* WdtLocation.swift in Sources */,
CDD0F1EE25725BCF00CF5017 /* ThemeManager.swift in Sources */, CDD0F1EE25725BCF00CF5017 /* ThemeManager.swift in Sources */,
CD1237F4255D889F00C98139 /* GradientView.swift in Sources */, CD1237F4255D889F00C98139 /* GradientView.swift in Sources */,
CD1237C3255D5C5900C98139 /* AppDelegate.swift in Sources */, CD1237C3255D5C5900C98139 /* AppDelegate.swift in Sources */,
CD6B304325726AD1004B34B3 /* DefaultTheme.swift in Sources */, CD6B304325726AD1004B34B3 /* DefaultTheme.swift in Sources */,
CD6B3036257262C2004B34B3 /* UIColor+Highlight.swift in Sources */, CD6B3036257262C2004B34B3 /* UIColor+Highlight.swift in Sources */,
CDA69B3325750D3400CB6409 /* LocationsViewModel.swift in Sources */, CDA69B3325750D3400CB6409 /* LocationsViewModel.swift in Sources */,
870880222578ED190076BFB1 /* WdtHourSummary.swift in Sources */,
CD6B303E25726960004B34B3 /* ThemeProtocol.swift in Sources */, CD6B303E25726960004B34B3 /* ThemeProtocol.swift in Sources */,
CD6B303B2572680C004B34B3 /* SelfSizingButton.swift in Sources */, CD6B303B2572680C004B34B3 /* SelfSizingButton.swift in Sources */,
CDA69B2C2574F3C800CB6409 /* CityCell.swift in Sources */, CDA69B2C2574F3C800CB6409 /* CityCell.swift in Sources */,
......
...@@ -12,6 +12,33 @@ import Foundation ...@@ -12,6 +12,33 @@ import Foundation
let kAlgoliaAppId: String = "plSP1L2N5P5J" let kAlgoliaAppId: String = "plSP1L2N5P5J"
let kAlgoliaAPIKey: String = "c211961220dc98074f14bc7ac1281cdd" let kAlgoliaAPIKey: String = "c211961220dc98074f14bc7ac1281cdd"
let DEGREES = "\u{00B0}"
let INCHES = "\u{2033}"
let PRESSURE_FALLING = "\u{25BC}"
let PRESSURE_RISING = "\u{25B2}"
let MILLIMETERS = "mm"
let BLANK = "--"
let UP_ARROW = "\u{2191}"
let DOWN_ARROW = "\u{2193}"
func windUnits() -> WindUnits {
return .mps
}
func pressureUnits() -> PressureUnits {
return .mmhg
}
func distanceUnits() -> DistanceUnits {
return .kilometers
}
enum DistanceUnits: Int {
case miles, kilometers
static let desc = ["Miles (mi)".localized, "Kilometers (km)".localized]
}
extension String { extension String {
func localized(comment: String? = nil) -> String { func localized(comment: String? = nil) -> String {
return NSLocalizedString(self, comment: comment ?? self) return NSLocalizedString(self, comment: comment ?? self)
...@@ -19,4 +46,274 @@ extension String { ...@@ -19,4 +46,274 @@ extension String {
var localized: String { var localized: String {
return NSLocalizedString(self, comment: self) return NSLocalizedString(self, comment: self)
} }
func trim() -> String {
return self.trimmingCharacters(in: CharacterSet.whitespaces)
}
func trimSpaceNewlines() -> String {
return self.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)
}
func trim(_ characters: String) -> String {
return self.trimmingCharacters(in: CharacterSet(charactersIn: characters))
}
}
func isMetric() -> Bool {
return true
}
extension Double {
func roundTo(_ numberOfPlaces: Int) -> Double {
let divisor = pow(10.0, Double(numberOfPlaces))
return (self * divisor).rounded() / divisor
}
}
public extension Date {
init(dateString: String) {
let dateStringFormatter = DateFormatter()
dateStringFormatter.locale = NSLocale(localeIdentifier: "en_US") as Locale
dateStringFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
// dateStringFormatter.timeZone = NSTimeZone(name: "GMT")
if let date = dateStringFormatter.date(from: dateString) {
self.init(timeInterval: 0, since: date)
} else {
self.init()
}
}
init(utcDateString: String) {
let dateStringFormatter = DateFormatter()
dateStringFormatter.locale = NSLocale(localeIdentifier: "en_US") as Locale
dateStringFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
dateStringFormatter.timeZone = TimeZone(abbreviation: "UTC")
if let date = dateStringFormatter.date(from: utcDateString) {
self.init(timeInterval: 0, since: date)
} else {
self.init()
}
}
init(dateString: String, format: String) {
let dateStringFormatter = DateFormatter()
dateStringFormatter.locale = NSLocale(localeIdentifier: "en_US") as Locale
// dateStringFormatter.timeZone = NSTimeZone(name: "GMT")
dateStringFormatter.dateFormat = format
dateStringFormatter.isLenient = true
if let date = dateStringFormatter.date(from: dateString) {
self.init(timeInterval: 0, since: date)
} else {
self.init()
}
}
func getDayPart() -> String {
let dateFormatter = DateFormatter()
let localeFormatString = DateFormatter.dateFormat(fromTemplate: "MMM dd", options: 0, locale: dateFormatter.locale)
dateFormatter.dateFormat = localeFormatString
let str = dateFormatter.string(from: self)
return str
// formatter.dateStyle = .ShortStyle
// formatter.dateFormat = "MMM dd"
// return formatter.stringFromDate(self)
}
func getTimePart() -> String {
let dateFormatter = DateFormatter()
let localeFormatString = DateFormatter.dateFormat(fromTemplate: "j:m a", options: 0, locale: dateFormatter.locale)
dateFormatter.dateFormat = localeFormatString
var str = dateFormatter.string(from: self)
if str.hasSuffix("AM") || str.hasSuffix("PM") {
// this is a kludge to return 10 PM instead of 10:00 PM which above gives.
// non-US format (23 hour) above returns 22:00
let localeFormatString = DateFormatter.dateFormat(fromTemplate: "j a", options: 0, locale: dateFormatter.locale)
dateFormatter.dateFormat = localeFormatString
str = dateFormatter.string(from: self)
}
return str
}
func getTimePartFull() -> String {
let dateFormatter = DateFormatter()
let localeFormatString = DateFormatter.dateFormat(fromTemplate: "j:m a", options: 0, locale: dateFormatter.locale)
dateFormatter.dateFormat = localeFormatString
let str = dateFormatter.string(from: self)
return str
}
func getWithFormat(_ format: String) -> String {
let dateFormatter = DateFormatter()
let localeFormatString = DateFormatter.dateFormat(fromTemplate: format, options: 0, locale: dateFormatter.locale)
dateFormatter.dateFormat = localeFormatString
let str = dateFormatter.string(from: self)
return str
}
func getTimePart(_ timeZone: String) -> String {
let dateFormatter = DateFormatter()
dateFormatter.timeZone = TimeZone(identifier: timeZone)
let localeFormatString = DateFormatter.dateFormat(fromTemplate: "j:m a", options: 0, locale: dateFormatter.locale)
dateFormatter.dateFormat = localeFormatString
let str = dateFormatter.string(from: self)
return str
}
// Return an iso 8601 formatted date
var iso8601: String {
return Formatter.iso8601.string(from: self)
}
}
extension Formatter {
// creates a formatter that creates a string in this format
// "2017-03-22T13:22:13.933Z"
public static let iso8601: DateFormatter = {
let formatter = DateFormatter()
formatter.calendar = Calendar(identifier: .iso8601)
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.timeZone = TimeZone(secondsFromGMT: 0)
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSXXXXX"
return formatter
}()
}
enum WindUnits: Int {
case mph, kph, mps, knots, beaufort
static let desc = ["Miles per hour (mph)".localized, "Kilometers per hour (km/h)".localized, "Meters per second (m/s)".localized, "Knots (kn)".localized, "Beaufont scale".localized]
func windSpeed(_ mph: String, kph: String) -> String {
switch self {
case .mph:
return "\(mph) MPH"
case .kph:
return "\(kph) KM/H"
case .mps:
return "\(kphToMps(kph)) M/S"
case .knots:
return "\(kphToKnots(kph)) KNOTS"
case .beaufort:
return "\(mphToBeaufort(mph))"
}
}
func kphToMps(_ valueKph: String) -> String {
if let dvalue = Double(valueKph) {
return String((dvalue * 0.277778).roundTo(1))
}
return valueKph
}
func kphToKnots(_ valueKph: String) -> String {
if let dvalue = Double(valueKph) {
return String(format:"%.0f", (dvalue * 0.539957).roundTo(0))
}
return valueKph
}
func mphToBeaufort(_ valueMph: String) -> String {
if let mph = Int(valueMph) {
if mph < 1 {
return "0"
} else if mph < 3 {
return "1"
} else if mph < 7 {
return "2"
} else if mph < 11 {
return "3"
} else if mph < 18 {
return "4"
} else if mph < 24 {
return "5"
} else if mph < 31 {
return "6"
} else if mph < 38 {
return "7"
} else if mph < 46 {
return "8"
} else if mph < 54 {
return "9"
} else if mph < 63 {
return "10"
} else if mph < 74 {
return "11"
} else {
return "12"
}
}
return valueMph
}
}
enum PressureUnits: Int {
case inches, mb, mmhg, atm, kpa
static let desc = ["Inches of mercury (\")".localized, "Millibars (mb)".localized, "Millimeters of mercury (mm)".localized, "Atmosphere (atm)".localized, "Kilopascal (kPa)".localized]
func pressure(_ inches: String, mb: String, tendency: String, accessibility: Bool = false) -> String {
var tStr = ""
let t = tendency.lowercased()
if t == "falling" {
tStr = accessibility ? "falling" : PRESSURE_FALLING
} else if t == "rising" {
tStr = accessibility ? "rising" : PRESSURE_RISING
}
switch self {
case .inches:
return ("\(inches)\"\(tStr)")
case .mb:
return ("\(formatPressureMb(mb))\(tStr)MB")
case .mmhg:
return ("\(inchesMercuryToMmHg(inches))\(tStr)MMHG")
case .atm:
return ("\(inchesMercuryToAtmosphere(inches))\(tStr)ATM")
case .kpa:
return ("\(inchesMercuryToKilopascal(inches))\(tStr)KPA")
}
}
func inchesMercuryToMmHg(_ inchesMercury: String) -> String {
if let dvalue = Double(inchesMercury) {
return String(format:"%.0f", (dvalue * 25.399999705).roundTo(0))
}
return inchesMercury
}
func inchesMercuryToAtmosphere(_ inchesMercury: String) -> String {
if let dvalue = Double(inchesMercury) {
return String((dvalue / 29.9212583001).roundTo(2))
}
return inchesMercury
}
func inchesMercuryToKilopascal(_ inchesMercury: String) -> String {
if let dvalue = Double(inchesMercury) {
return String((dvalue * 3.3863886667).roundTo(2))
}
return inchesMercury
}
func formatPressureMb(_ pressureMb: String) -> String {
if let dvalue = Double(pressureMb) {
return String(format:"%.0f", dvalue.roundTo(0))
}
return pressureMb
}
} }
...@@ -19,7 +19,17 @@ class GeoNamesPlace: NSObject { ...@@ -19,7 +19,17 @@ class GeoNamesPlace: NSObject {
var countryCode : String? var countryCode : String?
var fcodeName : String? // airport if airport var fcodeName : String? // airport if airport
var toponymName : String? // airport name if fcodeName is airport var toponymName : String? // airport name if fcodeName is airport
var isMyLocation: Bool = false
init(location: WdtLocation? = nil) {
guard let location = location else { return }
city = location.city
stateCode = location.region
countryCode = location.country
country = location.countryName
latitude = location.latitude(6)
longitude = location.longitude(6)
}
func detailName() -> String { func detailName() -> String {
var sb = String() var sb = String()
...@@ -59,7 +69,7 @@ class GeoNamesPlace: NSObject { ...@@ -59,7 +69,7 @@ class GeoNamesPlace: NSObject {
sb.append(", ") sb.append(", ")
} }
if (sb.count > 0) { if (sb.count > 0) {
// sb = sb.trim() sb = sb.trim()
} }
return sb return sb
} }
......
//
// WdtCondition.swift
// OneWeather
//
// Created by Steven G Pint on 8/13/15.
// Copyright © 2015 OneLouder, Inc. All rights reserved.
//
import UIKit
class WdtCondition: NSObject, NSCoding {
let TAG = "SfcOb"
var time = ""
var weekDay = ""
var tempC = ""
var tempF = ""
var temp: String {
get {
return isMetric() ? "\(tempC)\(DEGREES)" : "\(tempF)\(DEGREES)"
}
}
var dewC = ""
var dewF = ""
var dew: String {
get {
if dewF.count > 0 {
return isMetric() ? "\(dewC)\(DEGREES)" : "\(dewF)\(DEGREES)"
}
return "NA"
}
}
var humidity = ""
var humidityPercent: String {
get {
if humidity.count > 0 {
return "\(humidity)%"
}
return "NA"
}
}
var apparentTempF = ""
var apparentTempC = ""
var apparentTemp: String {
get {
return isMetric() ? "\(apparentTempC)\(DEGREES)" : "\(apparentTempF)\(DEGREES)"
}
}
var windDir = ""
var windSpeedMph = ""
var windSpeedKph = ""
var windSpeed: String {
get {
if windSpeedMph.count == 0 {
return "NA"
}
return windUnits().windSpeed(windSpeedMph, kph: windSpeedKph)
}
}
var wind: String {
get {
if windSpeed.count == 0 {
return "NA"
}
return "\(windDir) \(windSpeed)"
}
}
var pressureIn = ""
var pressureMb = ""
var pressureTendency = ""
var pressure: String {
get {
if pressureIn.isEmpty {
return "NA"
}
return pressureUnits().pressure(pressureIn, mb: pressureMb, tendency: pressureTendency)
}
}
var pressureAccessibility: String {
get {
if pressureIn.isEmpty {
return "Not Available".localized
}
return pressureUnits().pressure(pressureIn, mb: pressureMb, tendency: pressureTendency, accessibility: true)
}
}
var weatherDesc = ""
var weatherCode = ""
var cloudCoverDesc = ""
var isDay = false // assuming day|night are options
var moonPhase = ""
var moonPhaseDesc: String {
get {
switch moonPhase {
case "New Moon":
return "New\nMoon".localized
case "Waxing Crescent Moon":
return "Waxing\nCrescent".localized
case "Quarter Moon":
return "Quarter".localized
case "Waxing Gibbous Moon":
return "Waxing\nGibbous".localized
case "Full Moon":
return "Full".localized
case "Waning Gibbous Moon":
return "Waning\nGibbous".localized
case "Last Quarter Moon":
return "Last Quarter".localized
case "Waning Crescent Moon":
return "Waning\nCrescent".localized
default:
return "Unknown"
}
}
}
var sunriseTime = ""
var sunriseTimeDesc: String {
get {
let date = Date(dateString: sunriseTime, format: "h:mm a")
return date.getTimePartFull().uppercased()
}
}
var sunsetTime = ""
var sunsetTimeDesc: String {
get {
let date = Date(dateString: sunsetTime, format: "h:mm a")
return date.getTimePartFull().uppercased()
}
}
var precipHourIn = ""
var precipHourMm = ""
var precipHour: String {
get {
if precipHourIn == "0" || precipHourIn.count == 0 {
return ""
}
return isMetric() ? "\(precipHourMm)\(MILLIMETERS)" : "\(precipHourIn)\(INCHES)"
}
}
var precipDayIn = ""
var precipDayMm = ""
var precipDay: String {
get {
if precipDayIn == "0" || precipDayIn.count == 0 {
return ""
}
return isMetric() ? "\(precipDayMm)\(MILLIMETERS)" : "\(precipDayIn)\(INCHES)"
}
}
var visibilityFt = ""
var visibility: String {
get {
if visibilityFt.count > 0 && visibilityFt.lowercased() != "nan" {
let num: Double = distanceUnits() == DistanceUnits.kilometers ? 1000 : 5280
let desc = distanceUnits() == DistanceUnits.kilometers ? "KM" : "MI"
if let dvalue = Double(visibilityFt) {
let str = String(format:"%.0f", (dvalue / num).roundTo(0))
return "\(str) \(desc)"
}
}
return "NA"
}
}
override init() {
super.init()
}
// MARK: NSCoding
required init(coder decoder: NSCoder) {
// let version = decoder.decodeIntForKey("version")
time = decoder.decodeObject(forKey: "time") as! String
weekDay = decoder.decodeObject(forKey: "weekDay") as! String
tempC = decoder.decodeObject(forKey: "tempC") as! String
tempF = decoder.decodeObject(forKey: "tempF") as! String
dewC = decoder.decodeObject(forKey: "dewC") as! String
dewF = decoder.decodeObject(forKey: "dewF") as! String
humidity = decoder.decodeObject(forKey: "humidity") as! String
apparentTempF = decoder.decodeObject(forKey: "apparentTempF") as! String
apparentTempC = decoder.decodeObject(forKey: "apparentTempC") as! String
windDir = decoder.decodeObject(forKey: "windDir") as! String
windSpeedMph = decoder.decodeObject(forKey: "windSpeedMph") as! String
windSpeedKph = decoder.decodeObject(forKey: "windSpeedKph") as! String
pressureIn = decoder.decodeObject(forKey: "pressureIn") as! String
pressureMb = decoder.decodeObject(forKey: "pressureMb") as! String
pressureTendency = decoder.decodeObject(forKey: "pressureTendency") as! String
weatherDesc = decoder.decodeObject(forKey: "weatherDesc") as! String
weatherCode = decoder.decodeObject(forKey: "weatherCode") as! String
cloudCoverDesc = decoder.decodeObject(forKey: "cloudCoverDesc") as! String
isDay = decoder.decodeBool(forKey: "isDay")
moonPhase = decoder.decodeObject(forKey: "moonPhase") as! String
sunriseTime = decoder.decodeObject(forKey: "sunriseTime") as! String
sunsetTime = decoder.decodeObject(forKey: "sunsetTime") as! String
precipHourIn = decoder.decodeObject(forKey: "precipHourIn") as! String
precipHourMm = decoder.decodeObject(forKey: "precipHourMm") as! String
precipDayIn = decoder.decodeObject(forKey: "precipDayIn") as! String
precipDayMm = decoder.decodeObject(forKey: "precipDayMm") as! String
visibilityFt = decoder.decodeObject(forKey: "visibilityFt") as! String
}
func encode(with coder: NSCoder) {
coder.encodeCInt(1, forKey: "version")
coder.encode(self.time, forKey: "time")
coder.encode(self.weekDay, forKey: "weekDay")
coder.encode(self.tempC, forKey: "tempC")
coder.encode(self.tempF, forKey: "tempF")
coder.encode(self.dewC, forKey: "dewC")
coder.encode(self.dewF, forKey: "dewF")
coder.encode(self.humidity, forKey: "humidity")
coder.encode(self.apparentTempF, forKey: "apparentTempF")
coder.encode(self.apparentTempC, forKey: "apparentTempC")
coder.encode(self.windDir, forKey: "windDir")
coder.encode(self.windSpeedMph, forKey: "windSpeedMph")
coder.encode(self.windSpeedKph, forKey: "windSpeedKph")
coder.encode(self.pressureIn, forKey: "pressureIn")
coder.encode(self.pressureMb, forKey: "pressureMb")
coder.encode(self.pressureTendency, forKey: "pressureTendency")
coder.encode(self.weatherDesc, forKey: "weatherDesc")
coder.encode(self.weatherCode, forKey: "weatherCode")
coder.encode(self.cloudCoverDesc, forKey: "cloudCoverDesc")
coder.encode(self.isDay, forKey: "isDay")
coder.encode(self.moonPhase, forKey: "moonPhase")
coder.encode(self.sunriseTime, forKey: "sunriseTime")
coder.encode(self.sunsetTime, forKey: "sunsetTime")
coder.encode(self.precipHourIn, forKey: "precipHourIn")
coder.encode(self.precipHourMm, forKey: "precipHourMm")
coder.encode(self.precipDayIn, forKey: "precipDayIn")
coder.encode(self.precipDayMm, forKey: "precipDayMm")
coder.encode(self.visibilityFt, forKey: "visibilityFt")
}
}
//
// WdtDaySummary.swift
// OneWeather
//
// Created by Steven G Pint on 8/12/15.
// Copyright © 2015 OneLouder, Inc. All rights reserved.
//
import UIKit
class WdtDaySummary: NSObject, NSCoding {
var dayOfWeek = ""
var dayOfWeekShort: String {
get {
if self.dayOfWeek.count >= 3 {
return String(dayOfWeek[dayOfWeek.startIndex ..< dayOfWeek.index(dayOfWeek.startIndex, offsetBy: 3)])
} else {
return "NA"
}
}
}
var maxTempF = ""
var maxTempC = ""
var maxTemp: String {
get {
return isMetric() ? "\(maxTempC)\(DEGREES)" : "\(maxTempF)\(DEGREES)"
}
}
var maxTempNum: Double {
get {
if let val = isMetric() ? Double(maxTempC) : Double(maxTempF) {
return val
}
return 0.0
}
}
var isMaxFreezing: Bool {
get {
if isMetric() {
if let f = Int(maxTempC) {
return f <= 0
}
} else {
if let f = Int(maxTempF) {
return f <= 32
}
}
return false
}
}
var minTempF = ""
var minTempC = ""
var minTemp: String {
get {
return isMetric() ? "\(minTempC)\(DEGREES)" : "\(minTempF)\(DEGREES)"
}
}
var minTempNum: Double {
get {
if let val = isMetric() ? Double(minTempC) : Double(minTempF) {
return val
}
return 0.0
}
}
var tempRange: String {
get {
return "\(maxTemp) / \(minTemp)"
}
}
var tempRangeAccessibility: String {
get {
return "High \(maxTemp), Low \(minTemp)"
}
}
var windSpeedMph = ""
var windSpeedKph = ""
var windSpeed: String {
get {
return windUnits().windSpeed(windSpeedMph, kph: windSpeedKph)
}
}
var windDir = ""
var wind: String {
get {
return "\(windDir) \(windSpeed)"
}
}
var precip = ""
var precipPercent: String {
get {
if precip == "0" {
return ""
}
return "\(precip)%"
}
}
var precipPercentNotEmpty: String {
get {
return "\(precip)%"
}
}
var precipDouble: Double? {
get {
return Double(precip)
}
}
var weatherDesc = ""
var weatherCode = ""
var textDescription = ""
var sunriseTime = ""
var sunsetTime = ""
var summaryDate = ""
var monthDayPart: String {
get {
if self.summaryDate.count > 0 {
return Date(dateString: summaryDate, format: "MM/dd/yyyy").getDayPart().uppercased()
} else {
return ""
}
}
}
var dayPart: String {
get {
if self.summaryDate.count > 0 {
return Date(dateString: summaryDate, format: "MM/dd/yyyy").getWithFormat("dd")
} else {
return ""
}
}
}
var dayDatePart: String {
get {
if self.summaryDate.count > 0 {
return Date(dateString: summaryDate, format: "MM/dd/yyyy").getWithFormat("eeee, MMMM dd").uppercased()
} else {
return ""
}
}
}
var windGustMph = ""
var windGustKph = ""
var windGust: String {
get {
return windUnits().windSpeed(windGustMph, kph: windGustKph)
}
}
var moonPhase = ""
var moonPhaseDesc: String {
get {
switch moonPhase {
case "New Moon":
return "New\nMoon".localized
case "Waxing Crescent Moon":
return "Waxing\nCrescent".localized
case "Quarter Moon":
return "Quarter".localized
case "Waxing Gibbous Moon":
return "Waxing\nGibbous".localized
case "Full Moon":
return "Full".localized
case "Waning Gibbous Moon":
return "Waning\nGibbous".localized
case "Last Quarter Moon":
return "Last Quarter".localized
case "Waning Crescent Moon":
return "Waning\nCrescent".localized
default:
return "Unknown"
}
}
}
var morningWeather = ""
var morningPop = ""
var morningPrecipPercent: String {
get {
return "\(morningPop)%"
}
}
var morningTempF = ""
var morningTempC = ""
var morningTemp: String {
get {
return isMetric() ? "\(morningTempC)\(DEGREES)" : "\(morningTempF)\(DEGREES)"
}
}
var nightWeather = ""
var nightPop = ""
var nightPrecipPercent: String {
get {
return "\(nightPop)%"
}
}
var nightTempF = ""
var nightTempC = ""
var nightTemp: String {
get {
return isMetric() ? "\(nightTempC)\(DEGREES)" : "\(nightTempF)\(DEGREES)"
}
}
// added in version 2
var sunriseUtc: Date?
var sunsetUtc: Date?
var sunState: String?
var sunStateDesc: String {
get {
switch sunState ?? "" {
case "always_up":
return "Sun is always up".localized
case "never_up":
return "Sun is never up".localized
default:
return ""
}
}
}
var moonriseUtc: Date?
var moonsetUtc: Date?
var moonState: String?
var moonStateDesc: String {
get {
switch moonState ?? "" {
case "always_up":
return "Moon is always up".localized
case "never_up":
return "Moon is never up".localized
default:
return ""
}
}
}
var date : Date? // not persisted
override init() {
super.init()
}
// MARK: NSCoding
required init(coder decoder: NSCoder) {
let version = decoder.decodeCInt(forKey: "version")
dayOfWeek = decoder.decodeObject(forKey: "dayOfWeek") as! String
maxTempF = decoder.decodeObject(forKey: "maxTempF") as! String
maxTempC = decoder.decodeObject(forKey: "maxTempC") as! String
minTempF = decoder.decodeObject(forKey: "minTempF") as! String
minTempC = decoder.decodeObject(forKey: "minTempC") as! String
windSpeedMph = decoder.decodeObject(forKey: "windSpeedMph") as! String
windSpeedKph = decoder.decodeObject(forKey: "windSpeedKph") as! String
windDir = decoder.decodeObject(forKey: "windDir") as! String
precip = decoder.decodeObject(forKey: "precip") as! String
weatherDesc = decoder.decodeObject(forKey: "weatherDesc") as! String
weatherCode = decoder.decodeObject(forKey: "weatherCode") as! String
textDescription = decoder.decodeObject(forKey: "textDescription") as! String
sunriseTime = decoder.decodeObject(forKey: "sunriseTime") as! String
sunsetTime = decoder.decodeObject(forKey: "sunsetTime") as! String
summaryDate = decoder.decodeObject(forKey: "summaryDate") as! String
windGustMph = decoder.decodeObject(forKey: "windGustMph") as! String
windGustKph = decoder.decodeObject(forKey: "windGustKph") as! String
moonPhase = decoder.decodeObject(forKey: "moonPhase") as! String
morningWeather = decoder.decodeObject(forKey: "morningWeather") as! String
morningPop = decoder.decodeObject(forKey: "morningPop") as! String
morningTempF = decoder.decodeObject(forKey: "morningTempF") as! String
morningTempC = decoder.decodeObject(forKey: "morningTempC") as! String
nightWeather = decoder.decodeObject(forKey: "nightWeather") as! String
nightPop = decoder.decodeObject(forKey: "nightPop") as! String
morningPop = decoder.decodeObject(forKey: "morningPop") as! String
nightTempF = decoder.decodeObject(forKey: "nightTempF") as! String
nightTempC = decoder.decodeObject(forKey: "nightTempC") as! String
if version >= 2 {
sunriseUtc = decoder.decodeObject(forKey: "sunriseUtc") as? Date
sunsetUtc = decoder.decodeObject(forKey: "sunsetUtc") as? Date
sunState = decoder.decodeObject(forKey: "sunState") as? String
moonriseUtc = decoder.decodeObject(forKey: "moonriseUtc") as? Date
moonsetUtc = decoder.decodeObject(forKey: "moonsetUtc") as? Date
moonState = decoder.decodeObject(forKey: "moonState") as? String
}
}
func encode(with coder: NSCoder) {
coder.encodeCInt(2, forKey: "version") // changed to version 2 for moonrise values
coder.encode(self.dayOfWeek, forKey: "dayOfWeek")
coder.encode(self.maxTempF, forKey: "maxTempF")
coder.encode(self.maxTempC, forKey: "maxTempC")
coder.encode(self.minTempF, forKey: "minTempF")
coder.encode(self.minTempC, forKey: "minTempC")
coder.encode(self.windSpeedMph, forKey: "windSpeedMph")
coder.encode(self.windSpeedKph, forKey: "windSpeedKph")
coder.encode(self.windDir, forKey: "windDir")
coder.encode(self.precip, forKey: "precip")
coder.encode(self.weatherDesc, forKey: "weatherDesc")
coder.encode(self.weatherCode, forKey: "weatherCode")
coder.encode(self.textDescription, forKey: "textDescription")
coder.encode(self.sunriseTime, forKey: "sunriseTime")
coder.encode(self.sunsetTime, forKey: "sunsetTime")
coder.encode(self.summaryDate, forKey: "summaryDate")
coder.encode(self.windGustMph, forKey: "windGustMph")
coder.encode(self.windGustKph, forKey: "windGustKph")
coder.encode(self.moonPhase, forKey: "moonPhase")
coder.encode(self.morningWeather, forKey: "morningWeather")
coder.encode(self.morningPop, forKey: "morningPop")
coder.encode(self.morningTempF, forKey: "morningTempF")
coder.encode(self.morningTempC, forKey: "morningTempC")
coder.encode(self.nightWeather, forKey: "nightWeather")
coder.encode(self.nightPop, forKey: "nightPop")
coder.encode(self.nightTempF, forKey: "nightTempF")
coder.encode(self.nightTempC, forKey: "nightTempC")
coder.encode(sunriseUtc, forKey: "sunriseUtc")
coder.encode(sunsetUtc, forKey: "sunsetUtc")
coder.encode(sunState, forKey: "sunState")
coder.encode(moonriseUtc, forKey: "moonriseUtc")
coder.encode(moonsetUtc, forKey: "moonsetUtc")
coder.encode(moonState, forKey: "moonState")
}
}
//
// WdtHourSummary.swift
// OneWeather
//
// Created by Steven G Pint on 8/13/15.
// Copyright © 2015 OneLouder, Inc. All rights reserved.
//
import UIKit
enum DayPhase: Int {
case morn, noon, eve, night
var description: String {
switch self {
case .morn:
return "MORN".localized
case .noon:
return "NOON".localized
case .eve:
return "EVE".localized
case .night:
return "NIGHT".localized
}
}
var accessibilityDescription: String {
switch self {
case .morn:
return "Morning"
case .noon:
return "Noon"
case .eve:
return "Evening"
case .night:
return "Night"
}
}
static let daySegments = [7, 12, 18, 23]
}
class WdtHourSummary: NSObject, NSCoding {
let TAG = "WdtHourSummary"
var day = ""
var time = ""
// var time = "" {
// didSet(value) {
// if value.length > 0 {
// _date = NSDate(dateString: value)
// time = value
// }
// }
// }
fileprivate var _date: Date?
var date: Date {
get {
if _date == nil {
_date = Date(dateString: self.time)
}
return _date!
}
}
var hour: Int {
get {
return Calendar.current.component(.hour, from: date)
}
}
var dayPhase: DayPhase = .morn
var dayPart: String {
get {
if self.time.count > 0 {
return date.getDayPart().uppercased()
} else {
return "NA"
}
}
}
var timePart: String {
get {
if self.time.count > 0 {
return date.getTimePart()
} else {
return "NA"
}
}
}
var tempC = ""
var tempF = ""
var temp: String {
get {
return isMetric() ? "\(tempC)\(DEGREES)" : "\(tempF)\(DEGREES)"
}
}
var tempNum: Double {
get {
return (isMetric() ? Double(tempC) : Double(tempF))!
}
}
var isFreezing: Bool {
get {
if isMetric() {
if let f = Int(tempC) {
return f <= 0
}
} else {
if let f = Int(tempF) {
return f <= 32
}
}
return false
}
}
var dewPointC = ""
var dewPointF = ""
var apparentTempC = ""
var apparentTempF = ""
var apparentTemp: String {
get {
return isMetric() ? apparentTempC : apparentTempF
}
}
var tempFeels: String {
get {
return "\(temp) Feels \(apparentTemp)" // degree symbol
}
}
var humidityPercent = ""
var pressureIn = ""
var pressureMb = ""
var weatherDesc = ""
var weatherCode = ""
var precip = ""
var precipPercent: String {
get {
return "\(precip)%"
}
}
var precipDouble: Double? {
get {
return Double(precip)
}
}
var windDir = ""
var windSpeedKph = ""
var windSpeedMph = ""
var windSpeed: String {
get {
return windUnits().windSpeed(windSpeedMph, kph: windSpeedKph)
}
}
var wind: String {
get {
return "\(windDir) \(windSpeed)"
}
}
override init() {
super.init()
}
required init(coder decoder: NSCoder) {
// let version = decoder.decodeIntForKey("version")
day = decoder.decodeObject(forKey: "day") as! String
time = decoder.decodeObject(forKey: "time") as! String
tempC = decoder.decodeObject(forKey: "tempC") as! String
tempF = decoder.decodeObject(forKey: "tempF") as! String
dewPointC = decoder.decodeObject(forKey: "dewPointC") as! String
dewPointF = decoder.decodeObject(forKey: "dewPointF") as! String
apparentTempC = decoder.decodeObject(forKey: "apparentTempC") as! String
apparentTempF = decoder.decodeObject(forKey: "apparentTempF") as! String
humidityPercent = decoder.decodeObject(forKey: "humidityPercent") as! String
pressureIn = decoder.decodeObject(forKey: "pressureIn") as! String
pressureMb = decoder.decodeObject(forKey: "pressureMb") as! String
weatherDesc = decoder.decodeObject(forKey: "weatherDesc") as! String
weatherCode = decoder.decodeObject(forKey: "weatherCode") as! String
precip = decoder.decodeObject(forKey: "precip") as! String
windDir = decoder.decodeObject(forKey: "windDir") as! String
windSpeedKph = decoder.decodeObject(forKey: "windSpeedKph") as! String
windSpeedMph = decoder.decodeObject(forKey: "windSpeedMph") as! String
}
func encode(with coder: NSCoder) {
coder.encodeCInt(1, forKey: "version")
coder.encode(self.day, forKey: "day")
coder.encode(self.time, forKey: "time")
coder.encode(self.tempC, forKey: "tempC")
coder.encode(self.tempF, forKey: "tempF")
coder.encode(self.dewPointC, forKey: "dewPointC")
coder.encode(self.dewPointF, forKey: "dewPointF")
coder.encode(self.apparentTempC, forKey: "apparentTempC")
coder.encode(self.apparentTempF, forKey: "apparentTempF")
coder.encode(self.humidityPercent, forKey: "humidityPercent")
coder.encode(self.pressureIn, forKey: "pressureIn")
coder.encode(self.pressureMb, forKey: "pressureMb")
coder.encode(self.weatherDesc, forKey: "weatherDesc")
coder.encode(self.weatherCode, forKey: "weatherCode")
coder.encode(self.precip, forKey: "precip")
coder.encode(self.windDir, forKey: "windDir")
coder.encode(self.windSpeedKph, forKey: "windSpeedKph")
coder.encode(self.windSpeedMph, forKey: "windSpeedMph")
}
var isDay: Bool {
get {
if (hour > 6 && hour < 19) {
return true
}
return false
}
}
}
//
// WdtLocation.swift
// OneWeather
//
// Created by Steven G Pint on 8/5/15.
// Copyright © 2015 OneLouder, Inc. All rights reserved.
//
import UIKit
class WdtLocation: NSObject, NSCoding {
static let LOCATION = "location"
static let CONDITIONS = "conditions"
static let DAYSUMMARIES = "daysummaries"
static let HOURSUMMARIES = "hoursummaries"
static let LONGRANGEFORECASTS = "longrangeforecasts"
static let NWSALERTS = "nwsalerts"
static let NWSDISCUSSIONS = "nwsdiscussions"
let DEFAULT_LOCATION = "default_location"
let STALE_THRESHOLD: TimeInterval = 15 * 60 // 15 minutes
let ALERT_STALE_THRESHOLD: TimeInterval = 60 // 60 seconds
let MY_LOCATION_FILE_NAME = "_default"
var city: String?
var region: String? // aka state
var country: String? // actually countryCode (i.e US)
var countryName: String? // actually country (i.e United States)
var zip: String?
fileprivate var _nickName: String?
var nickName: String?
var cityName: String {
get {
if let nickName = self.nickName, nickName.count > 0 {
return nickName
}
return city ?? ""
}
}
var cityStateName: String {
get {
if let nickName = self.nickName, nickName.count > 0 {
return nickName
}
var sb = String()
if city?.count ?? 0 > 0 {
sb.append(city!)
sb.append(", ")
}
if region?.count ?? 0 > 0 {
sb.append(region!)
sb.append(", ")
} else if country?.count ?? 0 > 0 {
if !(myLocation && isUSA) {
sb.append(country!)
sb.append(", ")
}
}
sb = sb.trim(", ")
return sb
}
}
var cityState: String
var myLocation = false
var selectedLocation = false
var geoPointLat: Double = -1
var geoPointLong: Double = -1
var lastUpdateTime: TimeInterval = 0
var lastPartialUpdateTime: TimeInterval = 0 // background updates will no longer update all data
var lastUpdateAttemptedTime: TimeInterval = 0
var lastNwsDiscussionUpdateTime: TimeInterval = 0
// Not cached, used to make sure we don't check for new alerts too often
var lastAlertUpdateTime: TimeInterval = 0
fileprivate var _currentConditions: WdtCondition?
var currentConditions: WdtCondition?
var uvIndex: String?
var uvDesc: String
var _timezone: String?
var timezone: String?
var _timezoneOffset: Double?
var timezoneOffset: String?
// NWS ALERTS
// NWS region code
var fips: String?
// private ArrayList<NwsAfdSection> afdSections
func latitude(_ maxFraction: Int = 3) -> String {
let p = pow(10.0, Double(maxFraction))
let y = Double(round(p * geoPointLat) / p)
return String(y)
}
func longitude(_ maxFraction: Int = 3) -> String {
let p = pow(10.0, Double(maxFraction))
let y = Double(round(p * geoPointLong) / p)
return String(y)
}
// add a single alert - e.g. from a push event
// base weather class data is saved in Documents directory so it doesn't get deleted by the system
/*
* for location that should follow you
*/
override init() {
cityState = ""
uvDesc = ""
detailName = ""
fullName = ""
locationId = "us"
fileName = "us"
simpleFileName = "us"
isUSA = true
super.init()
myLocation = true
}
init(zip: String?, city: String?, region: String?, countryCode: String?, country: String?, lat: String?, lng: String?) {
cityState = ""
uvDesc = ""
detailName = ""
fullName = ""
locationId = "us"
fileName = "us"
simpleFileName = "us"
isUSA = true
super.init()
self.zip = zip
self.city = city
self.region = region
self.countryName = country
if let co = countryCode {
switch co.count {
case 3 where countryCode == "USA":
self.country = "US"
default:
self.country = co
}
}
if let lat1 = lat {
setLatitude(lat1)
}
if let lng1 = lng {
setLongitude(lng1)
}
}
convenience init(place: GeoNamesPlace) {
self.init(zip: nil, city: place.city, region: place.stateCode, countryCode: place.countryCode, country: place.country, lat: place.latitude, lng: place.longitude)
}
// MARK: NSCoding
required init(coder decoder: NSCoder) {
// let version = decoder.decodeIntForKey("version")
cityState = ""
uvDesc = ""
detailName = ""
fullName = ""
locationId = ""
fileName = ""
simpleFileName = ""
isUSA = true
self.city = decoder.decodeObject(forKey: "city") as? String
self._nickName = decoder.decodeObject(forKey: "nickName") as? String
self.country = decoder.decodeObject(forKey: "country") as? String
self.countryName = decoder.decodeObject(forKey: "countryName") as? String
self.region = decoder.decodeObject(forKey: "region") as? String
self.geoPointLat = decoder.decodeDouble(forKey: "geoPointLat")
self.geoPointLong = decoder.decodeDouble(forKey: "geoPointLong")
self.lastUpdateTime = decoder.decodeDouble(forKey: "lastUpdateTime")
self.lastPartialUpdateTime = decoder.decodeDouble(forKey: "lastPartialUpdateTime")
self.lastUpdateAttemptedTime = decoder.decodeDouble(forKey: "lastUpdateAttemptedTime")
self.uvIndex = decoder.decodeObject(forKey: "uvIndex") as? String
self.myLocation = decoder.decodeBool(forKey: "myLocation")
self.selectedLocation = decoder.decodeBool(forKey: "selectedLocation")
self._timezone = decoder.decodeObject(forKey: "timezone") as? String
self._timezoneOffset = decoder.decodeDouble(forKey: "timezoneOffset")
self.fips = decoder.decodeObject(forKey: "fips") as? String
self.lastNwsDiscussionUpdateTime = decoder.decodeDouble(forKey: "lastNwsDiscussionUpdateTime")
//print("************** decode city: \(city) nickName: \(self._nickName)")
}
func encode(with coder: NSCoder) {
coder.encodeCInt(1, forKey: "version")
coder.encode(self.city, forKey: "city")
coder.encode(self._nickName, forKey: "nickName")
coder.encode(self.country, forKey: "country")
coder.encode(self.countryName, forKey: "countryName")
coder.encode(self.region, forKey: "region")
coder.encode(self.geoPointLat, forKey: "geoPointLat")
coder.encode(self.geoPointLong, forKey: "geoPointLong")
coder.encode(self.lastUpdateTime, forKey: "lastUpdateTime")
coder.encode(self.lastPartialUpdateTime, forKey: "lastPartialUpdateTime")
coder.encode(self.lastUpdateAttemptedTime, forKey: "lastUpdateAttemptedTime")
coder.encode(self.uvIndex, forKey: "uvIndex")
coder.encode(self.myLocation, forKey: "myLocation")
coder.encode(self.selectedLocation, forKey: "selectedLocation")
coder.encode(self._timezone, forKey: "timezone")
if self._timezoneOffset != nil {
coder.encode(self._timezoneOffset!, forKey: "timezoneOffset")
}
coder.encode(self.fips, forKey: "fips")
coder.encode(self.lastNwsDiscussionUpdateTime, forKey: "lastNwsDiscussionUpdateTime")
//print("*************** encode city: \(city) nickName: \(self._nickName)")
}
// Since multiple existing icon condition lookups use WDT condition codes, easiest to
// translate Weather2020 codes -> WDT
var detailName: String
var fullName: String
var isDay: Bool = false
// Calculates totale minutes of the day based on dayTimeString (i.e 07:40 am, 06:10 pm
var locationId: String
var fileName: String
var simpleFileName: String
// remove non letter/digits
func setLatitude(_ latitude: String?) {
if let l = latitude, !l.isEmpty, let value = Double(l) {
geoPointLat = value
}
}
func setLongitude(_ longitude: String?) {
if let l = longitude, !l.isEmpty, let value = Double(l) {
geoPointLong = value
}
}
override var hash: Int {
if myLocation {
return "\(geoPointLat.roundTo(2)),\(geoPointLong.roundTo(2))".hash
} else {
return fullName.hash
}
}
var isUSA: Bool
}
...@@ -72,7 +72,6 @@ class LocationsViewModel { ...@@ -72,7 +72,6 @@ class LocationsViewModel {
fakePlace.countryCode = "US" fakePlace.countryCode = "US"
fakePlace.fcodeName = "populated place" fakePlace.fcodeName = "populated place"
fakePlace.toponymName = "1WVille" fakePlace.toponymName = "1WVille"
fakePlace.isMyLocation = false
DispatchQueue.main.async { DispatchQueue.main.async {
self.cities = [] self.cities = []
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment