From bb82bc90e3d5c6dcc7e98800389e0c64762cae8a Mon Sep 17 00:00:00 2001 From: Matteo Matassoni <4108197+matax87@users.noreply.github.com> Date: Mon, 12 Aug 2024 17:38:27 +0200 Subject: [PATCH 1/5] Adds Crashlytics and secret Developer Menu --- NOICommunity.xcodeproj/project.pbxproj | 60 ++++--- .../DeveloperToolsCoordinator.swift | 31 ++++ .../DeveloperToolsViewController.swift | 156 ++++++++++++++++++ .../DeveloperToolsViewModel.swift | 46 ++++++ .../Factories/DependencyContainer.swift | 12 +- .../Factories/ViewControllerFactory.swift | 4 + NOICommunity/Factories/ViewModelFactory.swift | 4 +- NOICommunity/SceneDelegate.swift | 8 +- NOICommunity/Views/BaseWindow.swift | 56 +++++++ 9 files changed, 349 insertions(+), 28 deletions(-) create mode 100644 NOICommunity/DeveloperTools/DeveloperToolsCoordinator.swift create mode 100644 NOICommunity/DeveloperTools/DeveloperToolsViewController.swift create mode 100644 NOICommunity/DeveloperTools/DeveloperToolsViewModel.swift create mode 100644 NOICommunity/Views/BaseWindow.swift diff --git a/NOICommunity.xcodeproj/project.pbxproj b/NOICommunity.xcodeproj/project.pbxproj index 2c66d96..c5bffb4 100644 --- a/NOICommunity.xcodeproj/project.pbxproj +++ b/NOICommunity.xcodeproj/project.pbxproj @@ -160,6 +160,11 @@ 31AD1DB32B279558006F71A4 /* ComeOnBoardOnboardingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31AD1DB02B2791D8006F71A4 /* ComeOnBoardOnboardingViewController.swift */; }; 31AD1DB52B279976006F71A4 /* ComeOnBoardOnboardingCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31AD1DB42B279976006F71A4 /* ComeOnBoardOnboardingCoordinator.swift */; }; 31AD1DB62B279E78006F71A4 /* ComeOnBoardOnboardingViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 31AD1DAE2B2791A4006F71A4 /* ComeOnBoardOnboardingViewController.xib */; }; + 31B1926F2C6A2136009872E9 /* FirebaseCrashlytics in Frameworks */ = {isa = PBXBuildFile; productRef = 31B1926E2C6A2136009872E9 /* FirebaseCrashlytics */; }; + 31B192722C6A367D009872E9 /* DeveloperToolsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31B192712C6A367D009872E9 /* DeveloperToolsViewController.swift */; }; + 31B192742C6A36E4009872E9 /* DeveloperToolsCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31B192732C6A36E4009872E9 /* DeveloperToolsCoordinator.swift */; }; + 31B192762C6A38C2009872E9 /* DeveloperToolsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31B192752C6A38C2009872E9 /* DeveloperToolsViewModel.swift */; }; + 31B192782C6A434B009872E9 /* BaseWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31B192772C6A434B009872E9 /* BaseWindow.swift */; }; 31B3623E26F1E27A00031024 /* UIColor+NOI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31B3623D26F1E27A00031024 /* UIColor+NOI.swift */; }; 31B37E1E2833AFF700C26E6B /* MessageViewController+Error.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31B37E1D2833AFF700C26E6B /* MessageViewController+Error.swift */; }; 31B4477F26F86FE5000999BA /* SegmentedControlBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31B4477E26F86FE4000999BA /* SegmentedControlBuilder.swift */; }; @@ -390,6 +395,10 @@ 31AD1DB02B2791D8006F71A4 /* ComeOnBoardOnboardingViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComeOnBoardOnboardingViewController.swift; sourceTree = ""; }; 31AD1DB12B27947B006F71A4 /* ComeOnBoardOnboardingViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComeOnBoardOnboardingViewModel.swift; sourceTree = ""; }; 31AD1DB42B279976006F71A4 /* ComeOnBoardOnboardingCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComeOnBoardOnboardingCoordinator.swift; sourceTree = ""; }; + 31B192712C6A367D009872E9 /* DeveloperToolsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeveloperToolsViewController.swift; sourceTree = ""; }; + 31B192732C6A36E4009872E9 /* DeveloperToolsCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeveloperToolsCoordinator.swift; sourceTree = ""; }; + 31B192752C6A38C2009872E9 /* DeveloperToolsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeveloperToolsViewModel.swift; sourceTree = ""; }; + 31B192772C6A434B009872E9 /* BaseWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseWindow.swift; sourceTree = ""; }; 31B3623D26F1E27A00031024 /* UIColor+NOI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIColor+NOI.swift"; sourceTree = ""; }; 31B37E1D2833AFF700C26E6B /* MessageViewController+Error.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MessageViewController+Error.swift"; sourceTree = ""; }; 31B4477E26F86FE4000999BA /* SegmentedControlBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SegmentedControlBuilder.swift; sourceTree = ""; }; @@ -466,6 +475,7 @@ 317B6F9C28118BD6008D07C0 /* AuthClient in Frameworks */, 3182F4AC27DB3841005ADDAF /* EventShortTypesClientLive in Frameworks */, 311E0EC62825157800404DCE /* FirebaseMessaging in Frameworks */, + 31B1926F2C6A2136009872E9 /* FirebaseCrashlytics in Frameworks */, 317B6F9E28118BD6008D07C0 /* AuthClientLive in Frameworks */, 317EC889283BB83E00F30B95 /* PeopleClient in Frameworks */, ); @@ -656,6 +666,7 @@ 3145D22F26B3F73F00F16787 /* NOICommunity */ = { isa = PBXGroup; children = ( + 31B192702C6A364E009872E9 /* DeveloperTools */, 3153010228071CF500471153 /* AuthFeature */, 3136CC3E2706F75200C27129 /* Transitions */, 31C640A926FE1389004B71A2 /* Factories */, @@ -875,6 +886,7 @@ 31796C7B2809B489000542F6 /* GradientView.swift */, 313010CE28463F1000AF6520 /* ContentConfiguration.swift */, 318664A12B22471E0088A752 /* LinkTextView.swift */, + 31B192772C6A434B009872E9 /* BaseWindow.swift */, ); path = Views; sourceTree = ""; @@ -924,6 +936,16 @@ path = ComeOnBoardOnboardingFeature; sourceTree = ""; }; + 31B192702C6A364E009872E9 /* DeveloperTools */ = { + isa = PBXGroup; + children = ( + 31B192712C6A367D009872E9 /* DeveloperToolsViewController.swift */, + 31B192732C6A36E4009872E9 /* DeveloperToolsCoordinator.swift */, + 31B192752C6A38C2009872E9 /* DeveloperToolsViewModel.swift */, + ); + path = DeveloperTools; + sourceTree = ""; + }; 31B3623A26F1D62700031024 /* Helpers */ = { isa = PBXGroup; children = ( @@ -1044,7 +1066,6 @@ 3145D22926B3F73F00F16787 /* Sources */, 3145D22A26B3F73F00F16787 /* Frameworks */, 3145D22B26B3F73F00F16787 /* Resources */, - 313FB0B82719C548000AD9DA /* Crashlytics */, ); buildRules = ( ); @@ -1069,6 +1090,7 @@ 317EC888283BB83E00F30B95 /* PeopleClient */, 317EC88A283BB83E00F30B95 /* PeopleClientLive */, 3181B9202B1E12BD000D2A0F /* Core */, + 31B1926E2C6A2136009872E9 /* FirebaseCrashlytics */, ); productName = NOICommunity; productReference = 3145D22D26B3F73F00F16787 /* NOICommunity.app */; @@ -1230,29 +1252,6 @@ }; /* End PBXResourcesBuildPhase section */ -/* Begin PBXShellScriptBuildPhase section */ - 313FB0B82719C548000AD9DA /* Crashlytics */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - "${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}/Contents/Resources/DWARF/${TARGET_NAME}\n", - "$(SRCROOT)/$(BUILT_PRODUCTS_DIR)/$(INFOPLIST_PATH)\n", - ); - name = Crashlytics; - outputFileListPaths = ( - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "if [[ \"${CONFIGURATION}\" == \"Release\" ]]\nthen\n ${BUILD_DIR%Build/*}/SourcePackages/checkouts/firebase-ios-sdk/Crashlytics/run\n echo \"✅ Crashlytics on configuration: ${CONFIGURATION}\"\nelse\n echo \"❌ Crashlytics on configuration: ${CONFIGURATION}\"\nfi\n"; - }; -/* End PBXShellScriptBuildPhase section */ - /* Begin PBXSourcesBuildPhase section */ 3145D22926B3F73F00F16787 /* Sources */ = { isa = PBXSourcesBuildPhase; @@ -1268,6 +1267,7 @@ 31B3623E26F1E27A00031024 /* UIColor+NOI.swift in Sources */, 31892F2E281BC32800DD89F7 /* MyAccountViewModel.swift in Sources */, 3110CF6026F0E89C003B7174 /* CircleView.swift in Sources */, + 31B192762C6A38C2009872E9 /* DeveloperToolsViewModel.swift in Sources */, 31C640AB26FE1397004B71A2 /* DependencyContainer.swift in Sources */, 31157D1B26FCB26200A43B33 /* String+Localization.swift in Sources */, 31AA31EE26F0A94E00744A00 /* IdentifiableCollectionViewCell.swift in Sources */, @@ -1337,6 +1337,7 @@ 3101FC5B283394FA00A3416F /* TodayCoordinator.swift in Sources */, 31C28BF8271992F500312A62 /* FiltersBarView.swift in Sources */, 3145D23326B3F73F00F16787 /* SceneDelegate.swift in Sources */, + 31B192722C6A367D009872E9 /* DeveloperToolsViewController.swift in Sources */, 31AA31E826F09E3600744A00 /* Event.swift in Sources */, 3187667726FB38D600782FA6 /* DateIntervalFormatter+Factory.swift in Sources */, 3102F45F282C06B700687CF7 /* NewsViewController.swift in Sources */, @@ -1365,6 +1366,7 @@ 3102F45A282C03D300687CF7 /* NewsDetailsViewModel.swift in Sources */, 31B37E1E2833AFF700C26E6B /* MessageViewController+Error.swift in Sources */, 315275672847A01000D5C8A1 /* PersonId.swift in Sources */, + 31B192742C6A36E4009872E9 /* DeveloperToolsCoordinator.swift in Sources */, 31C640C626FE1E43004B71A2 /* MeetMainViewController.swift in Sources */, 31C640C526FE1E43004B71A2 /* MeetCoordinator.swift in Sources */, 31AAC053270F2FFD00C26850 /* FooterView.swift in Sources */, @@ -1373,6 +1375,7 @@ 313010CF28463F1000AF6520 /* ContentConfiguration.swift in Sources */, 3185AA15281FEAE900767E31 /* AccessNotGrantedViewController.swift in Sources */, 317B6FA428118C95008D07C0 /* DependencyRepresentable.swift in Sources */, + 31B192782C6A434B009872E9 /* BaseWindow.swift in Sources */, 31927A8127464E2800EA96AC /* RootCoordinator.swift in Sources */, 31C6409F26FE0B73004B71A2 /* OrientateCoordinator.swift in Sources */, 3152755F28476D4B00D5C8A1 /* CompanyViewModel.swift in Sources */, @@ -1593,6 +1596,7 @@ "$(inherited)", "@executable_path/Frameworks", ); + OTHER_LDFLAGS = "-ObjC"; PRODUCT_BUNDLE_IDENTIFIER = "it.dimension.noi-community"; PRODUCT_NAME = "${TARGET_NAME}"; PROVISIONING_PROFILE_SPECIFIER = "Noi Community Dev"; @@ -1615,6 +1619,7 @@ "$(inherited)", "@executable_path/Frameworks", ); + OTHER_LDFLAGS = "-ObjC"; PRODUCT_BUNDLE_IDENTIFIER = it.bz.noi.community; PRODUCT_NAME = "${TARGET_NAME}"; PROVISIONING_PROFILE_SPECIFIER = it.bz.noi.community; @@ -1783,6 +1788,7 @@ "$(inherited)", "@executable_path/Frameworks", ); + OTHER_LDFLAGS = "-ObjC"; PRODUCT_BUNDLE_IDENTIFIER = "it.dimension.noi-community"; PRODUCT_NAME = "${TARGET_NAME}"; PROVISIONING_PROFILE_SPECIFIER = "Noi Community Dev"; @@ -1904,6 +1910,7 @@ "$(inherited)", "@executable_path/Frameworks", ); + OTHER_LDFLAGS = "-ObjC"; PRODUCT_BUNDLE_IDENTIFIER = it.bz.noi.community; PRODUCT_NAME = "${TARGET_NAME}"; PROVISIONING_PROFILE_SPECIFIER = it.bz.noi.community; @@ -2096,6 +2103,11 @@ isa = XCSwiftPackageProductDependency; productName = ArticlesClientLive; }; + 31B1926E2C6A2136009872E9 /* FirebaseCrashlytics */ = { + isa = XCSwiftPackageProductDependency; + package = 311E0EC42825157800404DCE /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; + productName = FirebaseCrashlytics; + }; 31CE9BF52701BF33005EA61A /* Kingfisher */ = { isa = XCSwiftPackageProductDependency; package = 31CE9BF42701BF33005EA61A /* XCRemoteSwiftPackageReference "Kingfisher" */; diff --git a/NOICommunity/DeveloperTools/DeveloperToolsCoordinator.swift b/NOICommunity/DeveloperTools/DeveloperToolsCoordinator.swift new file mode 100644 index 0000000..a76f45a --- /dev/null +++ b/NOICommunity/DeveloperTools/DeveloperToolsCoordinator.swift @@ -0,0 +1,31 @@ +// SPDX-FileCopyrightText: NOI Techpark +// +// SPDX-License-Identifier: AGPL-3.0-or-later + +// +// DeveloperToolsCoordinator.swift +// NOICommunity +// +// Created by Matteo Matassoni on 12/08/24. +// + +import Foundation + +final class DeveloperToolsCoordinator: BaseNavigationCoordinator { + + override func start(animated: Bool) { + let developerToolsViewModel = dependencyContainer.makeDeveloperToolsViewModel() + let developerToolsViewController = dependencyContainer.makeDeveloperToolsViewController( + viewModel: developerToolsViewModel + ) + developerToolsViewController.title = "Developer Tools" + navigationController.setViewControllers( + [developerToolsViewController], + animated: animated + ) + } + + func dismiss(animated: Bool) { + navigationController.dismiss(animated: animated) + } +} diff --git a/NOICommunity/DeveloperTools/DeveloperToolsViewController.swift b/NOICommunity/DeveloperTools/DeveloperToolsViewController.swift new file mode 100644 index 0000000..2449710 --- /dev/null +++ b/NOICommunity/DeveloperTools/DeveloperToolsViewController.swift @@ -0,0 +1,156 @@ +// SPDX-FileCopyrightText: NOI Techpark +// +// SPDX-License-Identifier: AGPL-3.0-or-later + +// +// DeveloperToolsViewController.swift +// NOICommunity +// +// Created by Matteo Matassoni on 12/08/24. +// + +import UIKit +import Combine + +class DeveloperToolsViewController: UICollectionViewController { + + private var viewModel: DeveloperToolsViewModel! + private var subscriptions: Set = [] + private var dataSource: UICollectionViewDiffableDataSource! = nil + + init(viewModel: DeveloperToolsViewModel) { + self.viewModel = viewModel + super.init(collectionViewLayout: UICollectionViewFlowLayout()) + } + + @available(*, unavailable) + required init?(coder: NSCoder) { + fatalError("\(#function) not available") + } + + @available(*, unavailable) + override init( + collectionViewLayout layout: UICollectionViewLayout + ) { + fatalError("\(#function) not available") + } + + @available(*, unavailable) + override init( + nibName nibNameOrNil: String?, + bundle nibBundleOrNil: Bundle? + ) { + fatalError("\(#function) not available") + } + + @available(*, unavailable) + init() { + fatalError("\(#function) not available") + } + + override func viewDidLoad() { + super.viewDidLoad() + + configureCollectionView() + configureDataSource() + configureBindings() + } + +} + +// MARK: Private APIs +extension DeveloperToolsViewController { + + override func collectionView( + _ collectionView: UICollectionView, + didSelectItemAt indexPath: IndexPath + ) { + guard let selectedOption = dataSource.itemIdentifier(for: indexPath) + else { return } + + viewModel.perform(option: selectedOption) + } +} + +// MARK: Private APIs + +private extension DeveloperToolsViewController { + + enum Section: Hashable { + case main + } + + func configureLayout() { + var config = UICollectionLayoutListConfiguration(appearance: .plain) + config.backgroundColor = .noiSecondaryBackgroundColor + if #available(iOS 14.5, *) { + config.itemSeparatorHandler = { [weak collectionView] indexPath, sectionSeparatorConfiguration in + guard let collectionView + else { return sectionSeparatorConfiguration } + + var configuration = sectionSeparatorConfiguration + if collectionView.isLastIndexPathInItsSection(indexPath) { + configuration.bottomSeparatorVisibility = .hidden + } + return configuration + } + } + collectionView.collectionViewLayout = UICollectionViewCompositionalLayout.list(using: config) + } + + func configureDataSource() { + let cellRegistration = UICollectionView.CellRegistration + { cell, _, option in + var contentConfiguration = UIListContentConfiguration.noiCell() + contentConfiguration.text = option.rawValue + cell.contentConfiguration = contentConfiguration + + cell.backgroundConfiguration = .noiListPlainCell(for: cell) + + cell.accessories = [.noiDisclosureIndicator()] + } + + dataSource = .init( + collectionView: collectionView + ) { collectionView, indexPath, item in + collectionView.dequeueConfiguredReusableCell( + using: cellRegistration, + for: indexPath, + item: item + ) + } + + setInitialSnapshot() + } + + func configureBindings() { + viewModel.$options + .sink { [weak self] newOptions in + self?.updateUI(options: newOptions) + } + .store(in: &subscriptions) + } + + func configureCollectionView() { + collectionView.backgroundColor = .clear + configureLayout() + } + + func updateUI(options: [DeveloperToolsOption]) { + let isOnScreen = viewIfLoaded?.window != nil + updateUI(options: options, animated: isOnScreen) + } + + func updateUI(options: [DeveloperToolsOption], animated: Bool) { + var snapshot = NSDiffableDataSourceSnapshot() + snapshot.appendSections([.main]) + snapshot.appendItems(options, toSection: .main) + dataSource.apply(snapshot, animatingDifferences: animated) + } + + func setInitialSnapshot() { + var snapshot = NSDiffableDataSourceSnapshot() + dataSource.apply(snapshot, animatingDifferences: false) + } +} + diff --git a/NOICommunity/DeveloperTools/DeveloperToolsViewModel.swift b/NOICommunity/DeveloperTools/DeveloperToolsViewModel.swift new file mode 100644 index 0000000..0a76c01 --- /dev/null +++ b/NOICommunity/DeveloperTools/DeveloperToolsViewModel.swift @@ -0,0 +1,46 @@ +// SPDX-FileCopyrightText: NOI Techpark +// +// SPDX-License-Identifier: AGPL-3.0-or-later + +// +// DeveloperToolsViewModel.swift +// NOICommunity +// +// Created by Matteo Matassoni on 12/08/24. +// + +import Foundation + +// MARK: - DeveloperToolsOption + +enum DeveloperToolsOption: String { + case forceCrash = "Force Crash 💥!" +} + +// MARK: - DeveloperToolsViewModel + +final class DeveloperToolsViewModel { + + @Published private(set) var options: [DeveloperToolsOption] = [ + .forceCrash + ] + + func perform(option: DeveloperToolsOption) { + switch option { + case .forceCrash: + forceCrash() + } + } + +} + +// MARK: Private APIs + +private extension DeveloperToolsViewModel { + + + func forceCrash() { + let numbers = [0] + let _ = numbers[1] + } +} diff --git a/NOICommunity/Factories/DependencyContainer.swift b/NOICommunity/Factories/DependencyContainer.swift index 3f997ce..b4f830e 100644 --- a/NOICommunity/Factories/DependencyContainer.swift +++ b/NOICommunity/Factories/DependencyContainer.swift @@ -188,7 +188,11 @@ extension DependencyContainer: ViewModelFactory { func makeComeOnBoardOnboardingViewModel() -> ComeOnBoardOnboardingViewModel { .init(appPreferencesClient: makeAppPreferencesClient()) } - + + func makeDeveloperToolsViewModel() -> DeveloperToolsViewModel { + .init() + } + } // MARK: ViewControllerFactory @@ -261,4 +265,10 @@ extension DependencyContainer: ViewControllerFactory { .init(viewModel: viewModel) } + func makeDeveloperToolsViewController( + viewModel: DeveloperToolsViewModel + ) -> DeveloperToolsViewController { + .init(viewModel: viewModel) + } + } diff --git a/NOICommunity/Factories/ViewControllerFactory.swift b/NOICommunity/Factories/ViewControllerFactory.swift index f249736..53a4150 100644 --- a/NOICommunity/Factories/ViewControllerFactory.swift +++ b/NOICommunity/Factories/ViewControllerFactory.swift @@ -57,4 +57,8 @@ protocol ViewControllerFactory { func makeComeOnBoardOnboardingViewController( viewModel: ComeOnBoardOnboardingViewModel ) -> ComeOnBoardOnboardingViewController + + func makeDeveloperToolsViewController( + viewModel: DeveloperToolsViewModel + ) -> DeveloperToolsViewController } diff --git a/NOICommunity/Factories/ViewModelFactory.swift b/NOICommunity/Factories/ViewModelFactory.swift index c9fe538..aa3d3a3 100644 --- a/NOICommunity/Factories/ViewModelFactory.swift +++ b/NOICommunity/Factories/ViewModelFactory.swift @@ -37,5 +37,7 @@ protocol ViewModelFactory { func makePeopleViewModel() -> PeopleViewModel func makeComeOnBoardOnboardingViewModel() -> ComeOnBoardOnboardingViewModel - + + func makeDeveloperToolsViewModel() -> DeveloperToolsViewModel + } diff --git a/NOICommunity/SceneDelegate.swift b/NOICommunity/SceneDelegate.swift index ad202c2..0ace6c4 100644 --- a/NOICommunity/SceneDelegate.swift +++ b/NOICommunity/SceneDelegate.swift @@ -91,8 +91,12 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate { // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). guard let windowScene = (scene as? UIWindowScene) else { return } - - let window = UIWindow(windowScene: windowScene) + + let window = { + let window = BaseWindow(windowScene: windowScene) + window.dependencyContainer = dependencyContainer + return window + }() self.window = window rootCoordinator = RootCoordinator( window: window, diff --git a/NOICommunity/Views/BaseWindow.swift b/NOICommunity/Views/BaseWindow.swift new file mode 100644 index 0000000..6311915 --- /dev/null +++ b/NOICommunity/Views/BaseWindow.swift @@ -0,0 +1,56 @@ +// SPDX-FileCopyrightText: NOI Techpark +// +// SPDX-License-Identifier: AGPL-3.0-or-later + +// +// BaseWindow.swift +// NOICommunity +// +// Created by Matteo Matassoni on 12/08/24. +// + +import UIKit + +// MARK: - BaseWindow + +class BaseWindow: UIWindow { + + var dependencyContainer: DependencyRepresentable! + + private var developerToolsCoordinator: DeveloperToolsCoordinator? + + open override func motionEnded(_ motion: UIEvent.EventSubtype, with event: UIEvent?) { + switch motion { + case .motionShake: +#if DEBUG + showDeveloperTools() +#endif + default: + break + } + } +} + +// MARK: Private APIs + +private extension BaseWindow { + +#if DEBUG + func showDeveloperTools() { + developerToolsCoordinator?.dismiss(animated: true) + + guard let rootViewController + else { return } + + let navigationController = UINavigationController() + let developerToolsCoordinator = DeveloperToolsCoordinator( + navigationController: navigationController, + dependencyContainer: dependencyContainer + ) + self.developerToolsCoordinator = developerToolsCoordinator + developerToolsCoordinator.start() + rootViewController.present(navigationController, animated: true) + } +#endif + +} From a2d9d117a776cff54a306ac447250e154cd7e958 Mon Sep 17 00:00:00 2001 From: Matteo Matassoni <4108197+matax87@users.noreply.github.com> Date: Mon, 12 Aug 2024 17:39:34 +0200 Subject: [PATCH 2/5] Adds upload of dSYMs to Firebase Crashlytics to Github workflows --- .github/workflows/main.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index c410380..559a720 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -129,3 +129,12 @@ jobs: -u "$APPLEID_USERNAME" \ -p "$APPLEID_PASSWORD" \ --verbose + + - name: Upload dSYMs to Firebase Crashlytics + if: success() + run: | + BUILD_DIR=$(xcodebuild -showBuildSettings | grep -m 1 "BUILD_DIR" | cut -d'=' -f2) + ${BUILD_DIR%Build/*}/SourcePackages/checkouts/firebase-ios-sdk/Crashlytics/upload-symbols \ + -gsp "NOICommunity/GoogleService-Info.plist" \ + -p ios \ + "$PWD/build/NOICommunity.xcarchive/dSYMs" From c9acbeebfb9df684a6ed3640ff2d60bc570fe74b Mon Sep 17 00:00:00 2001 From: Matteo Matassoni <4108197+matax87@users.noreply.github.com> Date: Tue, 13 Aug 2024 09:24:55 +0200 Subject: [PATCH 3/5] Refactors Developer Menu --- NOICommunity.xcodeproj/project.pbxproj | 256 +++++++++++++++++- .../NOICommunity DEVELOPER_MENU.xcscheme | 98 +++++++ .../NOICommunity TMA DEVELOPER_MENU.xcscheme | 98 +++++++ .../xcschemes/NOICommunity TMA.xcscheme | 98 +++++++ .../DeveloperToolsCoordinator.swift | 5 +- .../DeveloperToolsViewController.swift | 2 +- NOICommunity/Views/BaseWindow.swift | 16 +- 7 files changed, 560 insertions(+), 13 deletions(-) create mode 100644 NOICommunity.xcodeproj/xcshareddata/xcschemes/NOICommunity DEVELOPER_MENU.xcscheme create mode 100644 NOICommunity.xcodeproj/xcshareddata/xcschemes/NOICommunity TMA DEVELOPER_MENU.xcscheme create mode 100644 NOICommunity.xcodeproj/xcshareddata/xcschemes/NOICommunity TMA.xcscheme diff --git a/NOICommunity.xcodeproj/project.pbxproj b/NOICommunity.xcodeproj/project.pbxproj index c5bffb4..8fd7406 100644 --- a/NOICommunity.xcodeproj/project.pbxproj +++ b/NOICommunity.xcodeproj/project.pbxproj @@ -1464,6 +1464,250 @@ /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ + 3118B9052C6B3AAF00954F46 /* Release DEVELOPER_MENU */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + 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; + 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.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEVELOPER_MENU; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = "Release DEVELOPER_MENU"; + }; + 3118B9062C6B3AAF00954F46 /* Release DEVELOPER_MENU */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_ENTITLEMENTS = NOICommunity/NOICommunityRelease.entitlements; + CODE_SIGN_IDENTITY = "iPhone Distribution"; + CODE_SIGN_STYLE = Manual; + DEVELOPMENT_TEAM = 5V2Q9SWB7H; + INFOPLIST_FILE = NOICommunity/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + OTHER_LDFLAGS = "-ObjC"; + PRODUCT_BUNDLE_IDENTIFIER = it.bz.noi.community; + PRODUCT_NAME = "${TARGET_NAME}"; + PROVISIONING_PROFILE_SPECIFIER = it.bz.noi.community; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 1; + }; + name = "Release DEVELOPER_MENU"; + }; + 3118B9072C6B3AAF00954F46 /* Release DEVELOPER_MENU */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = ""; + INFOPLIST_FILE = NOICommunityTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 14.5; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "it.bz.noi.community-test"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/NOICommunity.app/NOICommunity"; + }; + name = "Release DEVELOPER_MENU"; + }; + 3118B9082C6B3AAF00954F46 /* Release DEVELOPER_MENU */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = ""; + INFOPLIST_FILE = NOICommunityUITests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "it.bz.noi.community-uitest"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = NOICommunity; + }; + name = "Release DEVELOPER_MENU"; + }; + 3118B9092C6B3AB900954F46 /* Release TMA DEVELOPER_MENU */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + 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; + 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.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "TESTINGMACHINE_OAUTH DEVELOPER_MENU"; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = "Release TMA DEVELOPER_MENU"; + }; + 3118B90A2C6B3AB900954F46 /* Release TMA DEVELOPER_MENU */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_ENTITLEMENTS = NOICommunity/NOICommunityRelease.entitlements; + CODE_SIGN_IDENTITY = "iPhone Distribution"; + CODE_SIGN_STYLE = Manual; + DEVELOPMENT_TEAM = 5V2Q9SWB7H; + INFOPLIST_FILE = NOICommunity/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + OTHER_LDFLAGS = "-ObjC"; + PRODUCT_BUNDLE_IDENTIFIER = it.bz.noi.community; + PRODUCT_NAME = "${TARGET_NAME}"; + PROVISIONING_PROFILE_SPECIFIER = it.bz.noi.community; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 1; + }; + name = "Release TMA DEVELOPER_MENU"; + }; + 3118B90B2C6B3AB900954F46 /* Release TMA DEVELOPER_MENU */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = ""; + INFOPLIST_FILE = NOICommunityTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 14.5; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "it.bz.noi.community-test"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/NOICommunity.app/NOICommunity"; + }; + name = "Release TMA DEVELOPER_MENU"; + }; + 3118B90C2C6B3AB900954F46 /* Release TMA DEVELOPER_MENU */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = ""; + INFOPLIST_FILE = NOICommunityUITests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "it.bz.noi.community-uitest"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = NOICommunity; + }; + name = "Release TMA DEVELOPER_MENU"; + }; 3145D25526B3F74000F16787 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -1521,7 +1765,7 @@ MTL_FAST_MATH = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG DEVELOPER_MENU"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; }; name = Debug; @@ -1769,7 +2013,7 @@ MTL_FAST_MATH = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG TESTINGMACHINE_OAUTH"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG TESTINGMACHINE_OAUTH DEVELOPER_MENU"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; }; name = "Debug TMA"; @@ -1970,7 +2214,9 @@ 3145D25526B3F74000F16787 /* Debug */, 3185AA1F28201A0000767E31 /* Debug TMA */, 3145D25626B3F74000F16787 /* Release */, + 3118B9052C6B3AAF00954F46 /* Release DEVELOPER_MENU */, 3185AA2328201ABF00767E31 /* Release TMA */, + 3118B9092C6B3AB900954F46 /* Release TMA DEVELOPER_MENU */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -1981,7 +2227,9 @@ 3145D25826B3F74000F16787 /* Debug */, 3185AA2028201A0000767E31 /* Debug TMA */, 3145D25926B3F74000F16787 /* Release */, + 3118B9062C6B3AAF00954F46 /* Release DEVELOPER_MENU */, 3185AA2428201ABF00767E31 /* Release TMA */, + 3118B90A2C6B3AB900954F46 /* Release TMA DEVELOPER_MENU */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -1992,7 +2240,9 @@ 3145D25B26B3F74000F16787 /* Debug */, 3185AA2128201A0000767E31 /* Debug TMA */, 3145D25C26B3F74000F16787 /* Release */, + 3118B9072C6B3AAF00954F46 /* Release DEVELOPER_MENU */, 3185AA2528201ABF00767E31 /* Release TMA */, + 3118B90B2C6B3AB900954F46 /* Release TMA DEVELOPER_MENU */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -2003,7 +2253,9 @@ 3145D25E26B3F74000F16787 /* Debug */, 3185AA2228201A0000767E31 /* Debug TMA */, 3145D25F26B3F74000F16787 /* Release */, + 3118B9082C6B3AAF00954F46 /* Release DEVELOPER_MENU */, 3185AA2628201ABF00767E31 /* Release TMA */, + 3118B90C2C6B3AB900954F46 /* Release TMA DEVELOPER_MENU */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; diff --git a/NOICommunity.xcodeproj/xcshareddata/xcschemes/NOICommunity DEVELOPER_MENU.xcscheme b/NOICommunity.xcodeproj/xcshareddata/xcschemes/NOICommunity DEVELOPER_MENU.xcscheme new file mode 100644 index 0000000..123f1bb --- /dev/null +++ b/NOICommunity.xcodeproj/xcshareddata/xcschemes/NOICommunity DEVELOPER_MENU.xcscheme @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/NOICommunity.xcodeproj/xcshareddata/xcschemes/NOICommunity TMA DEVELOPER_MENU.xcscheme b/NOICommunity.xcodeproj/xcshareddata/xcschemes/NOICommunity TMA DEVELOPER_MENU.xcscheme new file mode 100644 index 0000000..a4473db --- /dev/null +++ b/NOICommunity.xcodeproj/xcshareddata/xcschemes/NOICommunity TMA DEVELOPER_MENU.xcscheme @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/NOICommunity.xcodeproj/xcshareddata/xcschemes/NOICommunity TMA.xcscheme b/NOICommunity.xcodeproj/xcshareddata/xcschemes/NOICommunity TMA.xcscheme new file mode 100644 index 0000000..efb22f2 --- /dev/null +++ b/NOICommunity.xcodeproj/xcshareddata/xcschemes/NOICommunity TMA.xcscheme @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/NOICommunity/DeveloperTools/DeveloperToolsCoordinator.swift b/NOICommunity/DeveloperTools/DeveloperToolsCoordinator.swift index a76f45a..863a4e7 100644 --- a/NOICommunity/DeveloperTools/DeveloperToolsCoordinator.swift +++ b/NOICommunity/DeveloperTools/DeveloperToolsCoordinator.swift @@ -24,8 +24,5 @@ final class DeveloperToolsCoordinator: BaseNavigationCoordinator { animated: animated ) } - - func dismiss(animated: Bool) { - navigationController.dismiss(animated: animated) - } + } diff --git a/NOICommunity/DeveloperTools/DeveloperToolsViewController.swift b/NOICommunity/DeveloperTools/DeveloperToolsViewController.swift index 2449710..670a06a 100644 --- a/NOICommunity/DeveloperTools/DeveloperToolsViewController.swift +++ b/NOICommunity/DeveloperTools/DeveloperToolsViewController.swift @@ -149,7 +149,7 @@ private extension DeveloperToolsViewController { } func setInitialSnapshot() { - var snapshot = NSDiffableDataSourceSnapshot() + let snapshot = NSDiffableDataSourceSnapshot() dataSource.apply(snapshot, animatingDifferences: false) } } diff --git a/NOICommunity/Views/BaseWindow.swift b/NOICommunity/Views/BaseWindow.swift index 6311915..0ad7f5b 100644 --- a/NOICommunity/Views/BaseWindow.swift +++ b/NOICommunity/Views/BaseWindow.swift @@ -20,9 +20,11 @@ class BaseWindow: UIWindow { private var developerToolsCoordinator: DeveloperToolsCoordinator? open override func motionEnded(_ motion: UIEvent.EventSubtype, with event: UIEvent?) { + super.motionEnded(motion, with: event) + switch motion { case .motionShake: -#if DEBUG +#if DEVELOPER_MENU showDeveloperTools() #endif default: @@ -35,13 +37,15 @@ class BaseWindow: UIWindow { private extension BaseWindow { -#if DEBUG - func showDeveloperTools() { - developerToolsCoordinator?.dismiss(animated: true) - +#if DEVELOPER_MENU + func showDeveloperTools(animated: Bool = true) { guard let rootViewController else { return } + let isAlreadyShown = developerToolsCoordinator?.navigationController != nil && rootViewController.presentedViewController == developerToolsCoordinator?.navigationController + guard !isAlreadyShown + else { return } + let navigationController = UINavigationController() let developerToolsCoordinator = DeveloperToolsCoordinator( navigationController: navigationController, @@ -49,7 +53,7 @@ private extension BaseWindow { ) self.developerToolsCoordinator = developerToolsCoordinator developerToolsCoordinator.start() - rootViewController.present(navigationController, animated: true) + rootViewController.present(navigationController, animated: animated) } #endif From adc01a2ba191c5032e7bfeeba752686429320d55 Mon Sep 17 00:00:00 2001 From: Matteo Matassoni <4108197+matax87@users.noreply.github.com> Date: Tue, 13 Aug 2024 09:33:43 +0200 Subject: [PATCH 4/5] Updates documentation of the "Archive the project" CD job with the new available configurations --- .github/workflows/main.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 559a720..185eb33 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -91,8 +91,12 @@ jobs: BUILD_NUMBER=$(date "+%Y%m%d%H%M%S") /usr/libexec/PlistBuddy -c "Set :CFBundleVersion $BUILD_NUMBER" NOICommunity/Info.plist - # Set -configuration to "Release", if you want to use the production Keycloak server - # and to "Release TMA" for the testingmachine-authentication Keycloak server + # Set the -configuration parameter to one of the following options: + # - "Release": uses the production Keycloak server + # - "Release TMA": uses the testingmachine-authentication Keycloak server + # - "Release DEVELOPER_MENU": same as "Release" but includes the Developer Menu + # - "Release TMA DEVELOPER_MENU": same as "Release TMA" but includes the Developer Menu + - name: Archive the project run: | set -eo pipefail From 050855ea467395da7d6c4964154c5e7018c293ac Mon Sep 17 00:00:00 2001 From: Matteo Matassoni <4108197+matax87@users.noreply.github.com> Date: Tue, 13 Aug 2024 10:45:31 +0200 Subject: [PATCH 5/5] Improves modal presentation of Development Menu --- .../DeveloperToolsCoordinator.swift | 23 ++++++++++++++++++- NOICommunity/Views/BaseWindow.swift | 3 ++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/NOICommunity/DeveloperTools/DeveloperToolsCoordinator.swift b/NOICommunity/DeveloperTools/DeveloperToolsCoordinator.swift index 863a4e7..0d22084 100644 --- a/NOICommunity/DeveloperTools/DeveloperToolsCoordinator.swift +++ b/NOICommunity/DeveloperTools/DeveloperToolsCoordinator.swift @@ -10,6 +10,9 @@ // import Foundation +import UIKit + +// MARK: - DeveloperToolsCoordinator final class DeveloperToolsCoordinator: BaseNavigationCoordinator { @@ -18,11 +21,29 @@ final class DeveloperToolsCoordinator: BaseNavigationCoordinator { let developerToolsViewController = dependencyContainer.makeDeveloperToolsViewController( viewModel: developerToolsViewModel ) + developerToolsViewController.navigationItem.leftBarButtonItem = UIBarButtonItem( + image: UIImage(systemName: "xmark.circle.fill"), + style: .plain, + target: self, + action: #selector(didTapClose(_:)) + ) developerToolsViewController.title = "Developer Tools" navigationController.setViewControllers( [developerToolsViewController], animated: animated ) } - + + func dismiss(animated: Bool) { + navigationController.dismiss(animated: animated) + } +} + +// MARK: Private APIs + +private extension DeveloperToolsCoordinator { + + @objc func didTapClose(_ sender: Any?) { + dismiss(animated: true) + } } diff --git a/NOICommunity/Views/BaseWindow.swift b/NOICommunity/Views/BaseWindow.swift index 0ad7f5b..61664e4 100644 --- a/NOICommunity/Views/BaseWindow.swift +++ b/NOICommunity/Views/BaseWindow.swift @@ -46,7 +46,8 @@ private extension BaseWindow { guard !isAlreadyShown else { return } - let navigationController = UINavigationController() + let navigationController = NavigationController() + navigationController.modalPresentationStyle = .fullScreen let developerToolsCoordinator = DeveloperToolsCoordinator( navigationController: navigationController, dependencyContainer: dependencyContainer