Skip to content

Commit 0cf7229

Browse files
Merge pull request #26 from SmartDeviceLink-Examples/update-sdl
Update SDL to the latest version, UI Changes, add widgets
2 parents 94d1c76 + 3790a71 commit 0cf7229

31 files changed

+866
-132
lines changed

MobileWeather.xcodeproj/project.pbxproj

Lines changed: 271 additions & 0 deletions
Large diffs are not rendered by default.

MobileWeather/APIKey.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
import Foundation
1010

11-
struct APIKey {
12-
static let apiKey = ""
11+
struct APIKeys {
12+
// https://home.openweathermap.org/api_keys
13+
static let openWeatherKey = ""
1314
}

MobileWeather/CurrentConditionsView.swift

Lines changed: 30 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -15,40 +15,41 @@ struct CurrentConditionsView: View {
1515
#if DEBUG
1616
let _ = Self._printChanges()
1717
#endif
18+
GroupBox {
19+
VStack(alignment: .center, spacing: 10) {
20+
HStack(alignment: .center, spacing: 10) {
21+
let iconName = OpenWeatherIcon(rawValue: currentForecast.conditionIconNames.first ?? OpenWeatherIcon.clearDay.rawValue)!
22+
WeatherImageView(openWeatherName: iconName)
23+
.frame(width: 100, height: 100)
1824

19-
VStack(alignment: .center, spacing: 10) {
20-
HStack(alignment: .center, spacing: 10) {
21-
let iconName = OpenWeatherIcon(rawValue: currentForecast.conditionIconNames.first ?? OpenWeatherIcon.clearDay.rawValue)!
22-
WeatherImageView(openWeatherName: iconName)
23-
.frame(width: 100, height: 100)
24-
25-
Spacer()
26-
27-
VStack(alignment: .trailing, spacing: 5) {
28-
Text(WeatherView.temperatureFormatter.string(from: currentForecast.temperature))
29-
.font(.title)
30-
.fontWeight(.bold)
31-
HStack {
32-
Image(systemName: "wind")
33-
Text(currentForecast.windSpeed.formatted())
34-
}
35-
HStack {
36-
Image(systemName: "sunrise")
37-
Text(currentForecast.sunriseDate.formatted(date: .omitted, time: .shortened))
38-
}
39-
HStack {
40-
Image(systemName: "sunset")
41-
Text(currentForecast.sunsetDate.formatted(date: .omitted, time: .shortened))
25+
Spacer()
26+
27+
VStack(alignment: .trailing, spacing: 5) {
28+
Text(WeatherFormatter.temperatureFormatter.string(from: currentForecast.temperature))
29+
.font(.title)
30+
.fontWeight(.bold)
31+
HStack {
32+
Image(systemName: "wind")
33+
Text(currentForecast.windSpeed.formatted())
34+
}
35+
HStack {
36+
Image(systemName: "sunrise")
37+
Text(currentForecast.sunriseDate.formatted(date: .omitted, time: .shortened))
38+
}
39+
HStack {
40+
Image(systemName: "sunset")
41+
Text(currentForecast.sunsetDate.formatted(date: .omitted, time: .shortened))
42+
}
43+
Text("UV Index: \(Int(currentForecast.uvIndex.rounded()))")
4244
}
43-
Text("UV Index: \(Int(currentForecast.uvIndex.rounded()))")
4445
}
45-
}
4646

47-
Text("\(currentForecast.conditionDescriptions.joined(separator: ", ").capitalized)")
48-
.font(.title2)
49-
.fontWeight(.medium)
47+
Text("\(currentForecast.conditionDescriptions.joined(separator: ", ").capitalized)")
48+
.font(.title2)
49+
.fontWeight(.medium)
50+
}
51+
.padding([.horizontal], 40)
5052
}
51-
.padding([.horizontal], 40)
5253
}
5354
}
5455

MobileWeather/CurrentForecast.swift

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,22 @@ struct CurrentForecast: Equatable, Hashable, Decodable {
3131
visibility = Measurement<UnitLength>(value: 0.0, unit: .miles)
3232
windSpeed = Measurement<UnitSpeed>(value: 0.0, unit: .milesPerHour)
3333
windGust = nil
34-
conditionDescriptions = []
35-
conditionIconNames = []
34+
conditionDescriptions = ["Sunny"]
35+
conditionIconNames = [OpenWeatherIcon.clearDay.rawValue]
36+
}
37+
38+
init(date: Date, sunriseDate: Date, sunsetDate: Date, temperature: Measurement<UnitTemperature>, feelsLikeTemperature: Measurement<UnitTemperature>, uvIndex: Double, visibility: Measurement<UnitLength>, windSpeed: Measurement<UnitSpeed>, windGust: Measurement<UnitSpeed>?, conditionDescriptions: [String], conditionIconNames: [String]) {
39+
self.date = date
40+
self.sunriseDate = sunriseDate
41+
self.sunsetDate = sunsetDate
42+
self.temperature = temperature
43+
self.feelsLikeTemperature = feelsLikeTemperature
44+
self.uvIndex = uvIndex
45+
self.visibility = visibility
46+
self.windSpeed = windSpeed
47+
self.windGust = windGust
48+
self.conditionDescriptions = conditionDescriptions
49+
self.conditionIconNames = conditionIconNames
3650
}
3751

3852
init(from decoder: Decoder) throws {

MobileWeather/DailyConditionsView.swift

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,24 +12,22 @@ struct DailyConditionsView: View {
1212
var dailyForecast: [DailyForecast]
1313

1414
var body: some View {
15-
Text("Daily")
16-
.font(.title)
17-
.fontWeight(.bold)
18-
19-
VStack(alignment: .center, spacing: 20) {
20-
ForEach(dailyForecast) { forecast in
21-
DayForecastView(forecast: forecast)
15+
GroupBox {
16+
VStack(alignment: .center, spacing: 20) {
17+
ForEach(dailyForecast) { forecast in
18+
DayForecastView(forecast: forecast)
19+
}
2220
}
21+
} label: {
22+
Text("Daily")
23+
.font(.title).fontWeight(.bold)
2324
}
2425
}
2526
}
2627

2728
struct DailyConditionsView_Previews: PreviewProvider {
2829
static var previews: some View {
29-
let json = Bundle.main.url(forResource: "weather-api-response", withExtension: "json")!
30-
let jsonData = try! Data(contentsOf: json)
31-
let data = try! JSONDecoder().decode(WeatherData.self, from: jsonData)
32-
33-
DailyConditionsView(dailyForecast: data.daily)
30+
DailyConditionsView(dailyForecast: DailyForecast.testData)
31+
.previewLayout(.sizeThatFits)
3432
}
3533
}

MobileWeather/DailyForecast.swift

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,11 +85,19 @@ struct DailyForecast: Identifiable, Equatable, Hashable, Decodable {
8585
}
8686

8787
extension DailyForecast {
88-
static var testData: DailyForecast = {
88+
static var testData: [DailyForecast] = {
89+
var testDataArray = [DailyForecast]()
90+
8991
let sunriseDate = DateComponents(calendar: Calendar.current, timeZone: TimeZone.current, year: 2021, month: 12, day: 2, hour: 7, minute: 51, second: 1).date!
9092
let sunsetDate = DateComponents(calendar: Calendar.current, timeZone: TimeZone.current, year: 2021, month: 12, day: 2, hour: 20, minute: 2, second: 1).date!
91-
let testData = DailyForecast(date: Date(), sunriseDate: sunriseDate, sunsetDate: sunsetDate, lowTemperature: Measurement<UnitTemperature>(value: 61, unit: .fahrenheit), highTemperature: Measurement<UnitTemperature>(value: 80, unit: .fahrenheit), windSpeed: Measurement<UnitSpeed>(value: 15, unit: .milesPerHour), windGust: Measurement<UnitSpeed>(value: 25, unit: .milesPerHour), rainAmount: Measurement<UnitLength>(value: 0.1, unit: .inches), snowAmount: Measurement<UnitLength>(value: 0, unit: .inches), precipitationChance: 0.2, conditionDescriptions: ["overcast and rainy"], conditionIconNames: [OpenWeatherIcon.lightRainDay.rawValue])
93+
let testData = DailyForecast(date: Date(), sunriseDate: sunriseDate, sunsetDate: sunsetDate, lowTemperature: Measurement<UnitTemperature>(value: 61, unit: .fahrenheit), highTemperature: Measurement<UnitTemperature>(value: 80, unit: .fahrenheit), windSpeed: Measurement<UnitSpeed>(value: 15, unit: .milesPerHour), windGust: Measurement<UnitSpeed>(value: 25, unit: .milesPerHour), rainAmount: Measurement<UnitLength>(value: 0.1, unit: .inches), snowAmount: Measurement<UnitLength>(value: 0, unit: .inches), precipitationChance: 0.2, conditionDescriptions: ["overcast and rainy"], conditionIconNames: [OpenWeatherIcon.rainDay.rawValue])
94+
testDataArray.append(testData)
95+
96+
let sunriseDate2 = DateComponents(calendar: Calendar.current, timeZone: TimeZone.current, year: 2021, month: 12, day: 3, hour: 7, minute: 51, second: 1).date!
97+
let sunsetDate2 = DateComponents(calendar: Calendar.current, timeZone: TimeZone.current, year: 2021, month: 12, day: 3, hour: 20, minute: 2, second: 1).date!
98+
let testData2 = DailyForecast(date: Date(), sunriseDate: sunriseDate2, sunsetDate: sunsetDate2, lowTemperature: Measurement<UnitTemperature>(value: 84, unit: .fahrenheit), highTemperature: Measurement<UnitTemperature>(value: 102, unit: .fahrenheit), windSpeed: Measurement<UnitSpeed>(value: 15, unit: .milesPerHour), windGust: Measurement<UnitSpeed>(value: 3, unit: .milesPerHour), rainAmount: Measurement<UnitLength>(value: 2.2, unit: .inches), snowAmount: Measurement<UnitLength>(value: 0, unit: .inches), precipitationChance: 0.95, conditionDescriptions: ["Light Rain"], conditionIconNames: [OpenWeatherIcon.lightRainDay.rawValue])
99+
testDataArray.append(testData2)
92100

93-
return testData
101+
return testDataArray
94102
}()
95103
}

MobileWeather/DayForecastView.swift

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,21 @@ struct DayForecastView: View {
1414
static private let dayFormatter: DateFormatter = {
1515
let f = DateFormatter()
1616
f.timeStyle = .none
17+
f.locale = .autoupdatingCurrent
1718
f.doesRelativeDateFormatting = true
18-
f.setLocalizedDateFormatFromTemplate("EE MM d")
19+
f.setLocalizedDateFormatFromTemplate("EE MM dd")
1920

2021
return f
2122
}()
2223

2324
var body: some View {
2425
VStack(alignment: .leading, spacing: 5) {
25-
Text(DayForecastView.dayFormatter.string(from: forecast.date))
26-
.font(.subheadline)
26+
HStack {
27+
Spacer()
28+
Text(DayForecastView.dayFormatter.string(from: forecast.date))
29+
.font(.subheadline)
30+
Spacer()
31+
}
2732

2833
HStack {
2934
let iconName = OpenWeatherIcon(rawValue: forecast.conditionIconNames.first ?? OpenWeatherIcon.clearDay.rawValue)!
@@ -33,30 +38,36 @@ struct DayForecastView: View {
3338
Spacer()
3439

3540
Text(forecast.conditionDescriptions.first!.capitalized)
41+
.frame(maxWidth: 1000, alignment: .leading)
3642

3743
Spacer()
3844

3945
HStack(alignment: .center, spacing: 4) {
4046
HStack(alignment: .center, spacing: 0) {
4147
Image(systemName: "arrow.up")
4248
.foregroundColor(.red)
43-
Text(WeatherView.temperatureFormatter.string(from: forecast.highTemperature))
49+
Text(WeatherFormatter.temperatureFormatter.string(from: forecast.highTemperature))
4450
}
4551

4652
HStack(alignment: .center, spacing: 0) {
4753
Image(systemName: "arrow.down")
4854
.foregroundColor(.blue)
49-
Text(WeatherView.temperatureFormatter.string(from: forecast.lowTemperature))
55+
Text(WeatherFormatter.temperatureFormatter.string(from: forecast.lowTemperature))
5056
}
5157
}
5258
.font(.subheadline)
59+
5360
}
5461
}
5562
}
5663
}
5764

5865
struct DayForecastView_Previews: PreviewProvider {
5966
static var previews: some View {
60-
DayForecastView(forecast: DailyForecast.testData)
67+
VStack {
68+
DayForecastView(forecast: DailyForecast.testData[0])
69+
DayForecastView(forecast: DailyForecast.testData[1])
70+
}
71+
.previewLayout(.sizeThatFits)
6172
}
6273
}

MobileWeather/HourForecastView.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ struct HourForecastView: View {
2525
WeatherImageView(openWeatherName: iconName)
2626
.frame(width: 40, height: 40)
2727

28-
Text(WeatherView.temperatureFormatter.string(from: forecast.temperature))
28+
Text(WeatherFormatter.temperatureFormatter.string(from: forecast.temperature))
2929
Text(HourForecastView.hourDateFormatter.string(from: forecast.date))
3030
.font(.subheadline)
3131
}

MobileWeather/HourlyConditionsView.swift

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,17 @@ struct HourlyConditionsView: View {
1212
var hourlyForecast: [HourlyForecast]
1313

1414
var body: some View {
15-
Text("Hourly")
16-
.font(.title)
17-
.fontWeight(.bold)
18-
19-
ScrollView(.horizontal, showsIndicators: true) {
20-
HStack(alignment: .center, spacing: 20) {
21-
ForEach(hourlyForecast) { forecast in
22-
HourForecastView(forecast: forecast)
15+
GroupBox {
16+
ScrollView(.horizontal, showsIndicators: true) {
17+
HStack(alignment: .center, spacing: 20) {
18+
ForEach(hourlyForecast) { forecast in
19+
HourForecastView(forecast: forecast)
20+
}
2321
}
2422
}
23+
} label: {
24+
Text("Hourly")
25+
.font(.title).fontWeight(.bold)
2526
}
2627
}
2728
}

MobileWeather/Info.plist

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -27,18 +27,7 @@
2727
<key>NSLocationUsageDescription</key>
2828
<string></string>
2929
<key>NSLocationWhenInUseUsageDescription</key>
30-
<string></string>
31-
<key>UIBackgroundModes</key>
32-
<array>
33-
<string>external-accessory</string>
34-
<string>fetch</string>
35-
</array>
36-
<key>UILaunchStoryboardName</key>
37-
<string>Main</string>
38-
<key>UIRequiredDeviceCapabilities</key>
39-
<array>
40-
<string>armv7</string>
41-
</array>
30+
<string>SDL Weather uses your location to find the weather where you are</string>
4231
<key>UIApplicationSceneManifest</key>
4332
<dict>
4433
<key>UIApplicationSupportsMultipleScenes</key>
@@ -56,6 +45,17 @@
5645
</array>
5746
</dict>
5847
</dict>
48+
<key>UIBackgroundModes</key>
49+
<array>
50+
<string>external-accessory</string>
51+
<string>fetch</string>
52+
</array>
53+
<key>UILaunchStoryboardName</key>
54+
<string>Main</string>
55+
<key>UIRequiredDeviceCapabilities</key>
56+
<array>
57+
<string>armv7</string>
58+
</array>
5959
<key>UISupportedExternalAccessoryProtocols</key>
6060
<array>
6161
<string>com.ford.sync.prot0</string>

0 commit comments

Comments
 (0)