diff --git a/Assets.sketch b/Assets.sketch index b52227c..7882fca 100644 Binary files a/Assets.sketch and b/Assets.sketch differ diff --git a/MeteoLV.xcodeproj/project.pbxproj b/MeteoLV.xcodeproj/project.pbxproj index ad326f9..d925e3a 100644 --- a/MeteoLV.xcodeproj/project.pbxproj +++ b/MeteoLV.xcodeproj/project.pbxproj @@ -30,6 +30,12 @@ 636EC0FF244B37FF004E42A9 /* MeteoLVProvider in Frameworks */ = {isa = PBXBuildFile; productRef = 636EC0FE244B37FF004E42A9 /* MeteoLVProvider */; }; 636EC101244B3EB3004E42A9 /* MeteoLVProvider in Frameworks */ = {isa = PBXBuildFile; productRef = 636EC100244B3EB3004E42A9 /* MeteoLVProvider */; }; 6375AB5C236D740400B1D8F4 /* MeteoLV.xctestplan in Resources */ = {isa = PBXBuildFile; fileRef = 6375AB5B236D740400B1D8F4 /* MeteoLV.xctestplan */; }; + 63761DAF244C38260013E993 /* ListingTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63761DAE244C38260013E993 /* ListingTableViewController.swift */; }; + 63761DB7244C3D060013E993 /* ShareViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63761DB6244C3D060013E993 /* ShareViewController.swift */; }; + 63761DBA244C3D060013E993 /* MainInterface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 63761DB8244C3D060013E993 /* MainInterface.storyboard */; }; + 63761DBE244C3D060013E993 /* MeteoLVShare.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 63761DB4244C3D060013E993 /* MeteoLVShare.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + 63761DC2244C41DC0013E993 /* Localized.strings in Resources */ = {isa = PBXBuildFile; fileRef = 639F3EA1243A696100DF33E5 /* Localized.strings */; }; + 63761DC3244C41EC0013E993 /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 639F3EA3243A698900DF33E5 /* Extensions.swift */; }; 638E119821860AFC00F20159 /* Coordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 638E119721860AFC00F20159 /* Coordinator.swift */; }; 638E119A21860B2700F20159 /* Storyboarded.swift in Sources */ = {isa = PBXBuildFile; fileRef = 638E119921860B2700F20159 /* Storyboarded.swift */; }; 638E119C21860B5E00F20159 /* MapViewCooordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 638E119B21860B5E00F20159 /* MapViewCooordinator.swift */; }; @@ -53,6 +59,13 @@ remoteGlobalIDString = 63059D41244B1AE2003BF03A; remoteInfo = MeteoLVTodayNotification; }; + 63761DBC244C3D060013E993 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6300DC7D2039ED7D007C268C /* Project object */; + proxyType = 1; + remoteGlobalIDString = 63761DB3244C3D060013E993; + remoteInfo = MeteoLVShare; + }; 63E0991D203A0C3A00959498 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 6300DC7D2039ED7D007C268C /* Project object */; @@ -70,6 +83,7 @@ dstSubfolderSpec = 13; files = ( 63059D4F244B1AE2003BF03A /* Weather Latvia.appex in Embed App Extensions */, + 63761DBE244C3D060013E993 /* MeteoLVShare.appex in Embed App Extensions */, ); name = "Embed App Extensions"; runOnlyForDeploymentPostprocessing = 0; @@ -102,6 +116,11 @@ 635524F3205E5E6700EC0E23 /* InfoViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InfoViewController.swift; sourceTree = ""; }; 636EC0F7244B3218004E42A9 /* Weather Latvia.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "Weather Latvia.entitlements"; sourceTree = ""; }; 6375AB5B236D740400B1D8F4 /* MeteoLV.xctestplan */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = MeteoLV.xctestplan; sourceTree = ""; }; + 63761DAE244C38260013E993 /* ListingTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListingTableViewController.swift; sourceTree = ""; }; + 63761DB4244C3D060013E993 /* MeteoLVShare.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = MeteoLVShare.appex; sourceTree = BUILT_PRODUCTS_DIR; }; + 63761DB6244C3D060013E993 /* ShareViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareViewController.swift; sourceTree = ""; }; + 63761DB9244C3D060013E993 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/MainInterface.storyboard; sourceTree = ""; }; + 63761DBB244C3D060013E993 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 638E119721860AFC00F20159 /* Coordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Coordinator.swift; sourceTree = ""; }; 638E119921860B2700F20159 /* Storyboarded.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Storyboarded.swift; sourceTree = ""; }; 638E119B21860B5E00F20159 /* MapViewCooordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapViewCooordinator.swift; sourceTree = ""; }; @@ -138,6 +157,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 63761DB1244C3D060013E993 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 63E09915203A0C3900959498 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -154,6 +180,7 @@ 6300DC872039ED7D007C268C /* MeteoLV */, 63E09919203A0C3A00959498 /* MeteoLVUITests */, 63059D46244B1AE2003BF03A /* MeteoLVTodayNotification */, + 63761DB5244C3D060013E993 /* MeteoLVShare */, 63059D43244B1AE2003BF03A /* Frameworks */, 6300DC862039ED7D007C268C /* Products */, ); @@ -165,6 +192,7 @@ 6300DC852039ED7D007C268C /* MeteoLV.app */, 63E09918203A0C3900959498 /* MeteoLVUITests.xctest */, 63059D42244B1AE2003BF03A /* Weather Latvia.appex */, + 63761DB4244C3D060013E993 /* MeteoLVShare.appex */, ); name = Products; sourceTree = ""; @@ -210,6 +238,7 @@ 63059D38244B1094003BF03A /* List */ = { isa = PBXGroup; children = ( + 63761DAE244C38260013E993 /* ListingTableViewController.swift */, 639F3E9B243A5D2B00DF33E5 /* ListTableViewController.swift */, ); path = List; @@ -276,6 +305,16 @@ path = Storyboards; sourceTree = ""; }; + 63761DB5244C3D060013E993 /* MeteoLVShare */ = { + isa = PBXGroup; + children = ( + 63761DB6244C3D060013E993 /* ShareViewController.swift */, + 63761DB8244C3D060013E993 /* MainInterface.storyboard */, + 63761DBB244C3D060013E993 /* Info.plist */, + ); + path = MeteoLVShare; + sourceTree = ""; + }; 63E09919203A0C3A00959498 /* MeteoLVUITests */ = { isa = PBXGroup; children = ( @@ -307,6 +346,7 @@ ); dependencies = ( 63059D4E244B1AE2003BF03A /* PBXTargetDependency */, + 63761DBD244C3D060013E993 /* PBXTargetDependency */, ); name = MeteoLV; packageProductDependencies = ( @@ -336,6 +376,23 @@ productReference = 63059D42244B1AE2003BF03A /* Weather Latvia.appex */; productType = "com.apple.product-type.app-extension"; }; + 63761DB3244C3D060013E993 /* MeteoLVShare */ = { + isa = PBXNativeTarget; + buildConfigurationList = 63761DBF244C3D060013E993 /* Build configuration list for PBXNativeTarget "MeteoLVShare" */; + buildPhases = ( + 63761DB0244C3D060013E993 /* Sources */, + 63761DB1244C3D060013E993 /* Frameworks */, + 63761DB2244C3D060013E993 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = MeteoLVShare; + productName = MeteoLVShare; + productReference = 63761DB4244C3D060013E993 /* MeteoLVShare.appex */; + productType = "com.apple.product-type.app-extension"; + }; 63E09917203A0C3900959498 /* MeteoLVUITests */ = { isa = PBXNativeTarget; buildConfigurationList = 63E0991F203A0C3A00959498 /* Build configuration list for PBXNativeTarget "MeteoLVUITests" */; @@ -371,6 +428,9 @@ 63059D41244B1AE2003BF03A = { CreatedOnToolsVersion = 11.4.1; }; + 63761DB3244C3D060013E993 = { + CreatedOnToolsVersion = 11.4.1; + }; 63E09917203A0C3900959498 = { CreatedOnToolsVersion = 9.2; LastSwiftMigration = 1010; @@ -399,6 +459,7 @@ 6300DC842039ED7D007C268C /* MeteoLV */, 63E09917203A0C3900959498 /* MeteoLVUITests */, 63059D41244B1AE2003BF03A /* MeteoLVTodayNotification */, + 63761DB3244C3D060013E993 /* MeteoLVShare */, ); }; /* End PBXProject section */ @@ -421,11 +482,20 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 63761DC2244C41DC0013E993 /* Localized.strings in Resources */, 63059D54244B2AB6003BF03A /* Assets.xcassets in Resources */, 63059D4B244B1AE2003BF03A /* MainInterface.storyboard in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; + 63761DB2244C3D060013E993 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 63761DBA244C3D060013E993 /* MainInterface.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 63E09916203A0C3900959498 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -466,6 +536,7 @@ 631E462421BBEFB2000CC546 /* ObservationsViewController+Map.swift in Sources */, 6300DC9B2039EF16007C268C /* ObservationsViewController.swift in Sources */, 63D4718E243BA7CA00077406 /* FavoritesViewCoordinator.swift in Sources */, + 63761DAF244C38260013E993 /* ListingTableViewController.swift in Sources */, 63D47190243BA83000077406 /* ListCoordinatorProtocol.swift in Sources */, 6300DC892039ED7D007C268C /* AppDelegate.swift in Sources */, 635524F4205E5E6700EC0E23 /* InfoViewController.swift in Sources */, @@ -485,6 +556,15 @@ buildActionMask = 2147483647; files = ( 63059D48244B1AE2003BF03A /* TodayViewController.swift in Sources */, + 63761DC3244C41EC0013E993 /* Extensions.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 63761DB0244C3D060013E993 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 63761DB7244C3D060013E993 /* ShareViewController.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -506,6 +586,11 @@ target = 63059D41244B1AE2003BF03A /* MeteoLVTodayNotification */; targetProxy = 63059D4D244B1AE2003BF03A /* PBXContainerItemProxy */; }; + 63761DBD244C3D060013E993 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 63761DB3244C3D060013E993 /* MeteoLVShare */; + targetProxy = 63761DBC244C3D060013E993 /* PBXContainerItemProxy */; + }; 63E0991E203A0C3A00959498 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 6300DC842039ED7D007C268C /* MeteoLV */; @@ -538,6 +623,14 @@ name = MainInterface.storyboard; sourceTree = ""; }; + 63761DB8244C3D060013E993 /* MainInterface.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 63761DB9244C3D060013E993 /* Base */, + ); + name = MainInterface.storyboard; + sourceTree = ""; + }; 639F3EA1243A696100DF33E5 /* Localized.strings */ = { isa = PBXVariantGroup; children = ( @@ -584,7 +677,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = "iPhone Developer"; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1.8.200418.1842; + CURRENT_PROJECT_VERSION = 1.9.200419.1133; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; @@ -646,7 +739,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = "iPhone Developer"; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1.8.200418.1842; + CURRENT_PROJECT_VERSION = 1.9.200419.1133; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; @@ -675,7 +768,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_ENTITLEMENTS = MeteoLV/MeteoLV.entitlements; CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 1.8.200418.1842; + CURRENT_PROJECT_VERSION = 1.9.200419.1133; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = 3SGNZQGS68; INFOPLIST_FILE = MeteoLV/Info.plist; @@ -702,7 +795,7 @@ CODE_SIGN_ENTITLEMENTS = MeteoLV/MeteoLV.entitlements; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 1.8.200418.1842; + CURRENT_PROJECT_VERSION = 1.9.200419.1133; DEVELOPMENT_TEAM = 3SGNZQGS68; INFOPLIST_FILE = MeteoLV/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 11.0; @@ -725,7 +818,7 @@ buildSettings = { CLANG_ENABLE_OBJC_WEAK = YES; CODE_SIGN_ENTITLEMENTS = "MeteoLVTodayNotification/Weather Latvia.entitlements"; - CODE_SIGN_IDENTITY = "iPhone Distribution"; + CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Manual; DEVELOPMENT_TEAM = 3SGNZQGS68; INFOPLIST_FILE = MeteoLVTodayNotification/Info.plist; @@ -740,7 +833,7 @@ MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.fassko.MeteoLV.MeteoLVTodayNotification; PRODUCT_NAME = "Weather Latvia"; - PROVISIONING_PROFILE_SPECIFIER = "match AppStore com.fassko.MeteoLV.MeteoLVTodayNotification"; + PROVISIONING_PROFILE_SPECIFIER = "match Development com.fassko.MeteoLV.MeteoLVTodayNotification"; SKIP_INSTALL = YES; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; @@ -773,6 +866,55 @@ }; name = Release; }; + 63761DC0244C3D060013E993 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Manual; + DEVELOPMENT_TEAM = 3SGNZQGS68; + INFOPLIST_FILE = MeteoLVShare/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 13.4; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = com.fassko.MeteoLV.MeteoLVShare; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = "match Development com.fassko.MeteoLV.MeteoLVShare"; + SKIP_INSTALL = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 63761DC1244C3D060013E993 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = YES; + CODE_SIGN_IDENTITY = "iPhone Distribution"; + CODE_SIGN_STYLE = Manual; + DEVELOPMENT_TEAM = 3SGNZQGS68; + INFOPLIST_FILE = MeteoLVShare/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 13.4; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = com.fassko.MeteoLV.MeteoLVShare; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = "match AppStore com.fassko.MeteoLV.MeteoLVShare"; + SKIP_INSTALL = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; 63E09920203A0C3A00959498 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -847,6 +989,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 63761DBF244C3D060013E993 /* Build configuration list for PBXNativeTarget "MeteoLVShare" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 63761DC0244C3D060013E993 /* Debug */, + 63761DC1244C3D060013E993 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 63E0991F203A0C3A00959498 /* Build configuration list for PBXNativeTarget "MeteoLVUITests" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/MeteoLV.xcodeproj/xcuserdata/kristaps.xcuserdatad/xcschemes/xcschememanagement.plist b/MeteoLV.xcodeproj/xcuserdata/kristaps.xcuserdatad/xcschemes/xcschememanagement.plist index be1e7f8..d43e8cc 100644 --- a/MeteoLV.xcodeproj/xcuserdata/kristaps.xcuserdatad/xcschemes/xcschememanagement.plist +++ b/MeteoLV.xcodeproj/xcuserdata/kristaps.xcuserdatad/xcschemes/xcschememanagement.plist @@ -9,6 +9,11 @@ orderHint 0 + MeteoLVShare.xcscheme_^#shared#^_ + + orderHint + 2 + MeteoLVTodayNotification.xcscheme_^#shared#^_ orderHint diff --git a/MeteoLV/Assets.xcassets/home-full.imageset/home-full.pdf b/MeteoLV/Assets.xcassets/home-full.imageset/home-full.pdf index 40c2105..04e4b5f 100644 Binary files a/MeteoLV/Assets.xcassets/home-full.imageset/home-full.pdf and b/MeteoLV/Assets.xcassets/home-full.imageset/home-full.pdf differ diff --git a/MeteoLV/Assets.xcassets/home.imageset/home.pdf b/MeteoLV/Assets.xcassets/home.imageset/home.pdf index 2b8aa4a..b0c1d7c 100644 Binary files a/MeteoLV/Assets.xcassets/home.imageset/home.pdf and b/MeteoLV/Assets.xcassets/home.imageset/home.pdf differ diff --git a/MeteoLV/Core/MapViewCooordinator.swift b/MeteoLV/Core/MapViewCooordinator.swift index c30ca97..4d30f94 100644 --- a/MeteoLV/Core/MapViewCooordinator.swift +++ b/MeteoLV/Core/MapViewCooordinator.swift @@ -30,7 +30,7 @@ class MapViewCooordinator: Coordinator { navigationController.pushViewController(stationViewController, animated: true) } - func showInfo() { + func showInfo() { let infoViewController = InfoViewController.instantiate() navigationController.pushViewController(infoViewController, animated: true) } diff --git a/MeteoLV/Favorites/FavoritesTableViewController.swift b/MeteoLV/Favorites/FavoritesTableViewController.swift index 548ff28..2fc30ec 100644 --- a/MeteoLV/Favorites/FavoritesTableViewController.swift +++ b/MeteoLV/Favorites/FavoritesTableViewController.swift @@ -26,6 +26,7 @@ class FavoritesTableViewController: ListingTableViewController, Storyboarded { DispatchQueue.main.async { self?.tableView.reloadData() + self?.refreshControl?.endRefreshing() } case let .failure(error): os_log("%s", log: OSLog.standard, type: OSLogType.error, error.localizedDescription) diff --git a/MeteoLV/Info.plist b/MeteoLV/Info.plist index 03ca648..27d5f8b 100644 --- a/MeteoLV/Info.plist +++ b/MeteoLV/Info.plist @@ -17,9 +17,22 @@ CFBundlePackageType APPL CFBundleShortVersionString - 1.8 + 1.10 + CFBundleURLTypes + + + CFBundleTypeRole + Viewer + CFBundleURLName + + CFBundleURLSchemes + + weatherLatvia + + + CFBundleVersion - 1.7.200405.2256 + 1.9.200419.1133 Fabric APIKey diff --git a/MeteoLV/List/ListTableViewController.swift b/MeteoLV/List/ListTableViewController.swift index 295069a..fcffcf9 100644 --- a/MeteoLV/List/ListTableViewController.swift +++ b/MeteoLV/List/ListTableViewController.swift @@ -9,63 +9,6 @@ import UIKit import os.log -import MeteoLVProvider - -class ListingTableViewController: UITableViewController { - - var stations = [ObservationStation]() - var coordinator: ListCoordinatorProtocol? - let meteoDataProvider = MeteoLVProvider() - - override func viewDidLoad() { - super.viewDidLoad() - - navigationItem.rightBarButtonItem = UIBarButtonItem( - barButtonSystemItem: .refresh, - target: self, - action: #selector(executeLoadData)) - } - - override func viewDidAppear(_ animated: Bool) { - super.viewDidAppear(animated) - executeLoadData() - } - - @objc private func executeLoadData() { - loadData() - } - - func loadData() { - } - - override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - stations.count - } - - override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { - let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) - - switch stations[indexPath.row] { - case .meteo(let meteoStation): - cell.textLabel?.text = meteoStation.name - cell.detailTextLabel?.text = meteoStation.temperature - case .road(let lvRoadStation): - cell.textLabel?.text = lvRoadStation.name - cell.detailTextLabel?.text = lvRoadStation.temperature - } - - return cell - } - - override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { - let station = stations[indexPath.row] - coordinator?.showObservationStation(station) - } - - func navigate(with station: ObservationStation) { - } -} - class ListTableViewController: ListingTableViewController, Storyboarded { override func viewDidLoad() { super.viewDidLoad() @@ -83,6 +26,7 @@ class ListTableViewController: ListingTableViewController, Storyboarded { DispatchQueue.main.async { self?.tableView.reloadData() + self?.refreshControl?.endRefreshing() } case let .failure(error): os_log("%s", log: OSLog.standard, type: OSLogType.error, error.localizedDescription) diff --git a/MeteoLV/List/ListingTableViewController.swift b/MeteoLV/List/ListingTableViewController.swift new file mode 100644 index 0000000..1e0413c --- /dev/null +++ b/MeteoLV/List/ListingTableViewController.swift @@ -0,0 +1,83 @@ +// +// ListingTableViewController.swift +// MeteoLV +// +// Created by Kristaps Grinbergs on 19/04/2020. +// Copyright © 2020 fassko. All rights reserved. +// + +import Foundation +import UIKit + +import MeteoLVProvider + +class ListingTableViewController: UITableViewController { + + var stations = [ObservationStation]() + var coordinator: ListCoordinatorProtocol? + let meteoDataProvider = MeteoLVProvider() + + override func viewDidLoad() { + super.viewDidLoad() + + addRefreshControl() + + navigationItem.rightBarButtonItem = UIBarButtonItem( + barButtonSystemItem: .refresh, + target: self, + action: #selector(executeLoadData)) + } + + private func addRefreshControl() { + refreshControl = UIRefreshControl() + guard let refreshControl = self.refreshControl else { + return + } + + refreshControl.addTarget(self, action: #selector(executeLoadData), for: .valueChanged) + tableView.addSubview(refreshControl) + } + + override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + executeLoadData() + } + + @objc private func executeLoadData() { + loadData() + } + + func loadData() { + } + + override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + stations.count + } + + override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { + UITableView.automaticDimension + } + + override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) + + switch stations[indexPath.row] { + case .meteo(let meteoStation): + cell.textLabel?.text = meteoStation.name + cell.detailTextLabel?.text = meteoStation.temperature + case .road(let lvRoadStation): + cell.textLabel?.text = lvRoadStation.name + cell.detailTextLabel?.text = lvRoadStation.temperature + } + + return cell + } + + override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + let station = stations[indexPath.row] + coordinator?.showObservationStation(station) + } + + func navigate(with station: ObservationStation) { + } +} diff --git a/MeteoLV/StationView/StationViewController.swift b/MeteoLV/StationView/StationViewController.swift index 96b7a3e..89418af 100644 --- a/MeteoLV/StationView/StationViewController.swift +++ b/MeteoLV/StationView/StationViewController.swift @@ -40,6 +40,16 @@ extension StationViewController { } } + @IBAction func share(_ sender: Any) { + guard let temperature = station.temperature, let wind = station.wind else { + return + } + + let text = "\(station.name) \(temperature) \(wind)" + let activityViewController = UIActivityViewController(activityItems: [text], applicationActivities: nil) + navigationController?.present(activityViewController, animated: true, completion: {}) + } + private func updateFavoriteButton() { UIView.animate(withDuration: 0.5) { [weak self] in self?.favoriteButton.image = self?.station.isFavorited ?? false ? .favoritesFull : .favorites @@ -68,4 +78,8 @@ extension StationViewController { return cell } + + override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { + UITableView.automaticDimension + } } diff --git a/MeteoLV/Storyboards/Base.lproj/Main.storyboard b/MeteoLV/Storyboards/Base.lproj/Main.storyboard index 237aca2..d1ca19c 100644 --- a/MeteoLV/Storyboards/Base.lproj/Main.storyboard +++ b/MeteoLV/Storyboards/Base.lproj/Main.storyboard @@ -1,5 +1,5 @@ - + @@ -94,23 +94,23 @@ - + - + @@ -135,6 +135,11 @@ + + + + + @@ -164,16 +169,16 @@ @@ -208,16 +213,16 @@ @@ -230,6 +235,10 @@ + + + + @@ -239,6 +248,6 @@ - + diff --git a/MeteoLV/en.lproj/Localized.strings b/MeteoLV/en.lproj/Localized.strings index 62f96be..46d82f0 100644 --- a/MeteoLV/en.lproj/Localized.strings +++ b/MeteoLV/en.lproj/Localized.strings @@ -2,4 +2,5 @@ "List" = "List"; "Info" = "Info"; "Favorites" = "Favorites"; +"Please set your Home location." = "Please set your Home location."; "Weather Latvia shows current weather observations in Latvia. Data comes from Latvian Environment, Geology and Meteorology Centre and Latvian State Roads.\n\nApp is maintained by Kristaps Grinbergs and open sourced at https://github.com/fassko/MeteoLV" = "Weather Latvia shows current weather observations in Latvia. Data comes from Latvian Environment, Geology and Meteorology Centre and Latvian State Roads.\n\nApp is maintained by Kristaps Grinbergs and open sourced at https://github.com/fassko/MeteoLV"; diff --git a/MeteoLV/lv.lproj/Localized.strings b/MeteoLV/lv.lproj/Localized.strings index 865cd20..afdef1f 100644 --- a/MeteoLV/lv.lproj/Localized.strings +++ b/MeteoLV/lv.lproj/Localized.strings @@ -2,4 +2,5 @@ "List" = "Saraksts"; "Info" = "Info"; "Favorites" = "Favorīti"; +"Please set your Home location." = "Lūdzu, norādiet savu Mājas vietu."; "Weather Latvia shows current weather observations in Latvia. Data comes from Latvian Environment, Geology and Meteorology Centre and Latvian State Roads.\n\nApp is maintained by Kristaps Grinbergs and open sourced at https://github.com/fassko/MeteoLV" = "Weather Latvia shows current weather observations in Latvia. Data comes from Latvian Environment, Geology and Meteorology Centre and Latvian State Roads.\n\nApp is maintained by Kristaps Grinbergs and open sourced at https://github.com/fassko/MeteoLV"; diff --git a/MeteoLVShare/Base.lproj/MainInterface.storyboard b/MeteoLVShare/Base.lproj/MainInterface.storyboard new file mode 100644 index 0000000..286a508 --- /dev/null +++ b/MeteoLVShare/Base.lproj/MainInterface.storyboard @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/MeteoLVShare/Info.plist b/MeteoLVShare/Info.plist new file mode 100644 index 0000000..2cfe38f --- /dev/null +++ b/MeteoLVShare/Info.plist @@ -0,0 +1,39 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleDisplayName + MeteoLVShare + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.10 + CFBundleVersion + 1.9.200419.1133 + NSExtension + + NSExtensionAttributes + + NSExtensionActivationRule + + NSExtensionActivationSupportsText + + + + NSExtensionMainStoryboard + MainInterface + NSExtensionPointIdentifier + com.apple.share-services + + + diff --git a/MeteoLVShare/ShareViewController.swift b/MeteoLVShare/ShareViewController.swift new file mode 100644 index 0000000..b25bab9 --- /dev/null +++ b/MeteoLVShare/ShareViewController.swift @@ -0,0 +1,25 @@ +// +// ShareViewController.swift +// MeteoLVShare +// +// Created by Kristaps Grinbergs on 19/04/2020. +// Copyright © 2020 fassko. All rights reserved. +// + +import UIKit +import Social + +class ShareViewController: SLComposeServiceViewController { + + override func isContentValid() -> Bool { + return true + } + + override func didSelectPost() { + self.extensionContext!.completeRequest(returningItems: [], completionHandler: nil) + } + + override func configurationItems() -> [Any]! { + return [] + } +} diff --git a/MeteoLVTodayNotification/Base.lproj/MainInterface.storyboard b/MeteoLVTodayNotification/Base.lproj/MainInterface.storyboard index 4cf3c51..d83cbcd 100644 --- a/MeteoLVTodayNotification/Base.lproj/MainInterface.storyboard +++ b/MeteoLVTodayNotification/Base.lproj/MainInterface.storyboard @@ -64,12 +64,32 @@ + + + + + + + + + + @@ -77,7 +97,9 @@ + + diff --git a/MeteoLVTodayNotification/Info.plist b/MeteoLVTodayNotification/Info.plist index bee2b83..676c5a2 100644 --- a/MeteoLVTodayNotification/Info.plist +++ b/MeteoLVTodayNotification/Info.plist @@ -17,9 +17,9 @@ CFBundlePackageType $(PRODUCT_BUNDLE_PACKAGE_TYPE) CFBundleShortVersionString - 1.8 + 1.10 CFBundleVersion - 1 + 1.9.200419.1133 NSAppTransportSecurity NSAllowsArbitraryLoads diff --git a/MeteoLVTodayNotification/TodayViewController.swift b/MeteoLVTodayNotification/TodayViewController.swift index 8346158..cbecbec 100644 --- a/MeteoLVTodayNotification/TodayViewController.swift +++ b/MeteoLVTodayNotification/TodayViewController.swift @@ -14,14 +14,27 @@ import MeteoLVProvider class TodayViewController: UIViewController, NCWidgetProviding { + @IBOutlet weak var containerStackView: UIStackView! @IBOutlet weak var locationName: UILabel! @IBOutlet weak var temperatureLabel: UILabel! @IBOutlet weak var windLabel: UILabel! + @IBOutlet weak var setHomeLocationLabel: UILabel! + private let meteoDataProvider = MeteoLVProvider() override func viewDidLoad() { super.viewDidLoad() + + setHomeLocationLabel.text = "Please set your Home location.".localized + } + + @IBAction func openApp(_ sender: AnyObject) { + guard let appURL = URL(string: "weatherLatvia://home") else { + return + } + + extensionContext?.open(appURL) } func widgetPerformUpdate(completionHandler: (@escaping (NCUpdateResult) -> Void)) { @@ -31,6 +44,8 @@ class TodayViewController: UIViewController, NCWidgetProviding { guard let userDefaults = UserDefaults(suiteName: "group.com.fassko.MeteoLV"), let home = userDefaults.string(forKey: "home") else { + containerStackView.isHidden = true + setHomeLocationLabel.isHidden = false completionHandler(.noData) return } @@ -47,6 +62,8 @@ class TodayViewController: UIViewController, NCWidgetProviding { self?.locationName.text = homeStation.name self?.temperatureLabel.text = homeStation.temperature self?.windLabel.text = homeStation.wind + self?.containerStackView.isHidden = false + self?.setHomeLocationLabel.isHidden = true completionHandler(NCUpdateResult.newData) case let .failure(error): diff --git a/MeteoLVUITests/Info.plist b/MeteoLVUITests/Info.plist index cdaa5b2..917ba3d 100644 --- a/MeteoLVUITests/Info.plist +++ b/MeteoLVUITests/Info.plist @@ -15,8 +15,8 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 1.8 + 1.10 CFBundleVersion - 1.7.200405.2256 + 1.9.200419.1133 diff --git a/fastlane/.github/workflows/main.yml b/fastlane/.github/workflows/main.yml index ea0a50a..4f2739b 100644 --- a/fastlane/.github/workflows/main.yml +++ b/fastlane/.github/workflows/main.yml @@ -3,7 +3,7 @@ name: Build and test Weather Latvia on: push env: - DEVELOPER_DIR: /Applications/Xcode_11.4.app/Contents/Developer + DEVELOPER_DIR: /Applications/Xcode_11.5.app/Contents/Developer jobs: build: diff --git a/fastlane/Matchfile b/fastlane/Matchfile index 7d96bdc..9859155 100644 --- a/fastlane/Matchfile +++ b/fastlane/Matchfile @@ -2,5 +2,9 @@ git_url "https://fassko@bitbucket.org/fassko/certificates" type "development" -app_identifier ["com.fassko.MeteoLV", "com.fassko.MeteoLVUITests", "com.fassko.MeteoLV.MeteoLVTodayNotification"] +app_identifier ["com.fassko.MeteoLV", + "com.fassko.MeteoLVUITests", + "com.fassko.MeteoLV.MeteoLVTodayNotification", + "com.fassko.MeteoLV.MeteoLVShare"] + username "fassko@gmail.com" diff --git a/fastlane/Snapfile b/fastlane/Snapfile index d89f9ae..317f83f 100644 --- a/fastlane/Snapfile +++ b/fastlane/Snapfile @@ -12,4 +12,4 @@ scheme "MeteoLV" clear_previous_screenshots true -workspace "./MeteoLV.xcworkspace" +project "./MeteoLV.xcodeproj" diff --git a/fastlane/SnapshotHelper.swift b/fastlane/SnapshotHelper.swift index aaa2a9a..04b0ddc 100644 --- a/fastlane/SnapshotHelper.swift +++ b/fastlane/SnapshotHelper.swift @@ -38,22 +38,13 @@ func snapshot(_ name: String, timeWaitingForIdle timeout: TimeInterval = 20) { } enum SnapshotError: Error, CustomDebugStringConvertible { - case cannotDetectUser - case cannotFindHomeDirectory case cannotFindSimulatorHomeDirectory - case cannotAccessSimulatorHomeDirectory(String) case cannotRunOnPhysicalDevice var debugDescription: String { switch self { - case .cannotDetectUser: - return "Couldn't find Snapshot configuration files - can't detect current user " - case .cannotFindHomeDirectory: - return "Couldn't find Snapshot configuration files - can't detect `Users` dir" case .cannotFindSimulatorHomeDirectory: return "Couldn't find simulator home location. Please, check SIMULATOR_HOST_HOME env variable." - case .cannotAccessSimulatorHomeDirectory(let simulatorHostHome): - return "Can't prepare environment. Simulator home location is inaccessible. Does \(simulatorHostHome) exist?" case .cannotRunOnPhysicalDevice: return "Can't use Snapshot on a physical device." } @@ -75,7 +66,7 @@ open class Snapshot: NSObject { Snapshot.waitForAnimations = waitForAnimations do { - let cacheDir = try pathPrefix() + let cacheDir = try getCacheDirectory() Snapshot.cacheDirectory = cacheDir setLanguage(app) setLocale(app) @@ -206,34 +197,22 @@ open class Snapshot: NSObject { _ = XCTWaiter.wait(for: [networkLoadingIndicatorDisappeared], timeout: timeout) } - class func pathPrefix() throws -> URL? { - let homeDir: URL + class func getCacheDirectory() throws -> URL { + let cachePath = "Library/Caches/tools.fastlane" // on OSX config is stored in /Users//Library // and on iOS/tvOS/WatchOS it's in simulator's home dir #if os(OSX) - guard let user = ProcessInfo().environment["USER"] else { - throw SnapshotError.cannotDetectUser + let homeDir = URL(fileURLWithPath: NSHomeDirectory()) + return homeDir.appendingPathComponent(cachePath) + #elseif arch(i386) || arch(x86_64) + guard let simulatorHostHome = ProcessInfo().environment["SIMULATOR_HOST_HOME"] else { + throw SnapshotError.cannotFindSimulatorHomeDirectory } - - guard let usersDir = FileManager.default.urls(for: .userDirectory, in: .localDomainMask).first else { - throw SnapshotError.cannotFindHomeDirectory - } - - homeDir = usersDir.appendingPathComponent(user) + let homeDir = URL(fileURLWithPath: simulatorHostHome) + return homeDir.appendingPathComponent(cachePath) #else - #if arch(i386) || arch(x86_64) - guard let simulatorHostHome = ProcessInfo().environment["SIMULATOR_HOST_HOME"] else { - throw SnapshotError.cannotFindSimulatorHomeDirectory - } - guard let homeDirUrl = URL(string: simulatorHostHome) else { - throw SnapshotError.cannotAccessSimulatorHomeDirectory(simulatorHostHome) - } - homeDir = URL(fileURLWithPath: homeDirUrl.path) - #else - throw SnapshotError.cannotRunOnPhysicalDevice - #endif + throw SnapshotError.cannotRunOnPhysicalDevice #endif - return homeDir.appendingPathComponent("Library/Caches/tools.fastlane") } } @@ -300,4 +279,4 @@ private extension CGFloat { // Please don't remove the lines below // They are used to detect outdated configuration files -// SnapshotHelperVersion [1.21] +// SnapshotHelperVersion [1.22]