diff --git a/Passepartout/Library/Sources/CommonLibrary/Business/InMemoryProfileRepository.swift b/Passepartout/Library/Sources/CommonLibrary/Business/InMemoryProfileRepository.swift index e9d4283a..621d3111 100644 --- a/Passepartout/Library/Sources/CommonLibrary/Business/InMemoryProfileRepository.swift +++ b/Passepartout/Library/Sources/CommonLibrary/Business/InMemoryProfileRepository.swift @@ -46,7 +46,7 @@ public final class InMemoryProfileRepository: ProfileRepository { } public func saveProfile(_ profile: Profile) { - pp_log(.app, .info, "Save profile: \(profile.id))") + pp_log(.App.profiles, .info, "Save profile: \(profile.id))") if let index = profiles.firstIndex(where: { $0.id == profile.id }) { profiles[index] = profile } else { @@ -55,7 +55,7 @@ public final class InMemoryProfileRepository: ProfileRepository { } public func removeProfiles(withIds ids: [Profile.ID]) { - pp_log(.app, .info, "Remove profiles: \(ids)") + pp_log(.App.profiles, .info, "Remove profiles: \(ids)") profiles = profiles.filter { !ids.contains($0.id) } diff --git a/Passepartout/Library/Sources/CommonLibrary/Business/NEProfileRepository.swift b/Passepartout/Library/Sources/CommonLibrary/Business/NEProfileRepository.swift index 6114ba34..e976c19e 100644 --- a/Passepartout/Library/Sources/CommonLibrary/Business/NEProfileRepository.swift +++ b/Passepartout/Library/Sources/CommonLibrary/Business/NEProfileRepository.swift @@ -92,10 +92,10 @@ private extension NEProfileRepository { let profiles = managers.values.compactMap { do { let profile = try repository.profile(from: $0) - pp_log(.app, .debug, "Attributes for profile \(profile.id): \(profile.attributes)") + pp_log(.App.profiles, .debug, "Attributes for profile \(profile.id): \(profile.attributes)") return profile } catch { - pp_log(.app, .error, "Unable to decode profile from NE manager '\($0.localizedDescription ?? "")': \(error)") + pp_log(.App.profiles, .error, "Unable to decode profile from NE manager '\($0.localizedDescription ?? "")': \(error)") return nil } } @@ -119,7 +119,7 @@ private extension NEProfileRepository { } if !removedProfilesDescription.isEmpty { - pp_log(.app, .info, "Sync profiles removed externally: \(removedProfilesDescription)") + pp_log(.App.profiles, .info, "Sync profiles removed externally: \(removedProfilesDescription)") } profilesSubject.send(profiles) diff --git a/Passepartout/Library/Sources/CommonLibrary/Business/ProfileManager.swift b/Passepartout/Library/Sources/CommonLibrary/Business/ProfileManager.swift index 1328f6be..cc39d1c2 100644 --- a/Passepartout/Library/Sources/CommonLibrary/Business/ProfileManager.swift +++ b/Passepartout/Library/Sources/CommonLibrary/Business/ProfileManager.swift @@ -144,7 +144,7 @@ extension ProfileManager { profile = originalProfile } - pp_log(.app, .notice, "Save profile \(profile.id)...") + pp_log(.App.profiles, .notice, "Save profile \(profile.id)...") do { let existingProfile = allProfiles[profile.id] if existingProfile == nil || profile != existingProfile { @@ -157,27 +157,27 @@ extension ProfileManager { allProfiles[profile.id] = profile didChange.send(.save(profile)) } else { - pp_log(.app, .notice, "\tProfile \(profile.id) not modified, not saving") + pp_log(.App.profiles, .notice, "\tProfile \(profile.id) not modified, not saving") } } catch { - pp_log(.app, .fault, "\tUnable to save profile \(profile.id): \(error)") + pp_log(.App.profiles, .fault, "\tUnable to save profile \(profile.id): \(error)") throw error } do { if let isShared, let remoteRepository { if isShared { - pp_log(.app, .notice, "\tEnable remote sharing of profile \(profile.id)...") + pp_log(.App.profiles, .notice, "\tEnable remote sharing of profile \(profile.id)...") try await remoteRepository.saveProfile(profile) } else { - pp_log(.app, .notice, "\tDisable remote sharing of profile \(profile.id)...") + pp_log(.App.profiles, .notice, "\tDisable remote sharing of profile \(profile.id)...") try await remoteRepository.removeProfiles(withIds: [profile.id]) } } } catch { - pp_log(.app, .fault, "\tUnable to save/remove remote profile \(profile.id): \(error)") + pp_log(.App.profiles, .fault, "\tUnable to save/remove remote profile \(profile.id): \(error)") throw error } - pp_log(.app, .notice, "Finished saving profile \(profile.id)") + pp_log(.App.profiles, .notice, "Finished saving profile \(profile.id)") } public func remove(withId profileId: Profile.ID) async { @@ -185,7 +185,7 @@ extension ProfileManager { } public func remove(withIds profileIds: [Profile.ID]) async { - pp_log(.app, .notice, "Remove profiles \(profileIds)...") + pp_log(.App.profiles, .notice, "Remove profiles \(profileIds)...") do { // remove local profiles var newAllProfiles = allProfiles @@ -204,7 +204,7 @@ extension ProfileManager { allProfiles = newAllProfiles didChange.send(.remove(profileIds)) } catch { - pp_log(.app, .fault, "Unable to remove profiles \(profileIds): \(error)") + pp_log(.App.profiles, .fault, "Unable to remove profiles \(profileIds): \(error)") } } @@ -225,7 +225,7 @@ extension ProfileManager { } public func eraseRemotelySharedProfiles() async throws { - pp_log(.app, .notice, "Erase remotely shared profiles...") + pp_log(.App.profiles, .notice, "Erase remotely shared profiles...") try await remoteRepository?.removeProfiles(withIds: Array(allRemoteProfiles.keys)) } } @@ -250,7 +250,7 @@ extension ProfileManager { var builder = profile.builder(withNewId: true) builder.name = firstUniqueName(from: profile.name) - pp_log(.app, .notice, "Duplicate profile [\(profileId), \(profile.name)] -> [\(builder.id), \(builder.name)]...") + pp_log(.App.profiles, .notice, "Duplicate profile [\(profileId), \(profile.name)] -> [\(builder.id), \(builder.name)]...") let copy = try builder.tryBuild() try await save(copy) @@ -316,7 +316,7 @@ extension ProfileManager { private extension ProfileManager { func reloadLocalProfiles(_ result: [Profile]) { - pp_log(.app, .info, "Reload local profiles: \(result.map(\.id))") + pp_log(.App.profiles, .info, "Reload local profiles: \(result.map(\.id))") allProfiles = result.reduce(into: [:]) { $0[$1.id] = $1 } @@ -330,7 +330,7 @@ private extension ProfileManager { .map(\.key) if !idsToRemove.isEmpty { - pp_log(.app, .info, "Delete non-included local profiles: \(idsToRemove)") + pp_log(.App.profiles, .info, "Delete non-included local profiles: \(idsToRemove)") Task.detached { try await self.repository.removeProfiles(withIds: idsToRemove) } @@ -339,7 +339,7 @@ private extension ProfileManager { } func loadInitialRemoteProfiles(_ result: [Profile]) { - pp_log(.app, .info, "Load initial remote profiles: \(result.map(\.id))") + pp_log(.App.profiles, .info, "Load initial remote profiles: \(result.map(\.id))") allRemoteProfiles = result.reduce(into: [:]) { $0[$1.id] = $1 } @@ -347,7 +347,7 @@ private extension ProfileManager { } func reloadRemoteProfiles(_ result: [Profile]) { - pp_log(.app, .info, "Reload remote profiles: \(result.map(\.id))") + pp_log(.App.profiles, .info, "Reload remote profiles: \(result.map(\.id))") allRemoteProfiles = result.reduce(into: [:]) { $0[$1.id] = $1 } @@ -358,17 +358,17 @@ private extension ProfileManager { return } - pp_log(.app, .info, "Start importing remote profiles...") + pp_log(.App.profiles, .info, "Start importing remote profiles...") - pp_log(.app, .debug, "Local fingerprints:") + pp_log(.App.profiles, .debug, "Local fingerprints:") let localFingerprints: [Profile.ID: UUID] = await allProfiles.values.reduce(into: [:]) { $0[$1.id] = $1.attributes.fingerprint - pp_log(.app, .debug, "\t\($1.id) = \($1.attributes.fingerprint?.description ?? "nil")") + pp_log(.App.profiles, .debug, "\t\($1.id) = \($1.attributes.fingerprint?.description ?? "nil")") } - pp_log(.app, .debug, "Remote fingerprints:") + pp_log(.App.profiles, .debug, "Remote fingerprints:") let remoteFingerprints: [Profile.ID: UUID] = result.reduce(into: [:]) { $0[$1.id] = $1.attributes.fingerprint - pp_log(.app, .debug, "\t\($1.id) = \($1.attributes.fingerprint?.description ?? "nil")") + pp_log(.App.profiles, .debug, "\t\($1.id) = \($1.attributes.fingerprint?.description ?? "nil")") } let profilesToImport = result @@ -377,7 +377,7 @@ private extension ProfileManager { var idsToRemove: [Profile.ID] = [] if !remotelyDeletedIds.isEmpty { - pp_log(.app, .info, "Will \(deletingRemotely ? "delete" : "retain") local profiles not present in remote repository: \(remotelyDeletedIds)") + pp_log(.App.profiles, .info, "Will \(deletingRemotely ? "delete" : "retain") local profiles not present in remote repository: \(remotelyDeletedIds)") if deletingRemotely { idsToRemove.append(contentsOf: remotelyDeletedIds) @@ -386,27 +386,27 @@ private extension ProfileManager { for remoteProfile in profilesToImport { do { guard processor?.isIncluded(remoteProfile) ?? true else { - pp_log(.app, .info, "Will delete non-included remote profile \(remoteProfile.id)") + pp_log(.App.profiles, .info, "Will delete non-included remote profile \(remoteProfile.id)") idsToRemove.append(remoteProfile.id) continue } guard remoteFingerprints[remoteProfile.id] != localFingerprints[remoteProfile.id] else { - pp_log(.app, .info, "Skip re-importing local profile \(remoteProfile.id)") + pp_log(.App.profiles, .info, "Skip re-importing local profile \(remoteProfile.id)") continue } - pp_log(.app, .notice, "Import remote profile \(remoteProfile.id)...") + pp_log(.App.profiles, .notice, "Import remote profile \(remoteProfile.id)...") try await save(remoteProfile) } catch { - pp_log(.app, .error, "Unable to import remote profile: \(error)") + pp_log(.App.profiles, .error, "Unable to import remote profile: \(error)") } } - pp_log(.app, .notice, "Finished importing remote profiles, delete stale profiles: \(idsToRemove)") + pp_log(.App.profiles, .notice, "Finished importing remote profiles, delete stale profiles: \(idsToRemove)") try? await repository.removeProfiles(withIds: idsToRemove) } } func performSearch(_ search: String) { - pp_log(.app, .notice, "Filter profiles with '\(search)'") + pp_log(.App.profiles, .notice, "Filter profiles with '\(search)'") reloadFilteredProfiles(with: search) } diff --git a/Passepartout/Library/Sources/CommonLibrary/Domain/ProfileAttributes.swift b/Passepartout/Library/Sources/CommonLibrary/Domain/ProfileAttributes.swift index f8b24de7..c48c9ddb 100644 --- a/Passepartout/Library/Sources/CommonLibrary/Domain/ProfileAttributes.swift +++ b/Passepartout/Library/Sources/CommonLibrary/Domain/ProfileAttributes.swift @@ -73,7 +73,7 @@ extension ProfileAttributes: ProfileUserInfoTransformable { let data = try JSONEncoder().encode(self) return try JSONSerialization.jsonObject(with: data) as? [String: AnyHashable] ?? [:] } catch { - pp_log(.app, .error, "Unable to encode ProfileAttributes to dictionary: \(error)") + pp_log(.App.profiles, .error, "Unable to encode ProfileAttributes to dictionary: \(error)") return [:] } } @@ -83,7 +83,7 @@ extension ProfileAttributes: ProfileUserInfoTransformable { let data = try JSONSerialization.data(withJSONObject: userInfo ?? [:]) self = try JSONDecoder().decode(ProfileAttributes.self, from: data) } catch { - pp_log(.app, .error, "Unable to decode ProfileAttributes from dictionary: \(error)") + pp_log(.App.profiles, .error, "Unable to decode ProfileAttributes from dictionary: \(error)") return nil } } diff --git a/Passepartout/Library/Sources/CommonLibrary/IAP/FallbackReceiptReader.swift b/Passepartout/Library/Sources/CommonLibrary/IAP/FallbackReceiptReader.swift index 92ba6572..780d2689 100644 --- a/Passepartout/Library/Sources/CommonLibrary/IAP/FallbackReceiptReader.swift +++ b/Passepartout/Library/Sources/CommonLibrary/IAP/FallbackReceiptReader.swift @@ -60,14 +60,14 @@ private extension FallbackReceiptReader { func asyncReceipt(at userLevel: AppUserLevel) async -> InAppReceipt? { let localURL = Bundle.main.appStoreReceiptURL - pp_log(.iap, .debug, "\tParse receipt for user level \(userLevel)") + pp_log(.App.iap, .debug, "\tParse receipt for user level \(userLevel)") // 1. TestFlight, look for release receipt let releaseReceipt: InAppReceipt? = await { guard userLevel == .beta, let localURL else { return nil } - pp_log(.iap, .debug, "\tTestFlight, look for release receipt") + pp_log(.App.iap, .debug, "\tTestFlight, look for release receipt") let releaseURL = localURL .deletingLastPathComponent() .appendingPathComponent("receipt") @@ -83,7 +83,7 @@ private extension FallbackReceiptReader { }() if let releaseReceipt { - pp_log(.iap, .debug, "\tTestFlight, return release receipt") + pp_log(.App.iap, .debug, "\tTestFlight, return release receipt") return releaseReceipt } @@ -95,18 +95,18 @@ private extension FallbackReceiptReader { } // 2. primary receipt + build from local receipt - pp_log(.iap, .debug, "\tNo release receipt, read primary receipt") + pp_log(.App.iap, .debug, "\tNo release receipt, read primary receipt") if let receipt = await reader?.receipt() { if let build = await localReceiptBlock()?.originalBuildNumber { - pp_log(.iap, .debug, "\tReturn primary receipt with local build: \(build)") + pp_log(.App.iap, .debug, "\tReturn primary receipt with local build: \(build)") return receipt.withBuildNumber(build) } - pp_log(.iap, .debug, "\tReturn primary receipt without local build") + pp_log(.App.iap, .debug, "\tReturn primary receipt without local build") return receipt } // 3. fall back to local receipt - pp_log(.iap, .debug, "\tReturn local receipt") + pp_log(.App.iap, .debug, "\tReturn local receipt") return await localReceiptBlock() } } diff --git a/Passepartout/Library/Sources/CommonLibrary/IAP/IAPManager.swift b/Passepartout/Library/Sources/CommonLibrary/IAP/IAPManager.swift index b54757bd..d51628a6 100644 --- a/Passepartout/Library/Sources/CommonLibrary/IAP/IAPManager.swift +++ b/Passepartout/Library/Sources/CommonLibrary/IAP/IAPManager.swift @@ -83,7 +83,7 @@ extension IAPManager { inAppProducts[$0] } } catch { - pp_log(.iap, .error, "Unable to fetch in-app products: \(error)") + pp_log(.App.iap, .error, "Unable to fetch in-app products: \(error)") return [] } } @@ -159,7 +159,7 @@ extension IAPManager { private extension IAPManager { func asyncReloadReceipt() async { - pp_log(.iap, .notice, "Start reloading in-app receipt...") + pp_log(.App.iap, .notice, "Start reloading in-app receipt...") purchasedAppBuild = nil purchasedProducts.removeAll() @@ -171,41 +171,41 @@ private extension IAPManager { } if let purchasedAppBuild { - pp_log(.iap, .info, "Original purchased build: \(purchasedAppBuild)") + pp_log(.App.iap, .info, "Original purchased build: \(purchasedAppBuild)") // assume some purchases by build number let entitled = productsAtBuild?(purchasedAppBuild) ?? [] - pp_log(.iap, .notice, "Entitled features: \(entitled.map(\.rawValue))") + pp_log(.App.iap, .notice, "Entitled features: \(entitled.map(\.rawValue))") entitled.forEach { purchasedProducts.insert($0) } } if let iapReceipts = receipt.purchaseReceipts { - pp_log(.iap, .info, "Process in-app purchase receipts...") + pp_log(.App.iap, .info, "Process in-app purchase receipts...") let products: [AppProduct] = iapReceipts.compactMap { guard let pid = $0.productIdentifier else { return nil } guard let product = AppProduct(rawValue: pid) else { - pp_log(.iap, .debug, "\tDiscard unknown product identifier: \(pid)") + pp_log(.App.iap, .debug, "\tDiscard unknown product identifier: \(pid)") return nil } if let expirationDate = $0.expirationDate { let now = Date() - pp_log(.iap, .debug, "\t\(pid) [expiration date: \(expirationDate), now: \(now)]") + pp_log(.App.iap, .debug, "\t\(pid) [expiration date: \(expirationDate), now: \(now)]") if now >= expirationDate { - pp_log(.iap, .info, "\t\(pid) [expired on: \(expirationDate)]") + pp_log(.App.iap, .info, "\t\(pid) [expired on: \(expirationDate)]") return nil } } if let cancellationDate = $0.cancellationDate { - pp_log(.iap, .info, "\t\(pid) [cancelled on: \(cancellationDate)]") + pp_log(.App.iap, .info, "\t\(pid) [cancelled on: \(cancellationDate)]") return nil } if let purchaseDate = $0.originalPurchaseDate { - pp_log(.iap, .info, "\t\(pid) [purchased on: \(purchaseDate)]") + pp_log(.App.iap, .info, "\t\(pid) [purchased on: \(purchaseDate)]") } return product } @@ -221,7 +221,7 @@ private extension IAPManager { } } } else { - pp_log(.iap, .error, "Could not parse App Store receipt!") + pp_log(.App.iap, .error, "Could not parse App Store receipt!") } userLevel.features.forEach { @@ -231,10 +231,10 @@ private extension IAPManager { eligibleFeatures.insert($0) } - pp_log(.iap, .notice, "Finished reloading in-app receipt for user level \(userLevel)") - pp_log(.iap, .notice, "\tPurchased build number: \(purchasedAppBuild?.description ?? "unknown")") - pp_log(.iap, .notice, "\tPurchased products: \(purchasedProducts.map(\.rawValue))") - pp_log(.iap, .notice, "\tEligible features: \(eligibleFeatures)") + pp_log(.App.iap, .notice, "Finished reloading in-app receipt for user level \(userLevel)") + pp_log(.App.iap, .notice, "\tPurchased build number: \(purchasedAppBuild?.description ?? "unknown")") + pp_log(.App.iap, .notice, "\tPurchased products: \(purchasedProducts.map(\.rawValue))") + pp_log(.App.iap, .notice, "\tEligible features: \(eligibleFeatures)") objectWillChange.send() } @@ -249,7 +249,7 @@ private extension IAPManager { await reloadReceipt() do { let products = try await inAppHelper.fetchProducts() - pp_log(.iap, .info, "Available in-app products: \(products.map(\.key))") + pp_log(.App.iap, .info, "Available in-app products: \(products.map(\.key))") inAppHelper .didUpdate @@ -262,7 +262,7 @@ private extension IAPManager { .store(in: &subscriptions) } catch { - pp_log(.iap, .error, "Unable to fetch in-app products: \(error)") + pp_log(.App.iap, .error, "Unable to fetch in-app products: \(error)") } } } @@ -273,11 +273,11 @@ private extension IAPManager { } if let customUserLevel { userLevel = customUserLevel - pp_log(.iap, .info, "App level (custom): \(userLevel)") + pp_log(.App.iap, .info, "App level (custom): \(userLevel)") } else { let isBeta = await SandboxChecker().isBeta userLevel = isBeta ? .beta : .freemium - pp_log(.iap, .info, "App level: \(userLevel)") + pp_log(.App.iap, .info, "App level: \(userLevel)") } } } diff --git a/Passepartout/Library/Sources/CommonLibrary/Shared.swift b/Passepartout/Library/Sources/CommonLibrary/Shared.swift index 829124ab..f141a862 100644 --- a/Passepartout/Library/Sources/CommonLibrary/Shared.swift +++ b/Passepartout/Library/Sources/CommonLibrary/Shared.swift @@ -28,9 +28,13 @@ import PassepartoutKit import PassepartoutWireGuardGo extension LoggerDestination { - public static let app = Self(category: "app") + public static let app = LoggerDestination(category: "app") - public static let iap = Self(category: "iap") + public enum App { + public static let iap = LoggerDestination(category: "app.iap") + + public static let profiles = LoggerDestination(category: "app.profiles") + } } extension WireGuard.Configuration.Builder {