Commit 85443f4e by Dmitriy Stepanets

Implementing minutely API

parent b50d56fd
...@@ -198,6 +198,8 @@ ...@@ -198,6 +198,8 @@
CDE2BF222609D4250085C930 /* ForecastWindSpeedCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDE2BF212609D4250085C930 /* ForecastWindSpeedCell.swift */; }; CDE2BF222609D4250085C930 /* ForecastWindSpeedCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDE2BF212609D4250085C930 /* ForecastWindSpeedCell.swift */; };
CDE2BF252609D9140085C930 /* ForecastWindButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDE2BF242609D9140085C930 /* ForecastWindButton.swift */; }; CDE2BF252609D9140085C930 /* ForecastWindButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDE2BF242609D9140085C930 /* ForecastWindButton.swift */; };
CDEE8AD725DA882200C289DE /* ForecastPeriodButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDEE8AD625DA882200C289DE /* ForecastPeriodButton.swift */; }; CDEE8AD725DA882200C289DE /* ForecastPeriodButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDEE8AD625DA882200C289DE /* ForecastPeriodButton.swift */; };
CDF079FE26D501BD00E797D9 /* BlendMinutelySource.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CDF079FD26D501BD00E797D9 /* BlendMinutelySource.framework */; };
CDF079FF26D501BD00E797D9 /* BlendMinutelySource.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = CDF079FD26D501BD00E797D9 /* BlendMinutelySource.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
CDF63D29266779D8003DE569 /* AdLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDF63D28266779D8003DE569 /* AdLogger.swift */; }; CDF63D29266779D8003DE569 /* AdLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDF63D28266779D8003DE569 /* AdLogger.swift */; };
CDF6E87726A8329D004A9DBD /* WindWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDF6E87626A8329D004A9DBD /* WindWidget.swift */; }; CDF6E87726A8329D004A9DBD /* WindWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDF6E87626A8329D004A9DBD /* WindWidget.swift */; };
CDF8F12A262089A200DB384A /* MapTimeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDF8F129262089A200DB384A /* MapTimeView.swift */; }; CDF8F12A262089A200DB384A /* MapTimeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDF8F129262089A200DB384A /* MapTimeView.swift */; };
...@@ -284,6 +286,7 @@ ...@@ -284,6 +286,7 @@
CDFE45BD26566EF50021A29F /* WDTWeatherSource.framework in Embed Frameworks */, CDFE45BD26566EF50021A29F /* WDTWeatherSource.framework in Embed Frameworks */,
CD427D28266F856700B4350A /* InMobiShortsSource.framework in Embed Frameworks */, CD427D28266F856700B4350A /* InMobiShortsSource.framework in Embed Frameworks */,
CEEF4101265E47FF00425D8F /* BlendFIPSSource.framework in Embed Frameworks */, CEEF4101265E47FF00425D8F /* BlendFIPSSource.framework in Embed Frameworks */,
CDF079FF26D501BD00E797D9 /* BlendMinutelySource.framework in Embed Frameworks */,
CE13B97C2626FB11007CBD4D /* PSMLocationSDK.xcframework in Embed Frameworks */, CE13B97C2626FB11007CBD4D /* PSMLocationSDK.xcframework in Embed Frameworks */,
CE30E3802668FBE3006DF5CD /* OneWeatherAnalytics.framework in Embed Frameworks */, CE30E3802668FBE3006DF5CD /* OneWeatherAnalytics.framework in Embed Frameworks */,
CD615F7F265523BD00B717DB /* OneWeatherCore.framework in Embed Frameworks */, CD615F7F265523BD00B717DB /* OneWeatherCore.framework in Embed Frameworks */,
...@@ -496,6 +499,7 @@ ...@@ -496,6 +499,7 @@
CDE2BF242609D9140085C930 /* ForecastWindButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ForecastWindButton.swift; sourceTree = "<group>"; }; CDE2BF242609D9140085C930 /* ForecastWindButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ForecastWindButton.swift; sourceTree = "<group>"; };
CDEE8AD625DA882200C289DE /* ForecastPeriodButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ForecastPeriodButton.swift; sourceTree = "<group>"; }; CDEE8AD625DA882200C289DE /* ForecastPeriodButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ForecastPeriodButton.swift; sourceTree = "<group>"; };
CDEF70E2266E10B600BA40D6 /* OneWeatherCore.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = OneWeatherCore.framework; sourceTree = BUILT_PRODUCTS_DIR; }; CDEF70E2266E10B600BA40D6 /* OneWeatherCore.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = OneWeatherCore.framework; sourceTree = BUILT_PRODUCTS_DIR; };
CDF079FD26D501BD00E797D9 /* BlendMinutelySource.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = BlendMinutelySource.framework; sourceTree = BUILT_PRODUCTS_DIR; };
CDF63D28266779D8003DE569 /* AdLogger.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AdLogger.swift; sourceTree = "<group>"; }; CDF63D28266779D8003DE569 /* AdLogger.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AdLogger.swift; sourceTree = "<group>"; };
CDF6E87626A8329D004A9DBD /* WindWidget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WindWidget.swift; sourceTree = "<group>"; }; CDF6E87626A8329D004A9DBD /* WindWidget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WindWidget.swift; sourceTree = "<group>"; };
CDF8F129262089A200DB384A /* MapTimeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapTimeView.swift; sourceTree = "<group>"; }; CDF8F129262089A200DB384A /* MapTimeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapTimeView.swift; sourceTree = "<group>"; };
...@@ -566,6 +570,7 @@ ...@@ -566,6 +570,7 @@
CD3884552657BA8B0070FD6F /* CoreDataStorage.framework in Frameworks */, CD3884552657BA8B0070FD6F /* CoreDataStorage.framework in Frameworks */,
CD3884832657BBCC0070FD6F /* DelayedSaveStorage.framework in Frameworks */, CD3884832657BBCC0070FD6F /* DelayedSaveStorage.framework in Frameworks */,
CEEF4100265E47FF00425D8F /* BlendFIPSSource.framework in Frameworks */, CEEF4100265E47FF00425D8F /* BlendFIPSSource.framework in Frameworks */,
CDF079FE26D501BD00E797D9 /* BlendMinutelySource.framework in Frameworks */,
CD615F7E265523BD00B717DB /* OneWeatherCore.framework in Frameworks */, CD615F7E265523BD00B717DB /* OneWeatherCore.framework in Frameworks */,
CE30E37F2668FBE3006DF5CD /* OneWeatherAnalytics.framework in Frameworks */, CE30E37F2668FBE3006DF5CD /* OneWeatherAnalytics.framework in Frameworks */,
9FAD89D1BEBA0FEB5F50BE73 /* Pods_1Weather.framework in Frameworks */, 9FAD89D1BEBA0FEB5F50BE73 /* Pods_1Weather.framework in Frameworks */,
...@@ -1458,6 +1463,7 @@ ...@@ -1458,6 +1463,7 @@
DBFD169AA2AA6A3CB5B68BB5 /* Frameworks */ = { DBFD169AA2AA6A3CB5B68BB5 /* Frameworks */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
CDF079FD26D501BD00E797D9 /* BlendMinutelySource.framework */,
CD5909CF26A59AAA00448579 /* OneWeatherUI.framework */, CD5909CF26A59AAA00448579 /* OneWeatherUI.framework */,
CD5181BF269EEB61008E6B04 /* CoreLocation.framework */, CD5181BF269EEB61008E6B04 /* CoreLocation.framework */,
CDEF70E2266E10B600BA40D6 /* OneWeatherCore.framework */, CDEF70E2266E10B600BA40D6 /* OneWeatherCore.framework */,
......
...@@ -17,6 +17,9 @@ ...@@ -17,6 +17,9 @@
location = "group:BlendHealthSource/BlendHealthSource.xcodeproj"> location = "group:BlendHealthSource/BlendHealthSource.xcodeproj">
</FileRef> </FileRef>
<FileRef <FileRef
location = "group:BlendMinutelySource/BlendMinutelySource.xcodeproj">
</FileRef>
<FileRef
location = "group:CoreDataStorage/CoreDataStorage.xcodeproj"> location = "group:CoreDataStorage/CoreDataStorage.xcodeproj">
</FileRef> </FileRef>
<FileRef <FileRef
......
...@@ -3,4 +3,54 @@ ...@@ -3,4 +3,54 @@
uuid = "55281C35-FE9F-4CED-865E-FBED0E7393F6" uuid = "55281C35-FE9F-4CED-865E-FBED0E7393F6"
type = "0" type = "0"
version = "2.0"> version = "2.0">
<Breakpoints>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
uuid = "BD6801C5-CD0B-467D-9B94-1250A8FA6E1D"
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "BlendMinutelySource/BlendMinutelySource/BlendMinutelySource.swift"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "49"
endingLineNumber = "49"
landmarkName = "getMinutelyForecast(forLocation:completion:)"
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
uuid = "A2A04C12-64A5-4FC6-A9A4-2CECEE6DBFE9"
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "OneWeatherCore/OneWeatherCore/Model/LocationManager.swift"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "378"
endingLineNumber = "378"
landmarkName = "updateMinutelyForecast(for:)"
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
uuid = "958DC1E7-7576-44D0-B8D7-5CD5ECB0CDC1"
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "OneWeatherCore/OneWeatherCore/Model/LocationManager.swift"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "318"
endingLineNumber = "318"
landmarkName = "updateEverythingIfNeeded()"
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
</Breakpoints>
</Bucket> </Bucket>
...@@ -21,6 +21,7 @@ import OneWeatherUI ...@@ -21,6 +21,7 @@ import OneWeatherUI
import WDTWeatherSource import WDTWeatherSource
import BlendHealthSource import BlendHealthSource
import BlendMinutelySource
import BlendFIPSSource import BlendFIPSSource
import CoreDataStorage import CoreDataStorage
import DelayedSaveStorage import DelayedSaveStorage
...@@ -59,6 +60,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate { ...@@ -59,6 +60,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
//TODO: introduce dependency management (dependency injection engine coupled with a factory or something of the sort). //TODO: introduce dependency management (dependency injection engine coupled with a factory or something of the sort).
LocationManager.shared = LocationManager(weatherUpdateSource: WdtWeatherSource(), LocationManager.shared = LocationManager(weatherUpdateSource: WdtWeatherSource(),
healthSource: BlendHealthSource(), healthSource: BlendHealthSource(),
minutelyForecastSource: BlendMinutelySource(),
nwsAlertsManager: NWSAlertsManager(), nwsAlertsManager: NWSAlertsManager(),
fipsSource: BlendFIPSSource(), fipsSource: BlendFIPSSource(),
pushNotificationsManager: PushNotificationsManager.shared, pushNotificationsManager: PushNotificationsManager.shared,
......
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 50;
objects = {
/* Begin PBXBuildFile section */
CDF079E026D4EBB300E797D9 /* BlendMinutelySource.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CDF079D626D4EBB200E797D9 /* BlendMinutelySource.framework */; };
CDF079E526D4EBB300E797D9 /* BlendMinutelySourceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDF079E426D4EBB300E797D9 /* BlendMinutelySourceTests.swift */; };
CDF079E726D4EBB300E797D9 /* BlendMinutelySource.h in Headers */ = {isa = PBXBuildFile; fileRef = CDF079D926D4EBB200E797D9 /* BlendMinutelySource.h */; settings = {ATTRIBUTES = (Public, ); }; };
CDF079F826D4EE5000E797D9 /* OneWeatherCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CDF079F726D4EE5000E797D9 /* OneWeatherCore.framework */; };
CDF079FC26D4EFED00E797D9 /* BlendMinutelySource.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDF079FB26D4EFED00E797D9 /* BlendMinutelySource.swift */; };
CDF07A0E26D50B4800E797D9 /* BlendMinutelyItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDF07A0C26D50B4700E797D9 /* BlendMinutelyItem.swift */; };
CDF07A0F26D50B4800E797D9 /* BlendMinutelyForecast.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDF07A0D26D50B4700E797D9 /* BlendMinutelyForecast.swift */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
CDF079E126D4EBB300E797D9 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = CDF079CD26D4EBB200E797D9 /* Project object */;
proxyType = 1;
remoteGlobalIDString = CDF079D526D4EBB200E797D9;
remoteInfo = BlendMinutelySource;
};
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
CDF079D626D4EBB200E797D9 /* BlendMinutelySource.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = BlendMinutelySource.framework; sourceTree = BUILT_PRODUCTS_DIR; };
CDF079D926D4EBB200E797D9 /* BlendMinutelySource.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BlendMinutelySource.h; sourceTree = "<group>"; };
CDF079DA26D4EBB200E797D9 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
CDF079DF26D4EBB300E797D9 /* BlendMinutelySourceTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = BlendMinutelySourceTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
CDF079E426D4EBB300E797D9 /* BlendMinutelySourceTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlendMinutelySourceTests.swift; sourceTree = "<group>"; };
CDF079E626D4EBB300E797D9 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
CDF079F726D4EE5000E797D9 /* OneWeatherCore.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = OneWeatherCore.framework; sourceTree = BUILT_PRODUCTS_DIR; };
CDF079FB26D4EFED00E797D9 /* BlendMinutelySource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlendMinutelySource.swift; sourceTree = "<group>"; };
CDF07A0C26D50B4700E797D9 /* BlendMinutelyItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BlendMinutelyItem.swift; sourceTree = "<group>"; };
CDF07A0D26D50B4700E797D9 /* BlendMinutelyForecast.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BlendMinutelyForecast.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
CDF079D326D4EBB200E797D9 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
CDF079F826D4EE5000E797D9 /* OneWeatherCore.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
CDF079DC26D4EBB300E797D9 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
CDF079E026D4EBB300E797D9 /* BlendMinutelySource.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
CDF079CC26D4EBB200E797D9 = {
isa = PBXGroup;
children = (
CDF079D826D4EBB200E797D9 /* BlendMinutelySource */,
CDF079E326D4EBB300E797D9 /* BlendMinutelySourceTests */,
CDF079D726D4EBB200E797D9 /* Products */,
CDF079F626D4EE5000E797D9 /* Frameworks */,
);
sourceTree = "<group>";
};
CDF079D726D4EBB200E797D9 /* Products */ = {
isa = PBXGroup;
children = (
CDF079D626D4EBB200E797D9 /* BlendMinutelySource.framework */,
CDF079DF26D4EBB300E797D9 /* BlendMinutelySourceTests.xctest */,
);
name = Products;
sourceTree = "<group>";
};
CDF079D826D4EBB200E797D9 /* BlendMinutelySource */ = {
isa = PBXGroup;
children = (
CDF07A0726D5098300E797D9 /* Models */,
CDF079FB26D4EFED00E797D9 /* BlendMinutelySource.swift */,
CDF079D926D4EBB200E797D9 /* BlendMinutelySource.h */,
CDF079DA26D4EBB200E797D9 /* Info.plist */,
);
path = BlendMinutelySource;
sourceTree = "<group>";
};
CDF079E326D4EBB300E797D9 /* BlendMinutelySourceTests */ = {
isa = PBXGroup;
children = (
CDF079E426D4EBB300E797D9 /* BlendMinutelySourceTests.swift */,
CDF079E626D4EBB300E797D9 /* Info.plist */,
);
path = BlendMinutelySourceTests;
sourceTree = "<group>";
};
CDF079F626D4EE5000E797D9 /* Frameworks */ = {
isa = PBXGroup;
children = (
CDF079F726D4EE5000E797D9 /* OneWeatherCore.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
CDF07A0726D5098300E797D9 /* Models */ = {
isa = PBXGroup;
children = (
CDF07A0D26D50B4700E797D9 /* BlendMinutelyForecast.swift */,
CDF07A0C26D50B4700E797D9 /* BlendMinutelyItem.swift */,
);
path = Models;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
CDF079D126D4EBB200E797D9 /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
CDF079E726D4EBB300E797D9 /* BlendMinutelySource.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXHeadersBuildPhase section */
/* Begin PBXNativeTarget section */
CDF079D526D4EBB200E797D9 /* BlendMinutelySource */ = {
isa = PBXNativeTarget;
buildConfigurationList = CDF079EA26D4EBB300E797D9 /* Build configuration list for PBXNativeTarget "BlendMinutelySource" */;
buildPhases = (
CDF079D126D4EBB200E797D9 /* Headers */,
CDF079D226D4EBB200E797D9 /* Sources */,
CDF079D326D4EBB200E797D9 /* Frameworks */,
CDF079D426D4EBB200E797D9 /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = BlendMinutelySource;
productName = BlendMinutelySource;
productReference = CDF079D626D4EBB200E797D9 /* BlendMinutelySource.framework */;
productType = "com.apple.product-type.framework";
};
CDF079DE26D4EBB300E797D9 /* BlendMinutelySourceTests */ = {
isa = PBXNativeTarget;
buildConfigurationList = CDF079ED26D4EBB300E797D9 /* Build configuration list for PBXNativeTarget "BlendMinutelySourceTests" */;
buildPhases = (
CDF079DB26D4EBB300E797D9 /* Sources */,
CDF079DC26D4EBB300E797D9 /* Frameworks */,
CDF079DD26D4EBB300E797D9 /* Resources */,
);
buildRules = (
);
dependencies = (
CDF079E226D4EBB300E797D9 /* PBXTargetDependency */,
);
name = BlendMinutelySourceTests;
productName = BlendMinutelySourceTests;
productReference = CDF079DF26D4EBB300E797D9 /* BlendMinutelySourceTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
CDF079CD26D4EBB200E797D9 /* Project object */ = {
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 1250;
LastUpgradeCheck = 1250;
TargetAttributes = {
CDF079D526D4EBB200E797D9 = {
CreatedOnToolsVersion = 12.5.1;
LastSwiftMigration = 1250;
};
CDF079DE26D4EBB300E797D9 = {
CreatedOnToolsVersion = 12.5.1;
};
};
};
buildConfigurationList = CDF079D026D4EBB200E797D9 /* Build configuration list for PBXProject "BlendMinutelySource" */;
compatibilityVersion = "Xcode 9.3";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = CDF079CC26D4EBB200E797D9;
productRefGroup = CDF079D726D4EBB200E797D9 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
CDF079D526D4EBB200E797D9 /* BlendMinutelySource */,
CDF079DE26D4EBB300E797D9 /* BlendMinutelySourceTests */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
CDF079D426D4EBB200E797D9 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
CDF079DD26D4EBB300E797D9 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
CDF079D226D4EBB200E797D9 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
CDF079FC26D4EFED00E797D9 /* BlendMinutelySource.swift in Sources */,
CDF07A0F26D50B4800E797D9 /* BlendMinutelyForecast.swift in Sources */,
CDF07A0E26D50B4800E797D9 /* BlendMinutelyItem.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
CDF079DB26D4EBB300E797D9 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
CDF079E526D4EBB300E797D9 /* BlendMinutelySourceTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
CDF079E226D4EBB300E797D9 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = CDF079D526D4EBB200E797D9 /* BlendMinutelySource */;
targetProxy = CDF079E126D4EBB300E797D9 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin XCBuildConfiguration section */
CDF079E826D4EBB300E797D9 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 14.5;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Debug;
};
CDF079E926D4EBB300E797D9 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 14.5;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
SDKROOT = iphoneos;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
VALIDATE_PRODUCT = YES;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Release;
};
CDF079EB26D4EBB300E797D9 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Automatic;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = 24W4XMQ38L;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
INFOPLIST_FILE = BlendMinutelySource/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 11.4;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.inmobi.BlendMinutelySource;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SKIP_INSTALL = YES;
SUPPORTS_MACCATALYST = NO;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
CDF079EC26D4EBB300E797D9 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Automatic;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = 24W4XMQ38L;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
INFOPLIST_FILE = BlendMinutelySource/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 11.4;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.inmobi.BlendMinutelySource;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SKIP_INSTALL = YES;
SUPPORTS_MACCATALYST = NO;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
};
CDF079EE26D4EBB300E797D9 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = 24W4XMQ38L;
INFOPLIST_FILE = BlendMinutelySourceTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.inmobi.BlendMinutelySourceTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
CDF079EF26D4EBB300E797D9 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = 24W4XMQ38L;
INFOPLIST_FILE = BlendMinutelySourceTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.inmobi.BlendMinutelySourceTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
CDF079D026D4EBB200E797D9 /* Build configuration list for PBXProject "BlendMinutelySource" */ = {
isa = XCConfigurationList;
buildConfigurations = (
CDF079E826D4EBB300E797D9 /* Debug */,
CDF079E926D4EBB300E797D9 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
CDF079EA26D4EBB300E797D9 /* Build configuration list for PBXNativeTarget "BlendMinutelySource" */ = {
isa = XCConfigurationList;
buildConfigurations = (
CDF079EB26D4EBB300E797D9 /* Debug */,
CDF079EC26D4EBB300E797D9 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
CDF079ED26D4EBB300E797D9 /* Build configuration list for PBXNativeTarget "BlendMinutelySourceTests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
CDF079EE26D4EBB300E797D9 /* Debug */,
CDF079EF26D4EBB300E797D9 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = CDF079CD26D4EBB200E797D9 /* Project object */;
}
//
// BlendMinutelySource.h
// BlendMinutelySource
//
// Created by Dmitry Stepanets on 24.08.2021.
//
#import <Foundation/Foundation.h>
//! Project version number for BlendMinutelySource.
FOUNDATION_EXPORT double BlendMinutelySourceVersionNumber;
//! Project version string for BlendMinutelySource.
FOUNDATION_EXPORT const unsigned char BlendMinutelySourceVersionString[];
// In this header, you should import all the public headers of your framework using statements like #import <BlendMinutelySource/PublicHeader.h>
//
// BlendMinutelySource.swift
// BlendMinutelySource
//
// Created by Dmitry Stepanets on 24.08.2021.
//
import Foundation
import OneWeatherCore
public enum BlendMinutelySourceError: Error {
case badUrl
case networkError(Error?)
case badServerResponse(Error?)
case dataEncodingError(String)
case alreadyBeingUpdated
}
public class BlendMinutelySource: MinutelyForecastSource {
//Private
private let kBlendApiKey = "0imfnc8mVLWwsAawjYr4Rx-Af50DDqtlx"
private let kEndpoitURL = "https://pro-1w-dataaggregator.onelouder.com/1weather/api/v1/weather/nowcast"
private let kCountry = "US"
private let kWindUnit = "mph"
private let kPressureUnit = "inHg"
private let kPrecipitationUnit = "inhr"
private let kTempUnit = "F"
private lazy var dateFormatter: DateFormatter = {
let fmt = DateFormatter()
fmt.dateFormat = "yyyy-MM-dd'T'hh:mm:ss.sss'Z'"
return fmt
}()
//Public
public init() {}
public func getMinutelyForecast(forLocation location: Location, completion: @escaping MinutelyForecastCompletion) {
let endpointURL = URL(string: kEndpoitURL)!
let queryItems = [URLQueryItem(name: "lat", value: location.lat),
URLQueryItem(name: "lon", value: location.lon),
URLQueryItem(name: "state", value: location.region),
URLQueryItem(name: "country", value: kCountry),
URLQueryItem(name: "city", value: location.cityName),
URLQueryItem(name: "wind_unit", value: kWindUnit),
URLQueryItem(name: "pressure_unit", value: kPressureUnit),
URLQueryItem(name: "prec_unit", value: kPrecipitationUnit),
URLQueryItem(name: "temp_unit", value: kTempUnit)]
guard var components = URLComponents(url: endpointURL, resolvingAgainstBaseURL: true) else {
completion(.failure(BlendMinutelySourceError.badUrl))
return
}
components.queryItems = queryItems
guard let requestURL = components.url else {
completion(.failure(BlendMinutelySourceError.badUrl))
return
}
var request = URLRequest(url: requestURL)
request.addValue(kBlendApiKey, forHTTPHeaderField: "blend-api-key")
URLSession.shared.dataTask(with: request) {[weak self] data, response, error in
guard let self = self else {
completion(.failure(BlendMinutelySourceError.dataEncodingError("Missing self")))
return
}
if let networkError = error {
completion(.failure(BlendMinutelySourceError.networkError(networkError)))
return
}
guard let forecastData = data else {
completion(.failure(BlendMinutelySourceError.dataEncodingError("Incoming data is invalid")))
return
}
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
decoder.dateDecodingStrategy = .formatted(self.dateFormatter)
do {
let blendForecast = try decoder.decode(BlendMinutelyForecast.self, from: forecastData)
let forecast = MinutelyForecast(lastUpdateTime: Date(),
forecastInterval: blendForecast.forecastInterval,
tempUnit: blendForecast.tempUnit,
windUnit: blendForecast.windUnit,
pressureUnit: blendForecast.pressureUnit,
forecast: blendForecast.forecast.map{ MinutelyItem(time: $0.time,
temp: $0.temp,
precipitation: $0.precipitation,
windSpeed: $0.windSpeed,
pressure: $0.pressure) })
completion(.success(forecast))
}
catch {
completion(.failure(BlendMinutelySourceError.dataEncodingError(error.localizedDescription)))
}
}
.resume()
}
}
<?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>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
</dict>
</plist>
//
// BlendMinutelyForecast.swift
// BlendMinutelySource
//
// Created by Dmitry Stepanets on 24.08.2021.
//
import Foundation
import OneWeatherCore
struct BlendMinutelyForecast: Codable {
public let forecastInterval: Int
public let tempUnit: String
public let windUnit: String
public let pressureUnit: String
public let forecast: [BlendMinutelyItem]
}
//
// BlendMinutelyItem.swift
// BlendMinutelySource
//
// Created by Dmitry Stepanets on 24.08.2021.
//
import Foundation
public struct BlendMinutelyItem: Codable {
let time: Date
let temp: Int
let precipitation: Double
let windSpeed: Int
let pressure: Int
}
//
// BlendMinutelySourceTests.swift
// BlendMinutelySourceTests
//
// Created by Dmitry Stepanets on 24.08.2021.
//
import XCTest
@testable import BlendMinutelySource
class BlendMinutelySourceTests: XCTestCase {
override func setUpWithError() throws {
// Put setup code here. This method is called before the invocation of each test method in the class.
}
override func tearDownWithError() throws {
// Put teardown code here. This method is called after the invocation of each test method in the class.
}
func testExample() throws {
// This is an example of a functional test case.
// Use XCTAssert and related functions to verify your tests produce the correct results.
}
func testPerformanceExample() throws {
// This is an example of a performance test case.
self.measure {
// Put the code you want to measure the time of here.
}
}
}
<?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>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>
...@@ -74,6 +74,9 @@ ...@@ -74,6 +74,9 @@
CDD2F8EF2665102B00B48322 /* LocationManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDD2F8EE2665102B00B48322 /* LocationManager.swift */; }; CDD2F8EF2665102B00B48322 /* LocationManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDD2F8EE2665102B00B48322 /* LocationManager.swift */; };
CDD2F8F12665112900B48322 /* DeviceLocationMonitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDD2F8F02665112800B48322 /* DeviceLocationMonitor.swift */; }; CDD2F8F12665112900B48322 /* DeviceLocationMonitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDD2F8F02665112800B48322 /* DeviceLocationMonitor.swift */; };
CDD2F8F62665117400B48322 /* NWSAlertsManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDD2F8F42665117400B48322 /* NWSAlertsManager.swift */; }; CDD2F8F62665117400B48322 /* NWSAlertsManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDD2F8F42665117400B48322 /* NWSAlertsManager.swift */; };
CDF07A0126D5027300E797D9 /* MinutelyForecastSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDF07A0026D5027300E797D9 /* MinutelyForecastSource.swift */; };
CDF07A0526D5032800E797D9 /* MinutelyItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDF07A0326D5032800E797D9 /* MinutelyItem.swift */; };
CDF07A0626D5032800E797D9 /* MinutelyForecast.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDF07A0426D5032800E797D9 /* MinutelyForecast.swift */; };
CDFE458D26566BD50021A29F /* Storage.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDFE458C26566BD50021A29F /* Storage.swift */; }; CDFE458D26566BD50021A29F /* Storage.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDFE458C26566BD50021A29F /* Storage.swift */; };
CDFE459426566D7B0021A29F /* HealthSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDFE459326566D7B0021A29F /* HealthSource.swift */; }; CDFE459426566D7B0021A29F /* HealthSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDFE459326566D7B0021A29F /* HealthSource.swift */; };
CDFE459626566D860021A29F /* FIPSSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDFE459526566D860021A29F /* FIPSSource.swift */; }; CDFE459626566D860021A29F /* FIPSSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDFE459526566D860021A29F /* FIPSSource.swift */; };
...@@ -174,6 +177,9 @@ ...@@ -174,6 +177,9 @@
CDD2F8EE2665102B00B48322 /* LocationManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationManager.swift; sourceTree = "<group>"; }; CDD2F8EE2665102B00B48322 /* LocationManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationManager.swift; sourceTree = "<group>"; };
CDD2F8F02665112800B48322 /* DeviceLocationMonitor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DeviceLocationMonitor.swift; sourceTree = "<group>"; }; CDD2F8F02665112800B48322 /* DeviceLocationMonitor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DeviceLocationMonitor.swift; sourceTree = "<group>"; };
CDD2F8F42665117400B48322 /* NWSAlertsManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NWSAlertsManager.swift; sourceTree = "<group>"; }; CDD2F8F42665117400B48322 /* NWSAlertsManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NWSAlertsManager.swift; sourceTree = "<group>"; };
CDF07A0026D5027300E797D9 /* MinutelyForecastSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MinutelyForecastSource.swift; sourceTree = "<group>"; };
CDF07A0326D5032800E797D9 /* MinutelyItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MinutelyItem.swift; sourceTree = "<group>"; };
CDF07A0426D5032800E797D9 /* MinutelyForecast.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MinutelyForecast.swift; sourceTree = "<group>"; };
CDFE458C26566BD50021A29F /* Storage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Storage.swift; sourceTree = "<group>"; }; CDFE458C26566BD50021A29F /* Storage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Storage.swift; sourceTree = "<group>"; };
CDFE459326566D7B0021A29F /* HealthSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HealthSource.swift; sourceTree = "<group>"; }; CDFE459326566D7B0021A29F /* HealthSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HealthSource.swift; sourceTree = "<group>"; };
CDFE459526566D860021A29F /* FIPSSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FIPSSource.swift; sourceTree = "<group>"; }; CDFE459526566D860021A29F /* FIPSSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FIPSSource.swift; sourceTree = "<group>"; };
...@@ -363,6 +369,7 @@ ...@@ -363,6 +369,7 @@
CD615F912655269200B717DB /* Health */, CD615F912655269200B717DB /* Health */,
CD615F932655269200B717DB /* Notifications */, CD615F932655269200B717DB /* Notifications */,
CD3883EA2657B82A0070FD6F /* FIPS */, CD3883EA2657B82A0070FD6F /* FIPS */,
CDF07A0226D502F500E797D9 /* Minutely */,
CD427D1A266F5F0500B4350A /* Shorts */, CD427D1A266F5F0500B4350A /* Shorts */,
); );
path = ModelObjects; path = ModelObjects;
...@@ -439,6 +446,15 @@ ...@@ -439,6 +446,15 @@
path = Managers; path = Managers;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
CDF07A0226D502F500E797D9 /* Minutely */ = {
isa = PBXGroup;
children = (
CDF07A0426D5032800E797D9 /* MinutelyForecast.swift */,
CDF07A0326D5032800E797D9 /* MinutelyItem.swift */,
);
path = Minutely;
sourceTree = "<group>";
};
CDFE458B26566BC20021A29F /* Storage */ = { CDFE458B26566BC20021A29F /* Storage */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
...@@ -457,6 +473,7 @@ ...@@ -457,6 +473,7 @@
CDFE459526566D860021A29F /* FIPSSource.swift */, CDFE459526566D860021A29F /* FIPSSource.swift */,
CDFE459326566D7B0021A29F /* HealthSource.swift */, CDFE459326566D7B0021A29F /* HealthSource.swift */,
CD427D18266F5DCE00B4350A /* ShortsSource.swift */, CD427D18266F5DCE00B4350A /* ShortsSource.swift */,
CDF07A0026D5027300E797D9 /* MinutelyForecastSource.swift */,
); );
path = Sources; path = Sources;
sourceTree = "<group>"; sourceTree = "<group>";
...@@ -645,6 +662,7 @@ ...@@ -645,6 +662,7 @@
CDD2F8F12665112900B48322 /* DeviceLocationMonitor.swift in Sources */, CDD2F8F12665112900B48322 /* DeviceLocationMonitor.swift in Sources */,
CD2D55D626553384007B70F4 /* UserDefaultsValue.swift in Sources */, CD2D55D626553384007B70F4 /* UserDefaultsValue.swift in Sources */,
CD550FBA265531A100257FB5 /* RadarLayer.swift in Sources */, CD550FBA265531A100257FB5 /* RadarLayer.swift in Sources */,
CDF07A0626D5032800E797D9 /* MinutelyForecast.swift in Sources */,
CD550FBB265531A100257FB5 /* RadarLayerType.swift in Sources */, CD550FBB265531A100257FB5 /* RadarLayerType.swift in Sources */,
CDBC243F2656740E00F9F4E2 /* AppData.swift in Sources */, CDBC243F2656740E00F9F4E2 /* AppData.swift in Sources */,
CD550FBC265531A100257FB5 /* WeatherLayerType.swift in Sources */, CD550FBC265531A100257FB5 /* WeatherLayerType.swift in Sources */,
...@@ -661,6 +679,7 @@ ...@@ -661,6 +679,7 @@
CD91685726552FAE00EC04EF /* MulticastDelegate.swift in Sources */, CD91685726552FAE00EC04EF /* MulticastDelegate.swift in Sources */,
CDFE458D26566BD50021A29F /* Storage.swift in Sources */, CDFE458D26566BD50021A29F /* Storage.swift in Sources */,
CD615FBD2655295C00B717DB /* Measurement+String.swift in Sources */, CD615FBD2655295C00B717DB /* Measurement+String.swift in Sources */,
CDF07A0526D5032800E797D9 /* MinutelyItem.swift in Sources */,
CD615FBE2655295C00B717DB /* Calendar+TimeZone.swift in Sources */, CD615FBE2655295C00B717DB /* Calendar+TimeZone.swift in Sources */,
CD71B9C6265E629D00803DBB /* String+NewLine.swift in Sources */, CD71B9C6265E629D00803DBB /* String+NewLine.swift in Sources */,
CD91685F26552FEC00EC04EF /* Global.swift in Sources */, CD91685F26552FEC00EC04EF /* Global.swift in Sources */,
...@@ -676,6 +695,7 @@ ...@@ -676,6 +695,7 @@
CD427D19266F5DCE00B4350A /* ShortsSource.swift in Sources */, CD427D19266F5DCE00B4350A /* ShortsSource.swift in Sources */,
CD2D55D8265533F4007B70F4 /* UserDefaultsWrapper.swift in Sources */, CD2D55D8265533F4007B70F4 /* UserDefaultsWrapper.swift in Sources */,
CDD2F8F62665117400B48322 /* NWSAlertsManager.swift in Sources */, CDD2F8F62665117400B48322 /* NWSAlertsManager.swift in Sources */,
CDF07A0126D5027300E797D9 /* MinutelyForecastSource.swift in Sources */,
CE3A112726CD3CDE00D925C7 /* UserDefaults+OneWeather.swift in Sources */, CE3A112726CD3CDE00D925C7 /* UserDefaults+OneWeather.swift in Sources */,
CD11AFE726651BF900EC4BA0 /* LegacyWdtLocation.swift in Sources */, CD11AFE726651BF900EC4BA0 /* LegacyWdtLocation.swift in Sources */,
CD11AFE326651B6300EC4BA0 /* LegacyMigrationManager.swift in Sources */, CD11AFE326651B6300EC4BA0 /* LegacyMigrationManager.swift in Sources */,
......
...@@ -23,6 +23,7 @@ public class LocationManager { ...@@ -23,6 +23,7 @@ public class LocationManager {
private let weatherUpdateSource: WeatherSource private let weatherUpdateSource: WeatherSource
private let healthSource: HealthSource private let healthSource: HealthSource
private let minutelyForecastSource: MinutelyForecastSource
private let fipsSource: FIPSSource private let fipsSource: FIPSSource
public let nwsAlertsManager: NWSAlertsManager public let nwsAlertsManager: NWSAlertsManager
private var pushNotificationsManager: PushNotificationsManagerProtocol? private var pushNotificationsManager: PushNotificationsManagerProtocol?
...@@ -209,9 +210,10 @@ public class LocationManager { ...@@ -209,9 +210,10 @@ public class LocationManager {
!locations.isEmpty || deviceLocationMonitor.hasLocationPermissions !locations.isEmpty || deviceLocationMonitor.hasLocationPermissions
} }
public init(weatherUpdateSource: WeatherSource, healthSource: HealthSource, nwsAlertsManager: NWSAlertsManager, fipsSource: FIPSSource, pushNotificationsManager: PushNotificationsManagerProtocol?, storage: Storage) { public init(weatherUpdateSource: WeatherSource, healthSource: HealthSource, minutelyForecastSource: MinutelyForecastSource, nwsAlertsManager: NWSAlertsManager, fipsSource: FIPSSource, pushNotificationsManager: PushNotificationsManagerProtocol?, storage: Storage) {
self.weatherUpdateSource = weatherUpdateSource self.weatherUpdateSource = weatherUpdateSource
self.healthSource = healthSource self.healthSource = healthSource
self.minutelyForecastSource = minutelyForecastSource
self.deviceLocationMonitor = DeviceLocationMonitor() self.deviceLocationMonitor = DeviceLocationMonitor()
self.nwsAlertsManager = nwsAlertsManager self.nwsAlertsManager = nwsAlertsManager
self.fipsSource = fipsSource self.fipsSource = fipsSource
...@@ -301,6 +303,7 @@ public class LocationManager { ...@@ -301,6 +303,7 @@ public class LocationManager {
log.info("Update all: update default location if needed.") log.info("Update all: update default location if needed.")
updateWeather(for: defaultLocation, updateType: .full) updateWeather(for: defaultLocation, updateType: .full)
updateHealth(for: defaultLocation) updateHealth(for: defaultLocation)
updateMinutelyForecast(for: defaultLocation)
return return
} }
log.info("Update all \(locations.count) locations if needed...") log.info("Update all \(locations.count) locations if needed...")
...@@ -312,6 +315,7 @@ public class LocationManager { ...@@ -312,6 +315,7 @@ public class LocationManager {
updateWeather(for: location, updateType: .preferIncremental) updateWeather(for: location, updateType: .preferIncremental)
} }
updateHealth(for: location) updateHealth(for: location)
updateMinutelyForecast(for: location)
updateNotifications(for: location) updateNotifications(for: location)
getFipsIfNeeded(for: location) getFipsIfNeeded(for: location)
} }
...@@ -369,6 +373,12 @@ public class LocationManager { ...@@ -369,6 +373,12 @@ public class LocationManager {
} }
} }
public func updateMinutelyForecast(for location: Location) {
minutelyForecastSource.getMinutelyForecast(forLocation: location) { result in
print("Break")
}
}
public func updateNotifications(for location: Location) { public func updateNotifications(for location: Location) {
if let lastTimeUpdated = location.notifications?.updatedAt { if let lastTimeUpdated = location.notifications?.updatedAt {
guard Date().timeIntervalSince(lastTimeUpdated) >= nwsAlertsManager.updateInterval else { guard Date().timeIntervalSince(lastTimeUpdated) >= nwsAlertsManager.updateInterval else {
......
...@@ -47,6 +47,7 @@ public struct Location { ...@@ -47,6 +47,7 @@ public struct Location {
public var today: CurrentWeather? public var today: CurrentWeather?
public var daily = [DailyWeather]() public var daily = [DailyWeather]()
public var minutely: MinutelyForecast?
public var hourly = [HourlyWeather]() { public var hourly = [HourlyWeather]() {
didSet { didSet {
let calendar = Calendar.timeZoneCalendar(timeZone: self.timeZone) let calendar = Calendar.timeZoneCalendar(timeZone: self.timeZone)
......
//
// MinutelyForecast.swift
// OneWeatherCore
//
// Created by Dmitry Stepanets on 24.08.2021.
//
import Foundation
public struct MinutelyForecast: Codable {
public let lastUpdateTime: Date
public let forecastInterval: Int
public let tempUnit: Temperature
public let windUnit: WindSpeed
public let pressureUnit: Pressure
public let forecast: [MinutelyItem]
public init(lastUpdateTime: Date, forecastInterval: Int, tempUnit: Temperature, windUnit: WindSpeed, pressureUnit: Pressure, forecast: [MinutelyItem]) {
self.lastUpdateTime = lastUpdateTime
self.forecastInterval = forecastInterval
self.tempUnit = tempUnit
self.windUnit = windUnit
self.pressureUnit = pressureUnit
self.forecast = forecast
}
}
//
// MinutelyItem.swift
// OneWeatherCore
//
// Created by Dmitry Stepanets on 24.08.2021.
//
import Foundation
public struct MinutelyItem: Codable {
let time: Date
let temp: Int
let precipitation: Double
let windSpeed: Int
let pressure: Int
public init(time: Date, temp: Int, precipitation: Double, windSpeed: Int, pressure: Int) {
self.time = time
self.temp = temp
self.precipitation = precipitation
self.windSpeed = windSpeed
self.pressure = pressure
}
}
//
// MinutelyForecastSource.swift
// OneWeatherCore
//
// Created by Dmitry Stepanets on 24.08.2021.
//
import Foundation
public typealias MinutelyForecastCompletion = (_ result: Result<MinutelyForecast, Error>) -> ()
public protocol MinutelyForecastSource {
func getMinutelyForecast(forLocation location: Location, completion: @escaping MinutelyForecastCompletion)
}
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