From c17f8d276a198fca6ae335b3e05d7e206602b34e Mon Sep 17 00:00:00 2001 From: Gianni Carlo Date: Fri, 27 Sep 2024 21:41:29 -0500 Subject: [PATCH] Add swift format rules --- .swift-format | 10 ++ .swiftlint.yml | 1 + BookPlayer.xcodeproj/project.pbxproj | 4 + BookPlayer/AppDelegate.swift | 241 +++++++++++++++++---------- 4 files changed, 165 insertions(+), 91 deletions(-) create mode 100644 .swift-format diff --git a/.swift-format b/.swift-format new file mode 100644 index 00000000..d0f97b7a --- /dev/null +++ b/.swift-format @@ -0,0 +1,10 @@ +{ + "version": 1, + "lineLength": 120, + "indentation": { + "spaces": 2 + }, + "maximumBlankLines": 1, + "lineBreakBeforeEachArgument": true, + "prioritizeKeepingFunctionOutputTogether": true +} diff --git a/.swiftlint.yml b/.swiftlint.yml index babd5d0b..1168e047 100644 --- a/.swiftlint.yml +++ b/.swiftlint.yml @@ -19,3 +19,4 @@ disabled_rules: - file_length - orphaned_doc_comment - large_tuple + - opening_brace diff --git a/BookPlayer.xcodeproj/project.pbxproj b/BookPlayer.xcodeproj/project.pbxproj index e1b3dabb..8456e623 100644 --- a/BookPlayer.xcodeproj/project.pbxproj +++ b/BookPlayer.xcodeproj/project.pbxproj @@ -382,6 +382,7 @@ 638E64CC2B8E086400DCFA3B /* RealmManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 638E64CA2B8E086400DCFA3B /* RealmManager.swift */; }; 638E64CE2B8E1CFD00DCFA3B /* SyncTasksCountService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 638E64CD2B8E1CFD00DCFA3B /* SyncTasksCountService.swift */; }; 638E64CF2B8E1CFD00DCFA3B /* SyncTasksCountService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 638E64CD2B8E1CFD00DCFA3B /* SyncTasksCountService.swift */; }; + 6397206F2CA71D600045A4DB /* .swift-format in Resources */ = {isa = PBXBuildFile; fileRef = 6397206E2CA71D600045A4DB /* .swift-format */; }; 6399F94D2AA03C6C00A5C8EA /* BPSKANManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6399F94C2AA03C6C00A5C8EA /* BPSKANManager.swift */; }; 639AC9892AD9F1D50053AFC6 /* BPDownloadURLSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = 639AC9882AD9F1D50053AFC6 /* BPDownloadURLSession.swift */; }; 639AC98A2AD9F1D50053AFC6 /* BPDownloadURLSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = 639AC9882AD9F1D50053AFC6 /* BPDownloadURLSession.swift */; }; @@ -1158,6 +1159,7 @@ 63833DF92AAC139700496246 /* PlaybackPerformanceTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlaybackPerformanceTests.swift; sourceTree = ""; }; 638E64CA2B8E086400DCFA3B /* RealmManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RealmManager.swift; sourceTree = ""; }; 638E64CD2B8E1CFD00DCFA3B /* SyncTasksCountService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SyncTasksCountService.swift; sourceTree = ""; }; + 6397206E2CA71D600045A4DB /* .swift-format */ = {isa = PBXFileReference; lastKnownFileType = text; path = ".swift-format"; sourceTree = ""; }; 6399F94C2AA03C6C00A5C8EA /* BPSKANManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BPSKANManager.swift; sourceTree = ""; }; 639AC9882AD9F1D50053AFC6 /* BPDownloadURLSession.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BPDownloadURLSession.swift; sourceTree = ""; }; 639E12C52B85AACF00C875F7 /* SyncTasksObject.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SyncTasksObject.swift; sourceTree = ""; }; @@ -2740,6 +2742,7 @@ C35BADE7206989E6007687C1 /* LICENSE */, C35BADE9206989E6007687C1 /* .swiftlint.yml */, C3EA7175218DEC870005D488 /* .swiftformat */, + 6397206E2CA71D600045A4DB /* .swift-format */, ); name = Meta; sourceTree = ""; @@ -3183,6 +3186,7 @@ 41AD3D9A221C737F00DC41E1 /* retro-icon@2x.png in Resources */, 419B373F23B8D14100128A8F /* LoadingView.xib in Resources */, 9F665EDE2A4898F6004BFE27 /* heart-of-glass-ayu@2x.png in Resources */, + 6397206F2CA71D600045A4DB /* .swift-format in Resources */, C3EA7176218DEC870005D488 /* .swiftformat in Resources */, 41E562FC2239535D00C06BC9 /* neon-ipad@2x.png in Resources */, 41E562D222394F5A00C06BC9 /* dark@2x.png in Resources */, diff --git a/BookPlayer/AppDelegate.swift b/BookPlayer/AppDelegate.swift index 76dc9339..bddec417 100644 --- a/BookPlayer/AppDelegate.swift +++ b/BookPlayer/AppDelegate.swift @@ -14,9 +14,9 @@ import CoreData import DirectoryWatcher import Intents import MediaPlayer -import Sentry import RealmSwift import RevenueCat +import Sentry import StoreKit import UIKit import WatchConnectivity @@ -44,7 +44,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate, BPLogger { if let scene = UIApplication.shared.connectedScenes.first( where: { $0.activationState == .foregroundActive } ) as? UIWindowScene, - let delegate = scene.delegate as? SceneDelegate { + let delegate = scene.delegate as? SceneDelegate + { return delegate } else { return lastSceneToResignActive @@ -54,9 +55,13 @@ class AppDelegate: UIResponder, UIApplicationDelegate, BPLogger { private var crashReportsAccessObserver: NSKeyValueObservation? private var sharedWidgetActionURLObserver: NSKeyValueObservation? /// Background refresh task identifier - private lazy var refreshTaskIdentifier = "\(Bundle.main.configurationString(for: .bundleIdentifier)).background.refresh" + private lazy var refreshTaskIdentifier = + "\(Bundle.main.configurationString(for: .bundleIdentifier)).background.refresh" - func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + func application( + _ application: UIApplication, + didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? + ) -> Bool { Self.shared = self NotificationCenter.default.addObserver( @@ -84,7 +89,11 @@ class AppDelegate: UIResponder, UIApplicationDelegate, BPLogger { return true } - func application(_ application: UIApplication, handle intent: INIntent, completionHandler: @escaping (INIntentResponse) -> Void) { + func application( + _ application: UIApplication, + handle intent: INIntent, + completionHandler: @escaping (INIntentResponse) -> Void + ) { let response: INPlayMediaIntentResponse do { try ActionParserService.process(intent) @@ -196,14 +205,21 @@ class AppDelegate: UIResponder, UIApplicationDelegate, BPLogger { let fileURL = DataManager.getProcessedFolderURL().appendingPathComponent(relativePath) if syncService?.isActive == false, - !FileManager.default.fileExists(atPath: fileURL.path) { - alertPresenter.showAlert("file_missing_title".localized, message: "\("file_missing_description".localized)\n\(fileURL.lastPathComponent)", completion: nil) + !FileManager.default.fileExists(atPath: fileURL.path) + { + alertPresenter.showAlert( + "file_missing_title".localized, + message: + "\("file_missing_description".localized)\n\(fileURL.lastPathComponent)", + completion: nil + ) return } // Only load if loaded book is a different one if playerManager?.hasLoadedBook() == true, - relativePath == playerManager?.currentItem?.relativePath { + relativePath == playerManager?.currentItem?.relativePath + { if autoplay { playerManager?.play() } @@ -218,15 +234,20 @@ class AppDelegate: UIResponder, UIApplicationDelegate, BPLogger { do { /// If the selected item is a bound book, check that the contents are loaded if syncService?.isActive == true, - libraryItem.type == .bound, - let contents = libraryService?.getMaxItemsCount(at: relativePath), - contents == 0 { + libraryItem.type == .bound, + let contents = libraryService?.getMaxItemsCount(at: relativePath), + contents == 0 + { _ = try await syncService?.syncListContents(at: relativePath) } item = try self.playbackService?.getPlayableItem(from: libraryItem) } catch { - alertPresenter.showAlert("error_title".localized, message: error.localizedDescription, completion: nil) + alertPresenter.showAlert( + "error_title".localized, + message: error.localizedDescription, + completion: nil + ) return } @@ -247,7 +268,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate, BPLogger { @objc func messageReceived(_ notification: Notification) { guard let message = notification.userInfo as? [String: Any], - let action = CommandParser.parse(message) else { + let action = CommandParser.parse(message) + else { return } @@ -261,7 +283,10 @@ class AppDelegate: UIResponder, UIApplicationDelegate, BPLogger { let playerManager = self.playerManager, playerManager.currentItem != nil else { - UIAccessibility.post(notification: .announcement, argument: "voiceover_no_title".localized) + UIAccessibility.post( + notification: .announcement, + argument: "voiceover_no_title".localized + ) return false } @@ -270,90 +295,102 @@ class AppDelegate: UIResponder, UIApplicationDelegate, BPLogger { } func setupMPRemoteCommands() { - self.setupMPPlaybackRemoteCommands() - self.setupMPSkipRemoteCommands() + Task { + self.setupMPPlaybackRemoteCommands() + self.setupMPSkipRemoteCommands() + } } func setupMPPlaybackRemoteCommands() { - Task { - // Play / Pause - MPRemoteCommandCenter.shared().togglePlayPauseCommand.isEnabled = true - MPRemoteCommandCenter.shared().togglePlayPauseCommand.addTarget { [weak self] (_) -> MPRemoteCommandHandlerStatus in - guard let playerManager = self?.playerManager else { return .commandFailed } - - let wasPlaying = playerManager.isPlaying - playerManager.playPause() - - if wasPlaying, - UIApplication.shared.applicationState == .background { - self?.scheduleAppRefresh() - } - return .success + let center = MPRemoteCommandCenter.shared() + // Play / Pause + center.togglePlayPauseCommand.isEnabled = true + center.togglePlayPauseCommand.addTarget { [weak self] (_) -> MPRemoteCommandHandlerStatus in + guard let playerManager = self?.playerManager else { + return .commandFailed } - - MPRemoteCommandCenter.shared().playCommand.isEnabled = true - MPRemoteCommandCenter.shared().playCommand.addTarget { [weak self] (_) -> MPRemoteCommandHandlerStatus in - guard let playerManager = self?.playerManager else { return .commandFailed } - - playerManager.play() - return .success + + let wasPlaying = playerManager.isPlaying + playerManager.playPause() + + if wasPlaying, + UIApplication.shared.applicationState == .background + { + self?.scheduleAppRefresh() } - - MPRemoteCommandCenter.shared().pauseCommand.isEnabled = true - MPRemoteCommandCenter.shared().pauseCommand.addTarget { [weak self] (_) -> MPRemoteCommandHandlerStatus in - guard let playerManager = self?.playerManager else { return .commandFailed } - - playerManager.pause() - - if UIApplication.shared.applicationState == .background { - self?.scheduleAppRefresh() - } - - return .success + return .success + } + + center.playCommand.isEnabled = true + center.playCommand.addTarget { [weak self] (_) -> MPRemoteCommandHandlerStatus in + guard let playerManager = self?.playerManager else { + return .commandFailed } - - MPRemoteCommandCenter.shared().changePlaybackPositionCommand.isEnabled = true - MPRemoteCommandCenter.shared().changePlaybackPositionCommand.addTarget { [weak self] remoteEvent in - guard - let playerManager = self?.playerManager, - let currentItem = playerManager.currentItem, - let event = remoteEvent as? MPChangePlaybackPositionCommandEvent - else { return .commandFailed } - - var newTime = event.positionTime - - if UserDefaults.sharedDefaults.bool(forKey: Constants.UserDefaults.chapterContextEnabled), - let currentChapter = currentItem.currentChapter { - newTime += currentChapter.start - } - - playerManager.jumpTo(newTime, recordBookmark: true) - - return .success + + playerManager.play() + return .success + } + + center.pauseCommand.isEnabled = true + center.pauseCommand.addTarget { [weak self] (_) -> MPRemoteCommandHandlerStatus in + guard let playerManager = self?.playerManager else { + return .commandFailed } + + playerManager.pause() + + if UIApplication.shared.applicationState == .background { + self?.scheduleAppRefresh() + } + + return .success + } + + center.changePlaybackPositionCommand.isEnabled = true + center.changePlaybackPositionCommand.addTarget { [weak self] remoteEvent in + guard + let playerManager = self?.playerManager, + let currentItem = playerManager.currentItem, + let event = remoteEvent as? MPChangePlaybackPositionCommandEvent + else { return .commandFailed } + + var newTime = event.positionTime + + if UserDefaults.sharedDefaults.bool(forKey: Constants.UserDefaults.chapterContextEnabled), + let currentChapter = currentItem.currentChapter + { + newTime += currentChapter.start + } + + playerManager.jumpTo(newTime, recordBookmark: true) + + return .success } } // For now, seek forward/backward and next/previous track perform the same function func setupMPSkipRemoteCommands() { + let center = MPRemoteCommandCenter.shared() // Forward - MPRemoteCommandCenter.shared().skipForwardCommand.preferredIntervals = [NSNumber(value: PlayerManager.forwardInterval)] - MPRemoteCommandCenter.shared().skipForwardCommand.addTarget { [weak self] (_) -> MPRemoteCommandHandlerStatus in + center.skipForwardCommand.preferredIntervals = [NSNumber(value: PlayerManager.forwardInterval)] + center.skipForwardCommand.addTarget { [weak self] (_) -> MPRemoteCommandHandlerStatus in guard let playerManager = self?.playerManager else { return .commandFailed } playerManager.forward() return .success } - MPRemoteCommandCenter.shared().nextTrackCommand.addTarget { [weak self] (_) -> MPRemoteCommandHandlerStatus in + center.nextTrackCommand.addTarget { [weak self] (_) -> MPRemoteCommandHandlerStatus in guard let playerManager = self?.playerManager else { return .commandFailed } playerManager.forward() return .success } - MPRemoteCommandCenter.shared().seekForwardCommand.addTarget { [weak self] (commandEvent) -> MPRemoteCommandHandlerStatus in - guard let cmd = commandEvent as? MPSeekCommandEvent, cmd.type == .endSeeking else { + center.seekForwardCommand.addTarget { [weak self] (commandEvent) -> MPRemoteCommandHandlerStatus in + guard let cmd = commandEvent as? MPSeekCommandEvent, + cmd.type == .endSeeking + else { return .success } @@ -365,23 +402,26 @@ class AppDelegate: UIResponder, UIApplicationDelegate, BPLogger { } // Rewind - MPRemoteCommandCenter.shared().skipBackwardCommand.preferredIntervals = [NSNumber(value: PlayerManager.rewindInterval)] - MPRemoteCommandCenter.shared().skipBackwardCommand.addTarget { [weak self] (_) -> MPRemoteCommandHandlerStatus in + center.skipBackwardCommand.preferredIntervals = [NSNumber(value: PlayerManager.rewindInterval)] + center.skipBackwardCommand.addTarget { [weak self] (_) -> MPRemoteCommandHandlerStatus in guard let playerManager = self?.playerManager else { return .commandFailed } playerManager.rewind() return .success } - MPRemoteCommandCenter.shared().previousTrackCommand.addTarget { [weak self] (_) -> MPRemoteCommandHandlerStatus in + center.previousTrackCommand.addTarget { [weak self] (_) -> MPRemoteCommandHandlerStatus in guard let playerManager = self?.playerManager else { return .commandFailed } playerManager.rewind() return .success } - MPRemoteCommandCenter.shared().seekBackwardCommand.addTarget { [weak self] (commandEvent) -> MPRemoteCommandHandlerStatus in - guard let cmd = commandEvent as? MPSeekCommandEvent, cmd.type == .endSeeking else { + center.seekBackwardCommand.addTarget { [weak self] (commandEvent) -> MPRemoteCommandHandlerStatus in + guard + let cmd = commandEvent as? MPSeekCommandEvent, + cmd.type == .endSeeking + else { return .success } @@ -394,7 +434,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate, BPLogger { } func setupRevenueCat() { - let revenueCatApiKey: String = Bundle.main.configurationValue(for: .revenueCat) + let revenueCatApiKey: String = Bundle.main.configurationValue( + for: .revenueCat + ) Purchases.logLevel = .error Purchases.configure(withAPIKey: revenueCatApiKey) } @@ -402,12 +444,18 @@ class AppDelegate: UIResponder, UIApplicationDelegate, BPLogger { /// Setup observer for user preference, and setup Sentry based on initial value func setupSentry() { let userDefaults = UserDefaults.standard - crashReportsAccessObserver = userDefaults.observe(\.userSettingsCrashReportsDisabled) { [weak self] object, _ in - self?.handleSentryPreference(isDisabled: object.userSettingsCrashReportsDisabled) + crashReportsAccessObserver = userDefaults.observe( + \.userSettingsCrashReportsDisabled + ) { [weak self] object, _ in + self?.handleSentryPreference( + isDisabled: object.userSettingsCrashReportsDisabled + ) } handleSentryPreference( - isDisabled: userDefaults.bool(forKey: Constants.UserDefaults.crashReportsDisabled) + isDisabled: userDefaults.bool( + forKey: Constants.UserDefaults.crashReportsDisabled + ) ) } @@ -425,15 +473,21 @@ class AppDelegate: UIResponder, UIApplicationDelegate, BPLogger { if let actionURL = sharedDefaults.sharedWidgetActionURL { ActionParserService.process(actionURL) - sharedDefaults.removeObject(forKey: Constants.UserDefaults.sharedWidgetActionURL) + sharedDefaults.removeObject( + forKey: Constants.UserDefaults.sharedWidgetActionURL + ) } - sharedWidgetActionURLObserver = sharedDefaults.observe(\.sharedWidgetActionURL) { defaults, _ in + sharedWidgetActionURLObserver = sharedDefaults.observe( + \.sharedWidgetActionURL + ) { defaults, _ in DispatchQueue.main.async { guard let actionURL = defaults.sharedWidgetActionURL else { return } ActionParserService.process(actionURL) - sharedDefaults.removeObject(forKey: Constants.UserDefaults.sharedWidgetActionURL) + sharedDefaults.removeObject( + forKey: Constants.UserDefaults.sharedWidgetActionURL + ) } } } @@ -483,7 +537,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate, BPLogger { } func requestReview() { - if let scene = UIApplication.shared.connectedScenes.first(where: { $0.activationState == .foregroundActive }) as? UIWindowScene { + if let scene = UIApplication.shared.connectedScenes.first(where: { + $0.activationState == .foregroundActive + }) as? UIWindowScene { SKStoreReviewController.requestReview(in: scene) } } @@ -510,7 +566,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate, BPLogger { } if let mainCoordinator = activeSceneDelegate?.mainCoordinator, - !mainCoordinator.hasPlayerShown() { + !mainCoordinator.hasPlayerShown() + { mainCoordinator.showPlayer() } } @@ -523,10 +580,12 @@ extension AppDelegate { func setupBackgroundRefreshTasks() { NotificationCenter.default.addObserver( forName: UIApplication.didEnterBackgroundNotification, - object: nil, queue: nil) { _ in - if self.playerManager?.isPlaying != true { - self.scheduleAppRefresh() - } + object: nil, + queue: nil + ) { _ in + if self.playerManager?.isPlaying != true { + self.scheduleAppRefresh() + } } BGTaskScheduler.shared.register(