diff --git a/IceCubesNotifications/NotificationServiceSupport.swift b/IceCubesNotifications/NotificationServiceSupport.swift index 698ce296..6b5dde4f 100644 --- a/IceCubesNotifications/NotificationServiceSupport.swift +++ b/IceCubesNotifications/NotificationServiceSupport.swift @@ -24,16 +24,13 @@ extension NotificationService { var _plaintext: Data? do { _plaintext = try AES.GCM.open(sealedBox, using: key) - } catch { - print(error) - } + } catch { } guard let plaintext = _plaintext else { return nil } let paddingLength = Int(plaintext[0]) * 256 + Int(plaintext[1]) guard plaintext.count >= 2 + paddingLength else { - print("1") fatalError() } let unpadded = plaintext.suffix(from: paddingLength + 2) diff --git a/Packages/Account/Sources/Account/AccountDetailContextMenu.swift b/Packages/Account/Sources/Account/AccountDetailContextMenu.swift index 9688c8f2..3c592abe 100644 --- a/Packages/Account/Sources/Account/AccountDetailContextMenu.swift +++ b/Packages/Account/Sources/Account/AccountDetailContextMenu.swift @@ -37,9 +37,7 @@ public struct AccountDetailContextMenu: View { Task { do { viewModel.relationship = try await client.post(endpoint: Accounts.unblock(id: account.id)) - } catch { - print("Error while unblocking: \(error.localizedDescription)") - } + } catch { } } } label: { Label("account.action.unblock", systemImage: "person.crop.circle.badge.exclamationmark") @@ -57,9 +55,7 @@ public struct AccountDetailContextMenu: View { Task { do { viewModel.relationship = try await client.post(endpoint: Accounts.unmute(id: account.id)) - } catch { - print("Error while unmuting: \(error.localizedDescription)") - } + } catch { } } } label: { Label("account.action.unmute", systemImage: "speaker") @@ -71,9 +67,7 @@ public struct AccountDetailContextMenu: View { Task { do { viewModel.relationship = try await client.post(endpoint: Accounts.mute(id: account.id, json: MuteData(duration: duration.rawValue))) - } catch { - print("Error while muting: \(error.localizedDescription)") - } + } catch { } } } } @@ -92,9 +86,7 @@ public struct AccountDetailContextMenu: View { viewModel.relationship = try await client.post(endpoint: Accounts.follow(id: account.id, notify: false, reblogs: relationship.showingReblogs)) - } catch { - print("Error while disabling notifications: \(error.localizedDescription)") - } + } catch { } } } label: { Label("account.action.notify-disable", systemImage: "bell.fill") @@ -106,9 +98,7 @@ public struct AccountDetailContextMenu: View { viewModel.relationship = try await client.post(endpoint: Accounts.follow(id: account.id, notify: true, reblogs: relationship.showingReblogs)) - } catch { - print("Error while enabling notifications: \(error.localizedDescription)") - } + } catch { } } } label: { Label("account.action.notify-enable", systemImage: "bell") @@ -121,9 +111,7 @@ public struct AccountDetailContextMenu: View { viewModel.relationship = try await client.post(endpoint: Accounts.follow(id: account.id, notify: relationship.notifying, reblogs: false)) - } catch { - print("Error while disabling reboosts: \(error.localizedDescription)") - } + } catch { } } } label: { Label("account.action.reboosts-hide", image: "Rocket.Fill") @@ -135,9 +123,7 @@ public struct AccountDetailContextMenu: View { viewModel.relationship = try await client.post(endpoint: Accounts.follow(id: account.id, notify: relationship.notifying, reblogs: true)) - } catch { - print("Error while enabling reboosts: \(error.localizedDescription)") - } + } catch { } } } label: { Label("account.action.reboosts-show", image: "Rocket") diff --git a/Packages/Account/Sources/Account/AccountDetailView.swift b/Packages/Account/Sources/Account/AccountDetailView.swift index 7deb8251..9fde6778 100644 --- a/Packages/Account/Sources/Account/AccountDetailView.swift +++ b/Packages/Account/Sources/Account/AccountDetailView.swift @@ -366,9 +366,7 @@ public struct AccountDetailView: View { Task { do { viewModel.relationship = try await client.post(endpoint: Accounts.block(id: account.id)) - } catch { - print("Error while blocking: \(error.localizedDescription)") - } + } catch { } } } } diff --git a/Packages/Account/Sources/Account/AccountsList/AccountsListViewModel.swift b/Packages/Account/Sources/Account/AccountsList/AccountsListViewModel.swift index dd598f28..bc919e5b 100644 --- a/Packages/Account/Sources/Account/AccountsList/AccountsListViewModel.swift +++ b/Packages/Account/Sources/Account/AccountsList/AccountsListViewModel.swift @@ -2,6 +2,7 @@ import Models import Network import Observation import SwiftUI +import OSLog public enum AccountsListMode { case following(accountId: String), followers(accountId: String) @@ -126,7 +127,8 @@ public enum AccountsListMode { relationships: relationships, nextPageState: link?.maxId != nil ? .hasNextPage : .none) } catch { - print(error) + let logger = Logger(subsystem: "com.icecubesapp", category: "UI") + logger.log(level: .info, "\(error.localizedDescription)") } } diff --git a/Packages/Account/Sources/Account/Follow/FollowButton.swift b/Packages/Account/Sources/Account/Follow/FollowButton.swift index 05043779..328df665 100644 --- a/Packages/Account/Sources/Account/Follow/FollowButton.swift +++ b/Packages/Account/Sources/Account/Follow/FollowButton.swift @@ -5,6 +5,7 @@ import Models import Network import Observation import SwiftUI +import OSLog @MainActor @Observable public class FollowButtonViewModel { @@ -32,7 +33,6 @@ import SwiftUI relationship = try await client.post(endpoint: Accounts.follow(id: accountId, notify: false, reblogs: true)) relationshipUpdated(relationship) } catch { - print("Error while following: \(error.localizedDescription)") throw error } } @@ -43,7 +43,6 @@ import SwiftUI relationship = try await client.post(endpoint: Accounts.unfollow(id: accountId)) relationshipUpdated(relationship) } catch { - print("Error while unfollowing: \(error.localizedDescription)") throw error } } @@ -56,7 +55,6 @@ import SwiftUI reblogs: relationship.showingReblogs)) relationshipUpdated(relationship) } catch { - print("Error while following: \(error.localizedDescription)") throw error } } @@ -69,7 +67,6 @@ import SwiftUI reblogs: !relationship.showingReblogs)) relationshipUpdated(relationship) } catch { - print("Error while switching reboosts: \(error.localizedDescription)") throw error } } diff --git a/Packages/Env/Sources/Env/StreamWatcher.swift b/Packages/Env/Sources/Env/StreamWatcher.swift index 9f77fb6a..e844b356 100644 --- a/Packages/Env/Sources/Env/StreamWatcher.swift +++ b/Packages/Env/Sources/Env/StreamWatcher.swift @@ -3,6 +3,7 @@ import Foundation import Models import Network import Observation +import OSLog @MainActor @Observable public class StreamWatcher { @@ -26,6 +27,8 @@ import Observation public var events: [any StreamEvent] = [] public var unreadNotificationsCount: Int = 0 public var latestEvent: (any StreamEvent)? + + private let logger = Logger(subsystem: "com.icecubesapp", category: "stream") public static let shared = StreamWatcher() @@ -89,10 +92,11 @@ import Observation case let .string(string): do { guard let data = string.data(using: .utf8) else { - print("Error decoding streaming event string") + logger.error("Error decoding streaming event string") return } let rawEvent = try decoder.decode(RawStreamEvent.self, from: data) + logger.info("Stream update: \(rawEvent.event)") if let event = rawEventToEvent(rawEvent: rawEvent) { Task { @MainActor in self.events.append(event) @@ -103,7 +107,7 @@ import Observation } } } catch { - print("Error decoding streaming event: \(error.localizedDescription)") + logger.error("Error decoding streaming event: \(error.localizedDescription)") } default: @@ -147,8 +151,8 @@ import Observation return nil } } catch { - print("Error decoding streaming event to final event: \(error.localizedDescription)") - print("Raw data: \(rawEvent.payload)") + logger.error("Error decoding streaming event to final event: \(error.localizedDescription)") + logger.error("Raw data: \(rawEvent.payload)") return nil } } diff --git a/Packages/Network/Sources/Network/Client.swift b/Packages/Network/Sources/Network/Client.swift index c173005f..b7351a7d 100644 --- a/Packages/Network/Sources/Network/Client.swift +++ b/Packages/Network/Sources/Network/Client.swift @@ -4,8 +4,9 @@ import Models import Observation import os import SwiftUI +import OSLog -@Observable public final class Client: Equatable, Identifiable, Hashable { +@Observable public final class Client: Equatable, Identifiable, Hashable, @unchecked Sendable { public static func == (lhs: Client, rhs: Client) -> Bool { let lhsToken = lhs.critical.withLock { $0.oauthToken } let rhsToken = rhs.critical.withLock { $0.oauthToken } @@ -43,6 +44,8 @@ import SwiftUI public let version: Version private let urlSession: URLSession private let decoder = JSONDecoder() + + private let logger = Logger(subsystem: "com.icecubesapp", category: "networking") // Putting all mutable state inside an `OSAllocatedUnfairLock` makes `Client` // provably `Sendable`. The lock is a struct, but it uses a `ManagedBuffer` @@ -125,7 +128,7 @@ import SwiftUI request.httpBody = jsonData request.setValue("application/json", forHTTPHeaderField: "Content-Type") } catch { - print("Client Error encoding JSON: \(error.localizedDescription)") + logger.error("Error encoding JSON: \(error.localizedDescription)") } } return request @@ -141,7 +144,8 @@ import SwiftUI } public func getWithLink(endpoint: Endpoint) async throws -> (Entity, LinkHandler?) { - let (data, httpResponse) = try await urlSession.data(for: makeGet(endpoint: endpoint)) + let request = try makeGet(endpoint: endpoint) + let (data, httpResponse) = try await urlSession.data(for: request) var linkHandler: LinkHandler? if let response = httpResponse as? HTTPURLResponse, let link = response.allHeaderFields["Link"] as? String @@ -149,6 +153,7 @@ import SwiftUI linkHandler = .init(rawLink: link) } logResponseOnError(httpResponse: httpResponse, data: data) + logger.log(level: .info, "\(request)") return try (decoder.decode(Entity.self, from: data), linkHandler) } @@ -188,6 +193,7 @@ import SwiftUI let url = try makeURL(endpoint: endpoint, forceVersion: forceVersion) let request = makeURLRequest(url: url, endpoint: endpoint, httpMethod: method) let (data, httpResponse) = try await urlSession.data(for: request) + logger.log(level: .info, "\(request)") logResponseOnError(httpResponse: httpResponse, data: data) do { return try decoder.decode(Entity.self, from: data) @@ -298,10 +304,8 @@ import SwiftUI private func logResponseOnError(httpResponse: URLResponse, data: Data) { if let httpResponse = httpResponse as? HTTPURLResponse, httpResponse.statusCode > 299 { - print(httpResponse) - print(String(data: data, encoding: .utf8) ?? "") + let error = "HTTP Response error: \(httpResponse.statusCode), response: \(httpResponse), data: \(String(data: data, encoding: .utf8) ?? "")" + logger.error("\(error)") } } } - -extension Client: Sendable {} diff --git a/Packages/StatusKit/Sources/StatusKit/Editor/ViewModel.swift b/Packages/StatusKit/Sources/StatusKit/Editor/ViewModel.swift index 0eb9eb75..5fc218de 100644 --- a/Packages/StatusKit/Sources/StatusKit/Editor/ViewModel.swift +++ b/Packages/StatusKit/Sources/StatusKit/Editor/ViewModel.swift @@ -835,9 +835,7 @@ extension StatusEditor { error: nil ) } - } catch { - print(error.localizedDescription) - } + } catch { } } try? await Task.sleep(for: .seconds(5)) } while !Task.isCancelled @@ -858,7 +856,7 @@ extension StatusEditor { mediaAttachment: media, error: nil ) - } catch { print(error) } + } catch { } } } diff --git a/Packages/StatusKit/Sources/StatusKit/History/StatusEditHistoryView.swift b/Packages/StatusKit/Sources/StatusKit/History/StatusEditHistoryView.swift index 8c13d68b..acdc02d3 100644 --- a/Packages/StatusKit/Sources/StatusKit/History/StatusEditHistoryView.swift +++ b/Packages/StatusKit/Sources/StatusKit/History/StatusEditHistoryView.swift @@ -56,9 +56,7 @@ public struct StatusEditHistoryView: View { .task { do { history = try await client.get(endpoint: Statuses.history(id: statusId)) - } catch { - print(error) - } + } catch { } } .listStyle(.plain) .scrollContentBackground(.hidden) diff --git a/Packages/StatusKit/Sources/StatusKit/Poll/StatusPollViewModel.swift b/Packages/StatusKit/Sources/StatusKit/Poll/StatusPollViewModel.swift index 2b3c023c..cf6c0568 100644 --- a/Packages/StatusKit/Sources/StatusKit/Poll/StatusPollViewModel.swift +++ b/Packages/StatusKit/Sources/StatusKit/Poll/StatusPollViewModel.swift @@ -35,9 +35,7 @@ import SwiftUI votes = poll.ownVotes ?? [] showResults = true } - } catch { - print(error) - } + } catch { } } public func handleSelection(_ pollIndex: Int) { diff --git a/Packages/StatusKit/Sources/StatusKit/Row/StatusRowView.swift b/Packages/StatusKit/Sources/StatusKit/Row/StatusRowView.swift index aac8be72..a698a4eb 100644 --- a/Packages/StatusKit/Sources/StatusKit/Row/StatusRowView.swift +++ b/Packages/StatusKit/Sources/StatusKit/Row/StatusRowView.swift @@ -201,9 +201,7 @@ public struct StatusRowView: View { do { let operationAccount = viewModel.status.reblog?.account ?? viewModel.status.account viewModel.authorRelationship = try await client.post(endpoint: Accounts.block(id: operationAccount.id)) - } catch { - print("Error while blocking: \(error.localizedDescription)") - } + } catch { } } } } diff --git a/Packages/StatusKit/Sources/StatusKit/Row/Subviews/StatusRowContextMenu.swift b/Packages/StatusKit/Sources/StatusKit/Row/Subviews/StatusRowContextMenu.swift index 779dd871..7dd9d11f 100644 --- a/Packages/StatusKit/Sources/StatusKit/Row/Subviews/StatusRowContextMenu.swift +++ b/Packages/StatusKit/Sources/StatusKit/Row/Subviews/StatusRowContextMenu.swift @@ -204,9 +204,7 @@ struct StatusRowContextMenu: View { do { let operationAccount = viewModel.status.reblog?.account ?? viewModel.status.account viewModel.authorRelationship = try await client.post(endpoint: Accounts.unmute(id: operationAccount.id)) - } catch { - print("Error while unmuting: \(error.localizedDescription)") - } + } catch { } } } label: { Label("account.action.unmute", systemImage: "speaker") @@ -219,9 +217,7 @@ struct StatusRowContextMenu: View { do { let operationAccount = viewModel.status.reblog?.account ?? viewModel.status.account viewModel.authorRelationship = try await client.post(endpoint: Accounts.mute(id: operationAccount.id, json: MuteData(duration: duration.rawValue))) - } catch { - print("Error while muting: \(error.localizedDescription)") - } + } catch { } } } } @@ -275,9 +271,7 @@ struct StatusRowContextMenu: View { do { let operationAccount = viewModel.status.reblog?.account ?? viewModel.status.account viewModel.authorRelationship = try await client.post(endpoint: Accounts.unblock(id: operationAccount.id)) - } catch { - print("Error while unblocking: \(error.localizedDescription)") - } + } catch { } } } label: { Label("account.action.unblock", systemImage: "person.crop.circle.badge.exclamationmark")