Skip to content

Commit

Permalink
Create small widget
Browse files Browse the repository at this point in the history
Improve widget provider
Configure App Group Identifier
Improve widget location fetching logic
Clean up code
  • Loading branch information
pawelmilek committed Dec 12, 2023
1 parent 945ea82 commit 45893e3
Show file tree
Hide file tree
Showing 43 changed files with 1,224 additions and 105 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"colors" : [
{
"color" : {
"color-space" : "display-p3",
"components" : {
"alpha" : "1.000",
"blue" : "0x35",
"green" : "0x24",
"red" : "0x00"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"images" : [
{
"filename" : "AppIcon.png",
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
6 changes: 6 additions & 0 deletions SwiftyForecast Widget/Assets.xcassets/Contents.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"colors" : [
{
"color" : {
"color-space" : "display-p3",
"components" : {
"alpha" : "1.000",
"blue" : "0x3B",
"green" : "0x6E",
"red" : "0xEC"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "clearSky.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "cloudy_large.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
85 changes: 85 additions & 0 deletions SwiftyForecast Widget/CurrentWeatherView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
//
// CurrentWeatherView.swift
// SwiftyForecast
//
// Created by Pawel Milek on 12/8/23.
// Copyright © 2023 Pawel Milek. All rights reserved.
//

import SwiftUI

struct CurrentWeatherView: View {
var entry: WeatherProvider.Entry

var body: some View {
GeometryReader { proxy in
HStack(alignment: .top, spacing: 0) {
iconView
.frame(maxWidth: proxy.size.width * 0.5)
locationView
.frame(maxWidth: proxy.size.width * 0.5, alignment: .leading)
}
temperatureView
.frame(maxWidth: proxy.size.width, alignment: .center)
.offset(y: 30)
}
.overlay(alignment: .bottom) {
descriptionView
.frame(maxWidth: .infinity, alignment: .center)
}
}
}

private extension CurrentWeatherView {
var iconView: some View {
entry.icon
.resizable()
.scaledToFit()
.shadow(
color: .white,
radius: 0.5,
x: 1,
y: 1
)
}

var locationView: some View {
Text(entry.locationName)
.font(.caption2)
.fontWeight(.semibold)
.fontDesign(.monospaced)
.foregroundStyle(.white)
.lineLimit(2)
}

var temperatureView: some View {
VStack(spacing: -10) {
Text(entry.temperature)
.font(.system(size: 50, weight: .bold, design: .monospaced))
.modifier(TextScaledModifier())
Text(entry.temperatureMaxMin)
.font(.caption2)
}
.lineLimit(1)
.foregroundStyle(.accent)
.fontDesign(.monospaced)
}

var descriptionView: some View {
HStack(alignment: .center, spacing: 0) {
Text(entry.description)
.font(.caption2)
.fontWeight(.semibold)
.fontDesign(.monospaced)
.foregroundStyle(.accent)
.lineLimit(2)
.padding(.vertical, 3)
.padding(.horizontal, 10)
}
.background(
Color.white
.opacity(0.4)
.clipShape(RoundedRectangle(cornerRadius: 9))
)
}
}
26 changes: 26 additions & 0 deletions SwiftyForecast Widget/Info.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSLocationUsageDescription</key>
<string>The app requires location services to get weather data in your area.</string>
<key>NSWidgetWantsLocation</key>
<true/>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>The app requires location services to get weather data in your area.</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>The app requires location services to get weather data in your area.</string>
<key>NSLocationDefaultAccuracyReduced</key>
<true/>
<key>ConfigurationSettings</key>
<dict>
<key>WeatherServiceApiKey</key>
<string>$(API_KEY)</string>
</dict>
<key>NSExtension</key>
<dict>
<key>NSExtensionPointIdentifier</key>
<string>com.apple.widgetkit-extension</string>
</dict>
</dict>
</plist>
35 changes: 35 additions & 0 deletions SwiftyForecast Widget/SwiftyForecastWidget.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//
// SwiftyForecastWidgetEntryView.swift
// SwiftyForecast Widget
//
// Created by Pawel Milek on 12/6/23.
// Copyright © 2023 Pawel Milek. All rights reserved.
//

import WidgetKit
import SwiftUI

struct SwiftyForecastWidget: Widget {
let kind = "com.pawelmilek.Swifty-Forecast.widget"

var body: some WidgetConfiguration {
StaticConfiguration(
kind: kind,
provider: WeatherProvider()
) { entry in
CurrentWeatherView(entry: entry)
.frame(maxWidth: .infinity, maxHeight: .infinity)
.containerBackground(.widgetBackground, for: .widget)
}
.configurationDisplayName("Weather")
.description("Glance the conditions for current location.")
.supportedFamilies([.systemSmall])
}
}

#Preview(as: .systemSmall) {
SwiftyForecastWidget()
} timeline: {
WeatherEntry.sampleTimeline.first!
WeatherEntry.sampleTimeline.last!
}
17 changes: 17 additions & 0 deletions SwiftyForecast Widget/SwiftyForecastWidgetBundle.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//
// SwiftyForecastWidgetBundle.swift
// SwiftyForecast Widget
//
// Created by Pawel Milek on 12/6/23.
// Copyright © 2023 Pawel Milek. All rights reserved.
//

import WidgetKit
import SwiftUI

@main
struct SwiftyForecastWidgetBundle: WidgetBundle {
var body: some Widget {
SwiftyForecastWidget()
}
}
56 changes: 56 additions & 0 deletions SwiftyForecast Widget/WeatherEntry.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
//
// WeatherEntry.swift
// SwiftyForecast
//
// Created by Pawel Milek on 12/8/23.
// Copyright © 2023 Pawel Milek. All rights reserved.
//

import WidgetKit
import SwiftUI

struct WeatherEntry: TimelineEntry {
let date: Date
let icon: Image
let temperature: String
let temperatureMaxMin: String
let locationName: String
let description: String

init(
date: Date,
icon: Image,
temperature: String,
temperatureMaxMin: String,
locationName: String,
description: String
) {
self.date = date
self.icon = icon
self.temperature = temperature
self.temperatureMaxMin = temperatureMaxMin
self.locationName = locationName
self.description = description
}
}

extension WeatherEntry {
static let sampleTimeline = [
WeatherEntry(
date: Date(),
icon: Image(.cloudySky),
temperature: "69°",
temperatureMaxMin: "⏶ 75° ⏷ 72°",
locationName: "Cupertino",
description: "light intensity shower rain"
),
WeatherEntry(
date: Date(),
icon: Image(.clearSky),
temperature: "87°",
temperatureMaxMin: "⏶ 92° ⏷ 45°",
locationName: "Cupertino",
description: "scattered clouds"
)
]
}
Loading

0 comments on commit 45893e3

Please sign in to comment.