Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions mac/Config/Config.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

/* Begin PBXBuildFile section */
D83272A82F57614400F71698 /* KeymanSettings in Frameworks */ = {isa = PBXBuildFile; productRef = D83272A72F57614400F71698 /* KeymanSettings */; };
D88B79CA30472B3B00F10D14 /* Sentry-Dynamic in Frameworks */ = {isa = PBXBuildFile; productRef = D88B79C930472B3B00F10D14 /* Sentry-Dynamic */; };
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
Expand Down Expand Up @@ -70,6 +71,7 @@
buildActionMask = 2147483647;
files = (
D83272A82F57614400F71698 /* KeymanSettings in Frameworks */,
D88B79CA30472B3B00F10D14 /* Sentry-Dynamic in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -140,6 +142,7 @@
name = Config;
packageProductDependencies = (
D83272A72F57614400F71698 /* KeymanSettings */,
D88B79C930472B3B00F10D14 /* Sentry-Dynamic */,
);
productName = Config;
productReference = D88F03C62F50ED5000C02A31 /* Keyman Configuration.app */;
Expand Down Expand Up @@ -220,6 +223,9 @@
);
mainGroup = D88F03BD2F50ED5000C02A31;
minimizedProjectReferenceProxies = 1;
packageReferences = (
D88B79C830472B3B00F10D14 /* XCRemoteSwiftPackageReference "sentry-cocoa" */,
);
preferredProjectObjectVersion = 77;
productRefGroup = D88F03C72F50ED5000C02A31 /* Products */;
projectDirPath = "";
Expand Down Expand Up @@ -629,11 +635,27 @@
};
/* End XCConfigurationList section */

/* Begin XCRemoteSwiftPackageReference section */
D88B79C830472B3B00F10D14 /* XCRemoteSwiftPackageReference "sentry-cocoa" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/getsentry/sentry-cocoa.git";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = 9.26.1;
};
};
/* End XCRemoteSwiftPackageReference section */

/* Begin XCSwiftPackageProductDependency section */
D83272A72F57614400F71698 /* KeymanSettings */ = {
isa = XCSwiftPackageProductDependency;
productName = KeymanSettings;
};
D88B79C930472B3B00F10D14 /* Sentry-Dynamic */ = {
isa = XCSwiftPackageProductDependency;
package = D88B79C830472B3B00F10D14 /* XCRemoteSwiftPackageReference "sentry-cocoa" */;
productName = "Sentry-Dynamic";
};
/* End XCSwiftPackageProductDependency section */
};
rootObject = D88F03BE2F50ED5000C02A31 /* Project object */;
Expand Down
11 changes: 7 additions & 4 deletions mac/Config/Config/AddKeyboardView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

import SwiftUI
import KeymanSettings
import OSLog

