Skip to content

Commit

Permalink
Merge 0.2.1 hotfix (#443)
Browse files Browse the repository at this point in the history
  • Loading branch information
GhenadieVP committed May 29, 2023
1 parent d4f4b90 commit b2f39c9
Show file tree
Hide file tree
Showing 10 changed files with 148 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,15 @@
"version" : "1.0.3"
}
},
{
"identity" : "swift-log-file",
"kind" : "remoteSourceControl",
"location" : "https://github.com/crspybits/swift-log-file",
"state" : {
"revision" : "aa94b38bf88c7d9cbc87ceafcdffadaffbc2bffa",
"version" : "0.1.0"
}
},
{
"identity" : "swift-nonempty",
"kind" : "remoteSourceControl",
Expand Down Expand Up @@ -333,6 +342,15 @@
"version" : "110.0.0"
}
},
{
"identity" : "xcglogger",
"kind" : "remoteSourceControl",
"location" : "https://github.com/DaveWoodCom/XCGLogger.git",
"state" : {
"revision" : "a9c4667b247928a29bdd41be2ec2c8d304215a54",
"version" : "7.0.1"
}
},
{
"identity" : "xctest-dynamic-overlay",
"kind" : "remoteSourceControl",
Expand Down
2 changes: 1 addition & 1 deletion App/Config/Common.xcconfig
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// MARK: - Custom flags

/// Application version shared across all targets and flavours
APP_VERSION = 0.2.0
APP_VERSION = 0.2.1

/// App Icon base name
APP_ICON = AppIcon
Expand Down
3 changes: 3 additions & 0 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -978,6 +978,9 @@ package.addModules([
.product(name: "SwiftLogConsoleColors", package: "swift-log-console-colors") {
.package(url: "https://github.com/nneuberger1/swift-log-console-colors", from: "1.0.3")
},
.product(name: "FileLogging", package: "swift-log-file") {
.package(url: "https://github.com/crspybits/swift-log-file", from: "0.1.0")
},
.product(name: "Tagged", package: "swift-tagged") {
.package(url: "https://github.com/pointfreeco/swift-tagged", exact: "0.10.0")
},
Expand Down
2 changes: 2 additions & 0 deletions Sources/Features/AppFeature/App+Reducer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ public struct App: Sendable, FeatureReducer {

public init(root: Root = .splash(.init())) {
self.root = root

loggerGlobal.info("App started")
}
}

Expand Down
59 changes: 57 additions & 2 deletions Sources/Features/GeneralSettings/GeneralSettings+View.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ extension GeneralSettings.State {
hasLedgerHardwareWalletFactorSources: hasLedgerHardwareWalletFactorSources,
useVerboseLedgerDisplayMode: (preferences?.display.ledgerHQHardwareWalletSigningDisplayMode ?? .default) == .verbose,
isDeveloperModeEnabled: preferences?.security.isDeveloperModeEnabled ?? false,
isCloudProfileSyncEnabled: preferences?.security.isCloudProfileSyncEnabled ?? false
isCloudProfileSyncEnabled: preferences?.security.isCloudProfileSyncEnabled ?? false,
isExportingLogs: exportLogs
)
}
}
Expand All @@ -21,6 +22,8 @@ extension GeneralSettings {

let isDeveloperModeEnabled: Bool
let isCloudProfileSyncEnabled: Bool

let isExportingLogs: URL?
}

@MainActor
Expand All @@ -43,9 +46,12 @@ extension GeneralSettings {

private func coreView(with viewStore: ViewStoreOf<GeneralSettings>) -> some SwiftUI.View {
VStack(spacing: .zero) {
VStack(spacing: .zero) {
VStack(alignment: .leading, spacing: .zero) {
isCloudProfileSyncEnabled(with: viewStore)
isDeveloperModeEnabled(with: viewStore)
if !RuntimeInfo.isAppStoreBuild {
exportLogs(with: viewStore)
}
if viewStore.hasLedgerHardwareWalletFactorSources {
isUsingVerboseLedgerMode(with: viewStore)
}
Expand Down Expand Up @@ -92,9 +98,58 @@ extension GeneralSettings {
)
)
}

private func exportLogs(with viewStore: ViewStoreOf<GeneralSettings>) -> some SwiftUI.View {
HStack {
VStack(alignment: .leading, spacing: 0) {
Text("Export Logs")
.foregroundColor(.app.gray1)
.textStyle(.body1HighImportance)

Text("Export the Wallet development logs")
.foregroundColor(.app.gray2)
.textStyle(.body2Regular)
.fixedSize()
}

Button("Export") {
viewStore.send(.exportLogsTapped)
}
.buttonStyle(.secondaryRectangular)
.flushedRight
}
.sheet(item:
viewStore.binding(
get: { $0.isExportingLogs },
send: { _ in .exportLogsDismissed }
)
) { logFilePath in
ShareView(items: [logFilePath])
}
.frame(height: .largeButtonHeight)
}
}
}

// MARK: - URL + Identifiable
extension URL: Identifiable {
public var id: URL { self.absoluteURL }
}

// MARK: - ShareView
// TODO: This is alternative to `ShareLink`, which does not seem to work properly. Eventually we should make use of it instead of this wrapper.
struct ShareView: UIViewControllerRepresentable {
typealias UIViewControllerType = UIActivityViewController

let items: [Any]

func makeUIViewController(context: Context) -> UIActivityViewController {
UIActivityViewController(activityItems: items, applicationActivities: nil)
}

func updateUIViewController(_ uiViewController: UIActivityViewController, context: Context) {}
}

#if DEBUG
import SwiftUI // NB: necessary for previews to appear

Expand Down
10 changes: 10 additions & 0 deletions Sources/Features/GeneralSettings/GeneralSettings.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import AppPreferencesClient
import FactorSourcesClient
import FeaturePrelude
import Logging

// MARK: - GeneralSettings
public struct GeneralSettings: Sendable, FeatureReducer {
Expand All @@ -9,6 +10,7 @@ public struct GeneralSettings: Sendable, FeatureReducer {
public var hasLedgerHardwareWalletFactorSources: Bool = false
@PresentationState
public var alert: Alerts.State?
var exportLogs: URL?

public init() {}
}
Expand All @@ -19,6 +21,8 @@ public struct GeneralSettings: Sendable, FeatureReducer {
case developerModeToggled(Bool)
case cloudProfileSyncToggled(Bool)
case alert(PresentationAction<Alerts.Action>)
case exportLogsTapped
case exportLogsDismissed
}

public enum InternalAction: Sendable, Equatable {
Expand Down Expand Up @@ -101,6 +105,12 @@ public struct GeneralSettings: Sendable, FeatureReducer {
return updateCloudSync(state: &state, isEnabled: false)
case .alert(.dismiss):
return .none
case .exportLogsTapped:
state.exportLogs = Logger.logFilePath
return .none
case .exportLogsDismissed:
state.exportLogs = nil
return .none
}
}

Expand Down
35 changes: 24 additions & 11 deletions Sources/Prelude/Logger.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import FileLogging
import Foundation
import Logging
import SwiftLogConsoleColors
import XCGLogger

private let baseLabel = "com.radixpublishing"

Expand All @@ -8,23 +11,33 @@ private func makeLogger(
level: Logger.Level = .debug
) -> Logger {
Logger(label: label) { _ in
#if DEBUG
var logger = ColorStreamLogHandler.standardOutput(
label: label,
logIconType: .rainbow
)
logger.logLevel = level
return logger
#else
// We globally disable all logging for non DEBUG builds
return SwiftLogNoOpLogHandler()
#endif // DEBUG
// FIXME: Instead of this, we should differentiate by build flavour. Waiting on SPM to support proper build flavours.
if !RuntimeInfo.isAppStoreBuild {
let fileLogger: LogHandler = {
guard let path = Logger.logFilePath,
let handler = try? FileLogHandler(label: label, localFile: path)
else {
return SwiftLogNoOpLogHandler()
}
return handler
}()

var logger = ColorStreamLogHandler.standardOutput(
label: label,
logIconType: .rainbow
)
logger.logLevel = level
return MultiplexLogHandler([fileLogger, logger])
} else {
return SwiftLogNoOpLogHandler()
}
}
}

public let loggerGlobal = makeLogger(label: baseLabel)

extension Logger {
public static let logFilePath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first?.appending(path: "appLogs.txt")
public func feature(
_ message: String,
marker: String = "feature",
Expand Down
23 changes: 23 additions & 0 deletions Sources/Prelude/RuntimeInfo.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import Foundation

// MARK: - RuntimeInfo
// Namespace
public enum RuntimeInfo {}

extension RuntimeInfo {
public static let isAppStoreBuild = !(isDebug || isRunningInTestFlightEnvironment)

public static let isDebug: Bool = {
#if DEBUG
return true
#else
return false
#endif
}()
}

extension RuntimeInfo {
private static let isAppStoreReceiptSandbox = Bundle.main.appStoreReceiptURL?.lastPathComponent == "sandboxReceipt"
private static let hasEmbeddedMobileProvision = Bundle.main.path(forResource: "embedded", ofType: "mobileprovision") != nil
private static let isRunningInTestFlightEnvironment = isAppStoreReceiptSandbox && !hasEmbeddedMobileProvision
}
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ actor DataChannelClient {
} logError: { error in
loggerGlobal.error("Critical: Could not decode the Incoming DataChannel message \(error)")
}
.logInfo("DataChannel: Received message %@")
.eraseToAnyAsyncSequence()
.share()
.eraseToAnyAsyncSequence()
Expand All @@ -95,6 +96,8 @@ actor DataChannelClient {
try sendMessageOverDataChannel(.chunkedMessage($0))
}

loggerGlobal.info("DataChannel: Sent message \(assembledMessage)")

// TODO: Add timeout. What to do in case of timeout -> throw error? recend the message?
try await waitForMessageConfirmation(id)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ extension AsyncWebSocket {
receiveMessagesTask = Task {
try? Task.checkCancellation()
guard !Task.isCancelled else {
loggerGlobal.debug("WebSocket: Aborting receive messages, task cancelled.")
loggerGlobal.info("WebSocket: Aborting receive messages, task cancelled.")
return
}

Expand Down Expand Up @@ -158,7 +158,7 @@ extension AsyncWebSocket {
try? await clock.sleep(for: .seconds(Config.default.pingInterval))
try? Task.checkCancellation()
guard !Task.isCancelled else {
loggerGlobal.debug("WebSocket: Aborting ping, task cancelled.")
loggerGlobal.info("WebSocket: Aborting ping, task cancelled.")
return
}

Expand Down Expand Up @@ -237,12 +237,12 @@ extension AsyncWebSocket {
Task {
await self.invalidateAndRestartSession()
}
}, onOpen: { [weak self] in
}, onOpen: { [weak self, url = self.url] in
guard let self else { return }
Task {
await self.receiveMessages()
await self.sendPingContinuously()
loggerGlobal.info("WebSocket: Session Started")
loggerGlobal.info("WebSocket: Session Started for URL \(url)")
}
})

Expand Down Expand Up @@ -271,21 +271,21 @@ extension AsyncWebSocket {
webSocketTask: URLSessionWebSocketTask,
didOpenWithProtocol protocol: String?
) {
loggerGlobal.debug("websocket task=\(webSocketTask.taskIdentifier) didOpenWithProtocol: \(String(describing: `protocol`))")
loggerGlobal.info("websocket task=\(webSocketTask.taskIdentifier) didOpenWithProtocol: \(String(describing: `protocol`))")
onOpen()
}

// MARK: - Close events

func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
loggerGlobal.debug("WebSocket: Task failed with error \(String(describing: error))")
loggerGlobal.info("WebSocket: Task failed with error \(String(describing: error))")
onClose()
}

// MARK: - Connectivity

func urlSession(_ session: URLSession, taskIsWaitingForConnectivity task: URLSessionTask) {
loggerGlobal.debug("WebSocket: Internet connection seems to be down, waiting for connectivity")
loggerGlobal.info("WebSocket: Internet connection seems to be down, waiting for connectivity")
}
}
}

0 comments on commit b2f39c9

Please sign in to comment.