Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: new UI #5

Merged
merged 1 commit into from
Mar 2, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .swiftlint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
disabled_rules:
- identifier_name
- type_name
- cyclomatic_complexity
excluded:
- .vscode/*
113 changes: 54 additions & 59 deletions Redhill Weather.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"originHash" : "991dabb0b94544a13586e1235cf180b673bf74cdfc5351cc3c8309df8f8e398d",
"pins" : [
{
"identity" : "datehelper",
Expand All @@ -8,16 +9,7 @@
"revision" : "76d0840daab7288fc99b04a4c23d504f0394e083",
"version" : "5.0.1"
}
},
{
"identity" : "refreshablescrollview",
"kind" : "remoteSourceControl",
"location" : "https://github.com/phuhuynh2411/RefreshableScrollView",
"state" : {
"revision" : "e06edf5dc4facc7fbf71179e8a94f0d1c7035ce3",
"version" : "1.1.1"
}
}
],
"version" : 2
"version" : 3
}
55 changes: 0 additions & 55 deletions Redhill Weather/Controllers/Controller.swift

This file was deleted.

4 changes: 2 additions & 2 deletions Redhill Weather/Extensions/Date+Extension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
import Foundation

extension Date {

static func - (lhs: Date, rhs: Date) -> TimeInterval {
return lhs.timeIntervalSinceReferenceDate - rhs.timeIntervalSinceReferenceDate
}

}
6 changes: 3 additions & 3 deletions Redhill Weather/Extensions/String+Extension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,17 @@ extension String {
func index(from: Int) -> Index {
return self.index(startIndex, offsetBy: from)
}

func substring(from: Int) -> String {
let fromIndex = index(from: from)
return String(self[fromIndex...])
}

func substring(to: Int) -> String {
let toIndex = index(from: to)
return String(self[..<toIndex])
}

func substring(with r: Range<Int>) -> String {
let startIndex = index(from: r.lowerBound)
let endIndex = index(from: r.upperBound)
Expand Down
4 changes: 2 additions & 2 deletions Redhill Weather/Helpers/Helpers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ func cloudCoverage(_ cover: Int) -> String {
}
}

func decodeWeather (_ codedMetar:String) -> String {
func decodeWeather (_ codedMetar: String) -> String {
var decoded: String = ""
switch codedMetar.count {
case 5: decoded += decodeWeatherCode(codedMetar.substring(with: 0..<1)) + " "
Expand All @@ -36,7 +36,7 @@ func decodeWeather (_ codedMetar:String) -> String {
}

// The decoder of weather codes
fileprivate func decodeWeatherCode (_ code:String) -> String {
private func decodeWeatherCode (_ code: String) -> String {
switch code {
case "VC": return "In the vicinity"
case "MI": return "Shallow"
Expand Down
194 changes: 35 additions & 159 deletions Redhill Weather/Models/Model.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,178 +7,54 @@

import Foundation

// MARK: - This struct is a real mess. It is a bit of outrageous code but the starting point, ie the JSON returned by the API,

// is bad, undocumented and frankly not even nicely modelled.

struct Metar: Decodable {
var siteId: String
struct RedhillAtis: Decodable {
var site: String
var metar: String
var designator: String
var runway: String
var updatedOn: String
var isAutomatic: Bool
var isCavok: Bool
// var isAutomatic: Bool
// var isCavok: Bool
var qfe: Int
var qnh: Int
var temperature: Int
var dewPoint: Int
var visibility: Int
var clouds: [CloudCoverage]
var isWindVariable: Bool
var windSpeed: Int
var windBetweenFrom: Int
var windDirection: Int
var windBetweenTo: Int
var windSpeedGust: Int
var weather: String

struct CloudCoverage: Decodable {
var type: Int = 0
var height: Int = 0
var cover: Int = 0
}

enum OuterKeys: String, CodingKey {
case siteId
case reports
}

enum ReportsKeys: String, CodingKey {
case metarReport
}

// "Reports"."metarReport"
enum MetarReportKeys: String, CodingKey {
case auto, arrivalAtis, time, temperature, cloud, cavok, qnh, airfieldQfe, visibility, weather
}

enum VisibilityKeys: String, CodingKey {
case visibility
}

enum TemperatureKeys: String, CodingKey {
case temperature, dewPoint
}

enum WeatherKeys: String, CodingKey {
case fullReportString
}

enum CloudKeys: String, CodingKey {
case cloudLayer1, cloudLayer2, cloudLayer3
}

// "Reports"."metarReport"."temperature"
enum MetarKeys: String, CodingKey {
case cloud
}

enum ArrivalAtisKeys: String, CodingKey {
case codeLetter, runway, metReportString, wind
}

enum WindKeys: String, CodingKey {
case wind2Min
}

enum RecentWindContainer: String, CodingKey {
case isVrb, averageWindSpeed, averageWindDirection, minimumWindDirection, maximumWindDirection, maximumWindSpeed
}

init(from decoder: Decoder) throws {
let outerContainer = try decoder.container(keyedBy: OuterKeys.self)
let reportsContainer = try outerContainer.nestedContainer(keyedBy: ReportsKeys.self, forKey: .reports)
self.siteId = try outerContainer.decode(String.self, forKey: .siteId)

// METAR information
let metarContainer = try reportsContainer.nestedContainer(keyedBy: MetarReportKeys.self, forKey: .metarReport)
self.updatedOn = try metarContainer.decode(String.self, forKey: .time)
self.isCavok = try metarContainer.decode(Bool.self, forKey: .cavok)
self.isAutomatic = try metarContainer.decode(Bool.self, forKey: .auto)
self.qnh = try metarContainer.decode(Int.self, forKey: .qnh)
self.qfe = try metarContainer.decode(Int.self, forKey: .airfieldQfe)

// Arrival ATIS
let arrivalAtisContainer = try metarContainer.nestedContainer(keyedBy: ArrivalAtisKeys.self, forKey: .arrivalAtis)
self.metar = try arrivalAtisContainer.decode(String.self, forKey: .metReportString)
self.designator = try arrivalAtisContainer.decode(String.self, forKey: .codeLetter)
self.runway = try arrivalAtisContainer.decode(String.self, forKey: .runway)

// Temperature
let temperatureContainer = try metarContainer.nestedContainer(keyedBy: TemperatureKeys.self, forKey: .temperature)
self.temperature = try temperatureContainer.decode(Int.self, forKey: .temperature)
self.dewPoint = try temperatureContainer.decode(Int.self, forKey: .dewPoint)

// Visibility - This is returned nil when CAVOK
if self.isCavok == false {
let visibilityContainer = try metarContainer.nestedContainer(keyedBy: VisibilityKeys.self, forKey: .visibility)
self.visibility = try visibilityContainer.decode(Int.self, forKey: .visibility)
} else { self.visibility = 9999 }
// var temperature: Int
// var dewPoint: Int
// var visibility: Int
// var clouds: [CloudCoverage]
// var isWindVariable: Bool
// var windSpeed: Int
// var windBetweenFrom: Int
// var windDirection: Int
// var windBetweenTo: Int
// var windSpeedGust: Int
// var weather: String
//
// struct CloudCoverage: Decodable {
// var type: Int = 0
// var height: Int = 0
// var cover: Int = 0
// }

// Weather
let weatherContainer = try metarContainer.nestedContainer(keyedBy: WeatherKeys.self, forKey: .weather)
self.weather = try weatherContainer.decode(String.self, forKey: .fullReportString)

// Clouds
let cloudContainer = try metarContainer.nestedContainer(keyedBy: CloudKeys.self, forKey: .cloud)
self.clouds = [CloudCoverage]()

if let cloud1 = try? cloudContainer.decode(CloudCoverage.self, forKey: .cloudLayer1) {
self.clouds.append(cloud1)
}

if let cloud2 = try? cloudContainer.decode(CloudCoverage.self, forKey: .cloudLayer2) {
self.clouds.append(cloud2)
}

if let cloud3 = try? cloudContainer.decode(CloudCoverage.self, forKey: .cloudLayer3) {
self.clouds.append(cloud3)
}

// Wind
let windContainer = try arrivalAtisContainer.nestedContainer(keyedBy: WindKeys.self, forKey: .wind)
let recentWindContainer = try windContainer.nestedContainer(keyedBy: RecentWindContainer.self, forKey: .wind2Min)
self.windSpeed = try recentWindContainer.decode(Int.self, forKey: .averageWindSpeed)
self.isWindVariable = try recentWindContainer.decode(Bool.self, forKey: .isVrb)

if let windFrom = try? recentWindContainer.decode(Int.self, forKey: .minimumWindDirection) {
self.windBetweenFrom = windFrom
} else
{ self.windBetweenFrom = 0 }

if let windTo = try? recentWindContainer.decode(Int.self, forKey: .minimumWindDirection) {
self.windBetweenTo = windTo
} else
{ self.windBetweenTo = 0 }

self.windSpeedGust = try recentWindContainer.decode(Int.self, forKey: .maximumWindSpeed)
if let windDirection = try? recentWindContainer.decode(Int.self, forKey: .averageWindDirection) {
self.windDirection = windDirection
} else
{ self.windDirection = 0 }
}

init() {
self.siteId = ""
self.site = ""
self.metar = ""
self.designator = ""
self.runway = ""
self.updatedOn = ""
self.isAutomatic = true
self.isCavok = true
// self.isAutomatic = true
// self.isCavok = true
self.qfe = 0
self.qnh = 0
self.temperature = 0
self.dewPoint = 0
self.visibility = 0
self.clouds = []
self.isWindVariable = false
self.windSpeed = 0
self.windDirection = 0
self.windBetweenFrom = 0
self.windBetweenTo = 0
self.windSpeedGust = 0
self.weather = ""
// self.temperature = 0
// self.dewPoint = 0
// self.visibility = 0
// self.clouds = []
// self.isWindVariable = false
// self.windSpeed = 0
// self.windDirection = 0
// self.windBetweenFrom = 0
// self.windBetweenTo = 0
// self.windSpeedGust = 0
// self.weather = ""
}
}
12 changes: 6 additions & 6 deletions Redhill Weather/Redhill_WeatherApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import SwiftUI

@main
struct Redhill_WeatherApp: App {
struct RedhillWeatherApp: App {
var body: some Scene {
WindowGroup {
MainView()
Expand All @@ -19,14 +19,14 @@ struct Redhill_WeatherApp: App {
struct MainView: View {
var body: some View {
TabView {
ContentView()
AtisView()
.tabItem {
Label("Weather", systemImage: "cloud.sun.rain.fill")
Label("ATIS", systemImage: "cloud.sun.rain.fill")
}
InfoView()

SettingsView()
.tabItem {
Label("Info", systemImage: "info.circle.fill")
Label("Settings", systemImage: "gearshape.fill")
}
}
}
Expand Down
Loading