struct AddKeyboardView: View {
@EnvironmentObject var settings: SettingsContainer
Expand Down Expand Up @@ -52,7 +53,7 @@ struct AddKeyboardView: View {
// Placement determines where on the bar it sits
ToolbarItem(placement: .cancellationAction) {
Button("Close") {
print("close button clicked")
Logger.app.debug("AddKeyboardView close button clicked")
dismissAddKeyboardView()
if settings.isInstallationInProgress() {
settings.userCanceledPackageInstallation()
Expand All @@ -61,7 +62,7 @@ struct AddKeyboardView: View {
}
}
.onDisappear {
print("AddKeyboardView onDisappear")
Logger.app.debug("AddKeyboardView onDisappear")
downloadCoordinator.cancelActiveDownload()
}
.alert("Package Installation Failed", isPresented: $downloadCoordinator.loadPackageFailed) {
Expand All @@ -75,11 +76,13 @@ struct AddKeyboardView: View {
if let helper = downloadCoordinator.installHelper {
PackageConfirmationView(installHelper: helper) { accepted in
if accepted {
print("installing validated package: \(helper.packageName ?? "unknown package")")
Logger.download.info("installing validated package: \(helper.packageName ?? "unknown package", privacy: .public)")
LogUtil.infoBreadcrumb("installing validated package: \(helper.packageName ?? "unknown package")", category: .download)
do {
try settings.installPackage()
} catch {
print("failed to install package: \(helper.packageName ?? "unknown package") with error: \(error.localizedDescription)")
Logger.download.error("failed to install package: \(helper.packageName ?? "unknown package") with error: \(error as NSError, privacy: .public)")
LogUtil.errorBreadcrumb("failed to install package: \(helper.packageName ?? "unknown package") with error: \(error as NSError)", category: .download)
}
} else {
settings.userCanceledPackageInstallation()
Expand Down
14 changes: 11 additions & 3 deletions mac/Config/Config/ConfigApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@
import SwiftUI
import KeymanSettings
import OSLog
import Sentry

extension Logger {
private static let configSubsystem = ConfigAppUtil.configBundleId
static let package = Logger(subsystem: configSubsystem, category: "package")
static let app = Logger(subsystem: configSubsystem, category: "app")
static let download = Logger(subsystem: configSubsystem, category: "download")
static let ui = Logger(subsystem: configSubsystem, category: "ui")
}

@main
Expand All @@ -24,7 +24,15 @@ struct ConfigApp: App {
@Environment(\.openWindow) private var openWindow

init() {
print("tier: \(ConfigAppUtil.appTier)")
Logger.app.log("Starting Keyman Configuration, version: \(ConfigAppUtil.versionWithTag), versionWithTag: \(ConfigAppUtil.versionWithTag)")
let sentryDsnUrl = "https://960f8b8e574c46e3be385d60ce8e1fea@o1005580.ingest.sentry.io/5983522"

// Initialize Sentry only once here
SentrySDK.start { options in
options.dsn = sentryDsnUrl
options.releaseName = ConfigAppUtil.versionGitTag
options.environment = ConfigAppUtil.sentryEnvironment
}
}

var body: some Scene {
Expand Down
25 changes: 18 additions & 7 deletions mac/Config/Config/DownloadCoordinator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public class DownloadCoordinator: NSObject, ObservableObject, WKNavigationDelega
decisionHandler(.cancel)
return
}
Logger.download.info("received url: \(urlString, privacy: .public)")
Logger.download.log("received url: \(urlString, privacy: .public)")

// if the url matches the install url pattern, then cancel the request,
// build the standard URLRequest for a package installation and send it
Expand All @@ -58,13 +58,15 @@ public class DownloadCoordinator: NSObject, ObservableObject, WKNavigationDelega
// get the package id (though it appears to be identifying a keyboard in the URL)
let matchPackageId = String(match.4)
if let downloadUrl = self.settings?.buildDownloadPackageUrl(for: matchPackageId) {
Logger.download.info("package install, download url = \(downloadUrl.absoluteString, privacy: .public)")

Logger.download.info("package install, download url = \(downloadUrl.cleanUrlPath(), privacy: .public)")
LogUtil.infoBreadcrumb("package install, download url = \(downloadUrl.cleanUrlPath())", category: .download)

let newRequest = URLRequest(url: downloadUrl)

DispatchQueue.main.async {
webView.startDownload(using: newRequest) { download in
Logger.download.info("download initiated to \(newRequest.url?.absoluteString ?? "nil", privacy: .public)")
Logger.download.info("download initiated to \(newRequest.url?.cleanUrlPath() ?? "nil", privacy: .public)")
LogUtil.infoBreadcrumb("download initiated to \(newRequest.url?.cleanUrlPath() ?? "nil")", category: .download)
download.delegate = self
self.setupDownloadTracking(download)
}
Expand All @@ -74,11 +76,13 @@ public class DownloadCoordinator: NSObject, ObservableObject, WKNavigationDelega
else if urlString.contains(DownloadCoordinator.regexRoot) ||
urlString.contains(DownloadCoordinator.regexGo) {
Logger.download.info("requested root or go url: load in webview")
LogUtil.infoBreadcrumb("requested root or go url: load in webview", category: .download)

decisionHandler(.allow)
}
else {
Logger.download.info("default case, open in external browser")
LogUtil.infoBreadcrumb("default case, open in external browser", category: .download)

decisionHandler(.cancel)
if let targetUrl = URL(string: urlString) {
Expand Down Expand Up @@ -126,6 +130,7 @@ public class DownloadCoordinator: NSObject, ObservableObject, WKNavigationDelega

guard let keymanSettings = self.settings else {
Logger.download.error("tried to access settings before they were intialized")
LogUtil.errorBreadcrumb("tried to access settings before they were intialized", category: .download)
self.loadPackageFailed = true
self.loadFailureMessage = InstallPackageError.internalError.localizedDescription
completionHandler(nil)
Expand All @@ -138,6 +143,7 @@ public class DownloadCoordinator: NSObject, ObservableObject, WKNavigationDelega
do {
if let helper = try keymanSettings.initiateKmpFileDownload(kmpFilename: suggestedFilename) {
Logger.download.info("download suggested filename: \(suggestedFilename, privacy: .public)")
LogUtil.infoBreadcrumb("download suggested filename: \(suggestedFilename)", category: .download)
self.loadFailureMessage = nil // Reset previous error
self.loadPackageFailed = false

Expand All @@ -146,7 +152,8 @@ public class DownloadCoordinator: NSObject, ObservableObject, WKNavigationDelega
completionHandler(helper.temporaryKmpFileLocation)
}
} catch {
Logger.download.error("could not initiate package download, error: \(String(describing: error), privacy: .public)")
Logger.download.error("could not initiate package download, error: \(error as NSError, privacy: .public)")
LogUtil.errorBreadcrumb("could not initiate package download, error: \(error as NSError)", category: .download)
self.loadPackageFailed = true
self.loadFailureMessage = error.localizedDescription
completionHandler(nil)
Expand All @@ -158,7 +165,9 @@ public class DownloadCoordinator: NSObject, ObservableObject, WKNavigationDelega
self.progressObserver = nil

if let downloadDestination = installHelper?.temporaryKmpFileLocation {
Logger.download.info("download of \(downloadDestination.path, privacy: .public) was successful.")
Logger.download.info("download of \(downloadDestination.cleanUrlPath(), privacy: .public) was successful.")
LogUtil.infoBreadcrumb("download of \(downloadDestination.cleanUrlPath()) was successful.", category: .download)

if let settings {
do {
try settings.packageDownloadComplete(kmpFileUrl: downloadDestination)
Expand All @@ -173,7 +182,8 @@ public class DownloadCoordinator: NSObject, ObservableObject, WKNavigationDelega
}

public func download(_ download: WKDownload, didFailWithError error: Error, resumeData: Data?) {
Logger.download.error("download failed with error: \(String(describing: error), privacy: .public)")
Logger.download.error("download failed with error: \(error as NSError, privacy: .public)")
LogUtil.errorBreadcrumb("download failed with error: \(error as NSError)", category: .download)
self.isDownloading = false
self.progressObserver = nil
self.loadPackageFailed = true
Expand All @@ -187,6 +197,7 @@ public class DownloadCoordinator: NSObject, ObservableObject, WKNavigationDelega
public func webViewWebContentProcessDidTerminate(_ webView: WKWebView) {
// The web process crashed. Reload the webview safely.
Logger.download.error("webkit process terminated unexpectedly: reloading content")
LogUtil.errorBreadcrumb("webkit process terminated unexpectedly: reloading content", category: .download)
webView.reload()
}
}
6 changes: 0 additions & 6 deletions mac/Config/Config/InstallDebugView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,7 @@ struct InstallDebugView: View {
_ = installation.validateUserHasRestarted()
}
Button("Set Displayed Complete") {
let beforeDisplayed = installation.getHasDisplayedInstallationComplete()
installation.setHasDisplayedInstallationComplete()
let afterDisplayed = installation.getHasDisplayedInstallationComplete()
print("hasDisplayedInstallComplete = \(beforeDisplayed) -> \(afterDisplayed)")
}
Button("debug") {
installation.debug()
Expand All @@ -76,9 +73,6 @@ struct InstallDebugView: View {
Button("Kill Keyman") {
_ = installation.killKeymanInputMethod()
}
Button("Uninstall") {
installation.uninstall()
}
Spacer()
}
.padding()
Expand Down
6 changes: 4 additions & 2 deletions mac/Config/Config/KeyboardSearchView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import SwiftUI
import Combine
import WebKit
import KeymanSettings
import OSLog

struct KeyboardSearchView: NSViewRepresentable {
@ObservedObject var coordinator: DownloadCoordinator
Expand All @@ -22,7 +23,8 @@ struct KeyboardSearchView: NSViewRepresentable {

/** Creates the underlying NSView (WKWebView) for macOS */
func makeNSView(context: Context) -> WKWebView {
print("makeNSView called")
Logger.app.debug("KeyboardSearchView makeNSView called")

let webView = WKWebView()

// assign the coordinator as the navigation delegate
Expand All @@ -41,7 +43,7 @@ struct KeyboardSearchView: NSViewRepresentable {
func updateNSView(_ nsView: WKWebView, context: Context) {
if coordinator.settings == nil {
coordinator.settings = self.settings
print("updateNSView, settings intialized for coordinator")
Logger.app.debug("KeyboardSearchView updateNSView, settings intialized for coordinator")
}
}
}
Expand Down
24 changes: 20 additions & 4 deletions mac/Config/Config/MainConfigView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

import SwiftUI
import KeymanSettings
import OSLog
import Sentry

struct MainConfigView: View {

Expand Down Expand Up @@ -54,7 +56,17 @@ struct MainConfigView: View {
var body: some View {
TabView (selection: $selectedTab) {
VStack {
// the add keyboard button
// uncomment this Button to force sentry error (must edit scheme and disable 'Debug executable' to test)
/*
Button("Capture Sentry Error") {
let testError = NSError(domain: "SentryTest", code: 404, userInfo: [NSLocalizedDescriptionKey: "Testing Sentry from Keyman Config on Mac"])
SentrySDK.capture(error: testError)
}
.padding()
.buttonStyle(.borderedProminent)
.tint(.red)
*/
// the add keyboard button
LabelButtonView(
action: { isShowingAddKeyboardSheet = true },
label: "Add Keyboard",
Expand Down Expand Up @@ -96,7 +108,9 @@ struct MainConfigView: View {
) {
Button("Delete", role: .destructive) {
if let uuid = idToDelete {
print("deleting package.id: \(uuid)")
Logger.app.info("deleting package.id: \(uuid)")
LogUtil.infoBreadcrumb("deleting package.id: \(uuid)", category: .app)

// use multiple expanded states?
//expandedStates.removeValue(forKey: uuid)

Expand Down Expand Up @@ -156,13 +170,15 @@ struct MainConfigView: View {
packageInstallHelper = nil

if accepted {
print("installing validated package: \(helper.packageName ?? "unknown package")")
Logger.app.info("installing validated package: \(helper.packageName ?? "unknown package", privacy: .public)")
LogUtil.infoBreadcrumb("installing validated package: \(helper.packageName ?? "unknown package")", category: .app)
do {
try settings.installPackage()
} catch {
self.alertMessage = error.localizedDescription
self.isShowingDropKmpAlert = true
print("failed to install package: \(helper.packageName ?? "unknown package") with error: \(error.localizedDescription)")
Logger.app.error("failed to install package: \(helper.packageName ?? "unknown package", privacy: .public), error: \(error as NSError, privacy: .public)")
LogUtil.errorBreadcrumb("failed to install package: \(helper.packageName ?? "unknown package"), error: \(error)", category: .app)
}
} else {
settings.userCanceledPackageInstallation()
Expand Down
Loading