Commit 3696209f by Demid Merzlyakov

IOS-72: widget working with blurry images.

parent 3bc28137
......@@ -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 = (
);
......
......@@ -271,4 +271,4 @@
// Ads
"ads.native.sponsored" = "Sponsored";
"ads.placeholder" = "Advertisment";
"ads.placeholder" = "Advertisement";
......@@ -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
......
......@@ -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
......
......@@ -10,7 +10,7 @@ import SwiftUI
@main
struct OneWeatherWidget: Widget {
private let kind = "OneWeater_Widget"
private let kind = "com.onelouder.oneweather.widget"
var body: some WidgetConfiguration {
StaticConfiguration(kind: kind, provider: WeatherProvider()) { weatherEntry in
......
......@@ -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))
......
......@@ -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) -> UIImageView {
func makeUIView(context: Context) -> UIViewType {
let imageView = UIImageView()
imageView.setContentCompressionResistancePriority(.fittingSizeLevel,
for: .vertical)
imageView.image = image
imageView.contentMode = contentMode
imageView.tintColor = tintColor
return imageView
}
func updateUIView(_ uiView: UIImageView, context: Context) {
func updateUIView(_ uiView: UIViewType, 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))
}
}
......@@ -9,19 +9,19 @@ import SwiftUI
import OneWeatherCore
struct SmallWidgetViewModel {
let cityName:String
let temperature:String
let weatherType:String
let weatherIcon:VectorImage
let highTemperature:String
let lowTemperature:String
let isDeviceLocation:Bool
let cityName: String
let temperature: String
let weatherType: String
let weatherIcon: UIImage
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
......
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