Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
1
1weather
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Dmitriy Stepanets
1weather
Commits
3696209f
Commit
3696209f
authored
Jun 21, 2021
by
Demid Merzlyakov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
IOS-72: widget working with blurry images.
parent
3bc28137
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
95 additions
and
49 deletions
+95
-49
1Weather.xcodeproj/project.pbxproj
+35
-12
1Weather/Resources/en.lproj/Localizable.strings
+1
-1
OneWeatherCore/OneWeatherCore/Model/LocationManager.swift
+10
-1
OneWeatherWidget/Data/WeatherEntry.swift
+1
-1
OneWeatherWidget/OneWeatherWidget.swift
+1
-1
OneWeatherWidget/UI/SmallWidgetView.swift
+23
-21
OneWeatherWidget/UI/VectorImage.swift
+16
-4
OneWeatherWidget/ViewModels/SmallWidgetViewModel.swift
+8
-8
No files found.
1Weather.xcodeproj/project.pbxproj
View file @
3696209f
...
...
@@ -165,12 +165,6 @@
CDE2BF222609D4250085C930
/* ForecastWindSpeedCell.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CDE2BF212609D4250085C930
/* ForecastWindSpeedCell.swift */
;
};
CDE2BF252609D9140085C930
/* ForecastWindButton.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CDE2BF242609D9140085C930
/* ForecastWindButton.swift */
;
};
CDEE8AD725DA882200C289DE
/* ForecastPeriodButton.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CDEE8AD625DA882200C289DE
/* ForecastPeriodButton.swift */
;
};
CDEF70E6266E17BC00BA40D6
/* OneWeatherCore.framework in Frameworks */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CDEF70E2266E10B600BA40D6
/* OneWeatherCore.framework */
;
};
CDEF70E9266E18D600BA40D6
/* BlendFIPSSource.framework in Frameworks */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CEEF40FF265E47FF00425D8F
/* BlendFIPSSource.framework */
;
};
CDEF70EB266E18D600BA40D6
/* BlendHealthSource.framework in Frameworks */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CD3883C12657B6A10070FD6F
/* BlendHealthSource.framework */
;
};
CDEF70ED266E18D700BA40D6
/* CoreDataStorage.framework in Frameworks */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CD3884542657BA8B0070FD6F
/* CoreDataStorage.framework */
;
};
CDEF70EF266E18D700BA40D6
/* DelayedSaveStorage.framework in Frameworks */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CD3884822657BBCC0070FD6F
/* DelayedSaveStorage.framework */
;
};
CDEF70F2266E192200BA40D6
/* WDTWeatherSource.framework in Frameworks */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CDFE45BB26566EF50021A29F
/* WDTWeatherSource.framework */
;
};
CDEF70F6266E25E400BA40D6
/* VectorImage.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CDEF70F5266E25E400BA40D6
/* VectorImage.swift */
;
};
CDF63D29266779D8003DE569
/* AdLogger.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CDF63D28266779D8003DE569
/* AdLogger.swift */
;
};
CDF8F12A262089A200DB384A
/* MapTimeView.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CDF8F129262089A200DB384A
/* MapTimeView.swift */
;
};
...
...
@@ -208,6 +202,18 @@
CE578FE725FB415F00E8B85D
/* LocationsViewModel.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CE578FE425FB415F00E8B85D
/* LocationsViewModel.swift */
;
};
CE6BE4942634170800626822
/* USStateCode.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CE6BE4932634170800626822
/* USStateCode.swift */
;
};
CE6F5F0C263C8B3D00973137
/* SmartTextProvider.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CE6F5F0B263C8B3C00973137
/* SmartTextProvider.swift */
;
};
CE7298C9267A34F3002745D0
/* BlendFIPSSource.framework in Frameworks */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CEEF40FF265E47FF00425D8F
/* BlendFIPSSource.framework */
;
};
CE7298CA267A34F3002745D0
/* BlendFIPSSource.framework in Embed Frameworks */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CEEF40FF265E47FF00425D8F
/* BlendFIPSSource.framework */
;
settings
=
{
ATTRIBUTES
=
(
CodeSignOnCopy
,
RemoveHeadersOnCopy
,
);
};
};
CE7298CC267A34F5002745D0
/* BlendHealthSource.framework in Frameworks */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CD3883C12657B6A10070FD6F
/* BlendHealthSource.framework */
;
};
CE7298CD267A34F5002745D0
/* BlendHealthSource.framework in Embed Frameworks */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CD3883C12657B6A10070FD6F
/* BlendHealthSource.framework */
;
settings
=
{
ATTRIBUTES
=
(
CodeSignOnCopy
,
RemoveHeadersOnCopy
,
);
};
};
CE7298CE267A34F7002745D0
/* CoreDataStorage.framework in Frameworks */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CD3884542657BA8B0070FD6F
/* CoreDataStorage.framework */
;
};
CE7298CF267A34F7002745D0
/* CoreDataStorage.framework in Embed Frameworks */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CD3884542657BA8B0070FD6F
/* CoreDataStorage.framework */
;
settings
=
{
ATTRIBUTES
=
(
CodeSignOnCopy
,
RemoveHeadersOnCopy
,
);
};
};
CE7298D0267A34F8002745D0
/* DelayedSaveStorage.framework in Frameworks */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CD3884822657BBCC0070FD6F
/* DelayedSaveStorage.framework */
;
};
CE7298D1267A34F8002745D0
/* DelayedSaveStorage.framework in Embed Frameworks */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CD3884822657BBCC0070FD6F
/* DelayedSaveStorage.framework */
;
settings
=
{
ATTRIBUTES
=
(
CodeSignOnCopy
,
RemoveHeadersOnCopy
,
);
};
};
CE7298D2267A34FA002745D0
/* OneWeatherCore.framework in Frameworks */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CDEF70E2266E10B600BA40D6
/* OneWeatherCore.framework */
;
};
CE7298D3267A34FA002745D0
/* OneWeatherCore.framework in Embed Frameworks */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CDEF70E2266E10B600BA40D6
/* OneWeatherCore.framework */
;
settings
=
{
ATTRIBUTES
=
(
CodeSignOnCopy
,
RemoveHeadersOnCopy
,
);
};
};
CE7298D4267A34FF002745D0
/* WDTWeatherSource.framework in Frameworks */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CDFE45BB26566EF50021A29F
/* WDTWeatherSource.framework */
;
};
CE7298D5267A34FF002745D0
/* WDTWeatherSource.framework in Embed Frameworks */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CDFE45BB26566EF50021A29F
/* WDTWeatherSource.framework */
;
settings
=
{
ATTRIBUTES
=
(
CodeSignOnCopy
,
RemoveHeadersOnCopy
,
);
};
};
CE81A422266E289E00800EFF
/* NativeAdView.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CE81A421266E289E00800EFF
/* NativeAdView.swift */
;
};
CE849DB82638C33600DEFFBD
/* NotificationService.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CE849DB72638C33600DEFFBD
/* NotificationService.swift */
;
};
CE849DBC2638C33600DEFFBD
/* OneWeatherNotificationServiceExtension.appex in Embed App Extensions */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CE849DB52638C33600DEFFBD
/* OneWeatherNotificationServiceExtension.appex */
;
settings
=
{
ATTRIBUTES
=
(
RemoveHeadersOnCopy
,
);
};
};
...
...
@@ -272,6 +278,22 @@
name
=
"Embed Frameworks"
;
runOnlyForDeploymentPostprocessing
=
0
;
};
CE7298CB267A34F3002745D0
/* Embed Frameworks */
=
{
isa
=
PBXCopyFilesBuildPhase
;
buildActionMask
=
2147483647
;
dstPath
=
""
;
dstSubfolderSpec
=
10
;
files
=
(
CE7298D5267A34FF002745D0
/* WDTWeatherSource.framework in Embed Frameworks */
,
CE7298D1267A34F8002745D0
/* DelayedSaveStorage.framework in Embed Frameworks */
,
CE7298CF267A34F7002745D0
/* CoreDataStorage.framework in Embed Frameworks */
,
CE7298CA267A34F3002745D0
/* BlendFIPSSource.framework in Embed Frameworks */
,
CE7298D3267A34FA002745D0
/* OneWeatherCore.framework in Embed Frameworks */
,
CE7298CD267A34F5002745D0
/* BlendHealthSource.framework in Embed Frameworks */
,
);
name
=
"Embed Frameworks"
;
runOnlyForDeploymentPostprocessing
=
0
;
};
CE849DBD2638C33600DEFFBD
/* Embed App Extensions */
=
{
isa
=
PBXCopyFilesBuildPhase
;
buildActionMask
=
12
;
...
...
@@ -517,14 +539,14 @@
isa
=
PBXFrameworksBuildPhase
;
buildActionMask
=
2147483647
;
files
=
(
CDEF70EB266E18D600BA40D6
/* BlendHealthSource.framework in Frameworks */
,
CD1B713D2660F95000916E71
/* SwiftUI.framework in Frameworks */
,
CDEF70E9266E18D600BA40D6
/* BlendFIPSSource.framework in Frameworks */
,
CDEF70ED266E18D700BA40D6
/* CoreDataStorage.framework in Frameworks */
,
CDEF70E6266E17BC00BA40D6
/* OneWeatherCore.framework in Frameworks */
,
CE7298CC267A34F5002745D0
/* BlendHealthSource.framework in Frameworks */
,
CD1B713B2660F95000916E71
/* WidgetKit.framework in Frameworks */
,
CDEF70F2266E192200BA40D6
/* WDTWeatherSource.framework in Frameworks */
,
CDEF70EF266E18D700BA40D6
/* DelayedSaveStorage.framework in Frameworks */
,
CE7298D0267A34F8002745D0
/* DelayedSaveStorage.framework in Frameworks */
,
CE7298C9267A34F3002745D0
/* BlendFIPSSource.framework in Frameworks */
,
CE7298CE267A34F7002745D0
/* CoreDataStorage.framework in Frameworks */
,
CE7298D4267A34FF002745D0
/* WDTWeatherSource.framework in Frameworks */
,
CE7298D2267A34FA002745D0
/* OneWeatherCore.framework in Frameworks */
,
);
runOnlyForDeploymentPostprocessing
=
0
;
};
...
...
@@ -1349,6 +1371,7 @@
CD1B71352660F95000916E71
/* Sources */
,
CD1B71362660F95000916E71
/* Frameworks */
,
CD1B71372660F95000916E71
/* Resources */
,
CE7298CB267A34F3002745D0
/* Embed Frameworks */
,
);
buildRules
=
(
);
...
...
1Weather/Resources/en.lproj/Localizable.strings
View file @
3696209f
...
...
@@ -271,4 +271,4 @@
// Ads
"ads.native.sponsored" = "Sponsored";
"ads.placeholder" = "Advertisment";
"ads.placeholder" = "Advertis
e
ment";
OneWeatherCore/OneWeatherCore/Model/LocationManager.swift
View file @
3696209f
...
...
@@ -9,6 +9,7 @@ import Foundation
import
CoreLocation
import
UIKit
import
OneWeatherAnalytics
import
WidgetKit
public
protocol
LocationManagerDelegate
:
AnyObject
{
func
locationManager
(
_
locationManager
:
LocationManager
,
changedSelectedLocation
newLocation
:
Location
?)
...
...
@@ -89,6 +90,9 @@ public class LocationManager {
lastSeenCityId
=
newLocation
?
.
cityId
}
if
#available(iOS 14.0, *)
{
WidgetCenter
.
shared
.
reloadAllTimelines
()
}
}
storage
.
save
(
locations
:
locations
,
selectedIndex
:
selectedLocationIndex
)
}
...
...
@@ -403,11 +407,13 @@ public class LocationManager {
completion
:
((
_
updatedLocation
:
Location
?)
->
Void
)?
=
nil
)
{
guard
let
location
=
location
else
{
log
.
warning
(
"Update weather: empty location."
)
completion
?(
nil
)
return
}
if
let
lastTimeUpdated
=
location
.
lastWeatherUpdateDate
{
guard
Date
()
.
timeIntervalSince
(
lastTimeUpdated
)
>=
weatherUpdateSource
.
weatherUpdateInterval
else
{
log
.
verbose
(
"Update weather (
\(
location
)
): fresh enough (last updated at
\(
lastTimeUpdated
)
), skip update."
)
completion
?(
location
)
return
}
}
...
...
@@ -415,7 +421,10 @@ public class LocationManager {
log
.
info
(
"Update weather for:
\(
location
)
; type:
\(
updateType
)
"
)
weatherUpdateSource
.
updateWeather
(
for
:
location
,
type
:
updateType
)
{
[
weak
self
]
(
updatedLocation
,
error
)
in
guard
let
self
=
self
else
{
return
}
guard
let
self
=
self
else
{
completion
?(
updatedLocation
)
return
}
if
let
updatedLocation
=
updatedLocation
{
self
.
log
.
info
(
"Update weather finished for
\(
location
)
"
)
self
.
makeChanges
(
to
:
location
,
in
:
"weather"
)
{
(
oldLocation
)
->
Location
in
...
...
OneWeatherWidget/Data/WeatherEntry.swift
View file @
3696209f
...
...
@@ -30,7 +30,7 @@ struct WeatherEntry: TimelineEntry {
dayTimeForecast
:
[])
let
date
:
Date
let
location
:
Location
let
location
:
Location
init
(
location
:
Location
?
=
nil
,
date
:
Date
=
Date
())
{
self
.
location
=
location
??
WeatherEntry
.
defaultLocation
...
...
OneWeatherWidget/OneWeatherWidget.swift
View file @
3696209f
...
...
@@ -10,7 +10,7 @@ import SwiftUI
@main
struct
OneWeatherWidget
:
Widget
{
private
let
kind
=
"
OneWeater_W
idget"
private
let
kind
=
"
com.onelouder.oneweather.w
idget"
var
body
:
some
WidgetConfiguration
{
StaticConfiguration
(
kind
:
kind
,
provider
:
WeatherProvider
())
{
weatherEntry
in
...
...
OneWeatherWidget/UI/SmallWidgetView.swift
View file @
3696209f
...
...
@@ -15,19 +15,13 @@ struct SmallWidgetView: View {
//Private
@Environment(\.colorScheme)
private
var
colorScheme
private
var
interfaceStyle
:
AppInterfaceStyle
{
switch
Settings
.
shared
.
appTheme
{
case
.
light
:
private
var
interfaceStyle
:
AppInterfaceStyle
{
if
#available(iOS 13, *)
{
return
colorScheme
==
.
light
?
.
light
:
.
dark
}
else
{
return
.
light
case
.
dark
:
return
.
dark
case
.
system
:
if
#available(iOS 13, *)
{
return
colorScheme
==
.
light
?
.
light
:
.
dark
}
else
{
return
.
light
}
}
}
...
...
@@ -39,37 +33,43 @@ struct SmallWidgetView: View {
.
multilineTextAlignment
(
.
leading
)
.
font
(
AppFont
.
SFProDisplay
.
regular
(
size
:
12
)
.
font
)
.
foregroundColor
(
ThemeManager
.
currentTheme
.
graphTintColor
.
color
)
VectorImage
(
name
:
"location_arrow"
,
contentMode
:
.
scaleAspectFit
,
tintColor
:
ThemeManager
.
currentTheme
.
graphTintColor
)
Image
(
"location_arrow"
)
.
resizable
()
.
renderingMode
(
.
template
)
.
frame
(
width
:
8
,
height
:
8
,
alignment
:
.
center
)
.
aspectRatio
(
contentMode
:
.
fit
)
.
foregroundColor
(
Color
(
ThemeManager
.
currentTheme
.
graphTintColor
.
cgColor
))
.
opacity
(
widgetViewModel
.
isDeviceLocation
?
1
:
0
)
Spacer
()
}
.
padding
(
.
top
,
12
)
.
padding
(
.
leading
,
10
)
HStack
(
spacing
:
0
)
{
VStack
(
alignment
:
.
leading
){
Text
(
widgetViewModel
.
temperature
)
.
font
(
AppFont
.
SFProDisplay
.
light
(
size
:
32
)
.
font
)
.
padding
(
.
leading
,
10
)
.
padding
(
.
trailing
,
4
)
.
textColor
(
for
:
interfaceStyle
)
Text
(
widgetViewModel
.
weatherType
)
.
font
(
AppFont
.
SFProDisplay
.
regular
(
size
:
12
)
.
font
)
.
frame
(
width
:
geometry
.
size
.
width
*
0.5
,
alignment
:
.
leading
)
.
textColor
(
for
:
interfaceStyle
)
.
padding
(
.
leading
,
10
)
.
padding
(
.
trailing
,
4
)
.
textColor
(
for
:
interfaceStyle
)
Spacer
(
minLength
:
0
)
}
.
frame
(
height
:
70
)
Spacer
(
minLength
:
0
)
widgetViewModel
.
weatherIcon
Image
(
uiImage
:
widgetViewModel
.
weatherIcon
)
.
resizable
()
.
aspectRatio
(
contentMode
:
.
fit
)
.
frame
(
width
:
70
,
height
:
70
,
alignment
:
.
center
)
.
shadow
(
for
:
interfaceStyle
)
.
padding
(
.
trailing
,
4
)
}
HStack
{
Text
(
"H
\(
widgetViewModel
.
highTemperature
)
"
)
.
font
(
AppFont
.
SFProDisplay
.
regular
(
size
:
12
)
.
font
)
...
...
@@ -79,7 +79,8 @@ struct SmallWidgetView: View {
.
footerTextColor
(
for
:
interfaceStyle
)
Spacer
()
}
.
padding
(
.
top
,
20
)
// .padding(.top, 20)
.
padding
(
.
bottom
,
21
)
.
padding
(
.
leading
,
10
)
}
}
...
...
@@ -116,6 +117,7 @@ private extension View {
}
}
struct
SmallWidget_Preview
:
PreviewProvider
{
static
var
previews
:
some
View
{
SmallWidgetView
(
widgetViewModel
:
.
init
(
location
:
WeatherEntry
.
defaultLocation
))
...
...
OneWeatherWidget/UI/VectorImage.swift
View file @
3696209f
...
...
@@ -6,14 +6,15 @@
//
import
SwiftUI
import
WidgetKit
struct
VectorImage
:
UIViewRepresentable
{
typealias
UIViewType
=
UIImageView
var
name
:
String
var
name
:
String
var
contentMode
:
UIView
.
ContentMode
=
.
scaleAspectFit
var
tintColor
:
UIColor
=
.
black
private
var
image
:
UIImage
?
private
var
image
:
UIImage
?
init
(
image
:
UIImage
,
contentMode
:
UIView
.
ContentMode
=
.
scaleAspectFit
,
tintColor
:
UIColor
=
.
black
)
{
self
.
image
=
image
...
...
@@ -28,14 +29,17 @@ struct VectorImage: UIViewRepresentable {
self
.
tintColor
=
tintColor
}
func
makeUIView
(
context
:
Context
)
->
UI
ImageView
{
func
makeUIView
(
context
:
Context
)
->
UI
ViewType
{
let
imageView
=
UIImageView
()
imageView
.
setContentCompressionResistancePriority
(
.
fittingSizeLevel
,
for
:
.
vertical
)
imageView
.
image
=
image
imageView
.
contentMode
=
contentMode
imageView
.
tintColor
=
tintColor
return
imageView
}
func
updateUIView
(
_
uiView
:
UI
ImageView
,
context
:
Context
)
{
func
updateUIView
(
_
uiView
:
UI
ViewType
,
context
:
Context
)
{
uiView
.
contentMode
=
contentMode
uiView
.
tintColor
=
tintColor
...
...
@@ -47,3 +51,11 @@ struct VectorImage: UIViewRepresentable {
}
}
}
struct
VectorImage_Preview
:
PreviewProvider
{
static
var
previews
:
some
View
{
VectorImage
(
image
:
UIImage
())
.
previewLayout
(
.
fixed
(
width
:
200
,
height
:
200
))
.
previewContext
(
WidgetPreviewContext
(
family
:
.
systemSmall
))
}
}
OneWeatherWidget/ViewModels/SmallWidgetViewModel.swift
View file @
3696209f
...
...
@@ -9,19 +9,19 @@ import SwiftUI
import
OneWeatherCore
struct
SmallWidgetViewModel
{
let
cityName
:
String
let
temperature
:
String
let
weatherType
:
String
let
weatherIcon
:
Vector
Image
let
highTemperature
:
String
let
lowTemperature
:
String
let
isDeviceLocation
:
Bool
let
cityName
:
String
let
temperature
:
String
let
weatherType
:
String
let
weatherIcon
:
UI
Image
let
highTemperature
:
String
let
lowTemperature
:
String
let
isDeviceLocation
:
Bool
init
(
location
:
Location
)
{
self
.
cityName
=
location
.
cityName
??
"--"
self
.
temperature
=
"
\(
location
.
today
?
.
temp
?
.
shortString
??
"--"
)
"
self
.
weatherType
=
location
.
today
?
.
type
.
localized
(
isDay
:
location
.
today
?
.
isDay
??
true
)
??
"--"
self
.
weatherIcon
=
VectorImage
(
image
:
location
.
today
?
.
type
.
image
(
isDay
:
location
.
today
?
.
isDay
??
true
)
??
UIImage
()
)
self
.
weatherIcon
=
location
.
today
?
.
type
.
image
(
isDay
:
location
.
today
?
.
isDay
??
true
)
??
UIImage
(
)
self
.
highTemperature
=
location
.
today
?
.
maxTemp
?
.
shortString
??
"--"
self
.
lowTemperature
=
location
.
today
?
.
minTemp
?
.
shortString
??
"--"
self
.
isDeviceLocation
=
location
.
deviceLocation
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment