Skip to content

Commit 8d88525

Browse files
committed
feat(preferences): allow generating support report
1 parent 0ceb865 commit 8d88525

17 files changed

Lines changed: 592 additions & 149 deletions

McBopomofo.xcodeproj/project.pbxproj

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
6AFF97F2253B299E007F1C49 /* NonModalAlertWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6AFF97F0253B299E007F1C49 /* NonModalAlertWindowController.xib */; };
4040
B058C5272AC9DF51002EDD66 /* ServiceProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = B058C5262AC9DF51002EDD66 /* ServiceProvider.swift */; };
4141
B0781B352ACA2655003D9F75 /* ServicesMenu.strings in Resources */ = {isa = PBXBuildFile; fileRef = B0781B372ACA2655003D9F75 /* ServicesMenu.strings */; };
42+
D40EFFA22EB669F900C1728A /* InfoCollector in Frameworks */ = {isa = PBXBuildFile; productRef = D40EFFA12EB669F900C1728A /* InfoCollector */; };
4243
D41355D8278D74B5005E5CBD /* LanguageModelManager.mm in Sources */ = {isa = PBXBuildFile; fileRef = D41355D7278D7409005E5CBD /* LanguageModelManager.mm */; };
4344
D41355DB278E6D17005E5CBD /* McBopomofoLM.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D41355D9278E6D17005E5CBD /* McBopomofoLM.cpp */; };
4445
D41355DE278EA3ED005E5CBD /* UserPhrasesLM.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D41355DC278EA3ED005E5CBD /* UserPhrasesLM.cpp */; };
@@ -177,6 +178,7 @@
177178
B058C5262AC9DF51002EDD66 /* ServiceProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServiceProvider.swift; sourceTree = "<group>"; };
178179
B0781B362ACA2655003D9F75 /* en */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/ServicesMenu.strings; sourceTree = "<group>"; };
179180
B0781B382ACA2659003D9F75 /* zh-Hant */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = "zh-Hant"; path = "zh-Hant.lproj/ServicesMenu.strings"; sourceTree = "<group>"; };
181+
D40EFFA02EB669BB00C1728A /* InfoCollector */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = InfoCollector; path = Packages/InfoCollector; sourceTree = "<group>"; };
180182
D41355D6278D7409005E5CBD /* LanguageModelManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LanguageModelManager.h; sourceTree = "<group>"; };
181183
D41355D7278D7409005E5CBD /* LanguageModelManager.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = LanguageModelManager.mm; sourceTree = "<group>"; };
182184
D41355D9278E6D17005E5CBD /* McBopomofoLM.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = McBopomofoLM.cpp; sourceTree = "<group>"; };
@@ -258,6 +260,7 @@
258260
D48F853E2EACDB6C00C2FDAB /* RomanNumbers in Frameworks */,
259261
D4E7917A2B52CDE500676A68 /* ChineseNumbers in Frameworks */,
260262
D427F76A278C9E29004A2160 /* CandidateUI in Frameworks */,
263+
D40EFFA22EB669F900C1728A /* InfoCollector in Frameworks */,
261264
D4C9CAB127AAC9690058DFEA /* NSStringUtils in Frameworks */,
262265
D427F7AE27907B8A004A2160 /* NotifierUI in Frameworks */,
263266
D41B626C2B86EAE900583148 /* BopomofoBraille in Frameworks */,
@@ -459,6 +462,7 @@
459462
D427F766278C9CBD004A2160 /* Packages */ = {
460463
isa = PBXGroup;
461464
children = (
465+
D40EFFA02EB669BB00C1728A /* InfoCollector */,
462466
D4E5EEE22E68A9B30068BC58 /* SystemCharacterInfo */,
463467
D41B626A2B86EAD400583148 /* BopomofoBraille */,
464468
D4E791782B52CDCF00676A68 /* ChineseNumbers */,
@@ -544,6 +548,7 @@
544548
D41B626B2B86EAE900583148 /* BopomofoBraille */,
545549
D4451AC82E688C6B00E8F5AB /* SystemCharacterInfo */,
546550
D48F853D2EACDB6C00C2FDAB /* RomanNumbers */,
551+
D40EFFA12EB669F900C1728A /* InfoCollector */,
547552
);
548553
productName = McBopomofo;
549554
productReference = 6A0D4EA215FC0D2D00ABF4B3 /* McBopomofo.app */;
@@ -1436,6 +1441,10 @@
14361441
/* End XCConfigurationList section */
14371442

14381443
/* Begin XCSwiftPackageProductDependency section */
1444+
D40EFFA12EB669F900C1728A /* InfoCollector */ = {
1445+
isa = XCSwiftPackageProductDependency;
1446+
productName = InfoCollector;
1447+
};
14391448
D41B626B2B86EAE900583148 /* BopomofoBraille */ = {
14401449
isa = XCSwiftPackageProductDependency;
14411450
productName = BopomofoBraille;

Packages/InfoCollector/Package.swift

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
1-
// swift-tools-version: 6.2
1+
// swift-tools-version: 5.9
22
// The swift-tools-version declares the minimum version of Swift required to build this package.
33

44
import PackageDescription
55

66
let package = Package(
77
name: "InfoCollector",
8-
platforms: [
9-
.macOS(.v13)
10-
],
118
products: [
129
// Products define the executables and libraries a package produces, making them visible to other packages.
1310
.library(

Packages/InfoCollector/Sources/InfoCollector/InfoCollector.swift

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,41 @@
1-
import Foundation
1+
// Copyright (c) 2022 and onwards The McBopomofo Authors.
2+
//
3+
// Permission is hereby granted, free of charge, to any person
4+
// obtaining a copy of this software and associated documentation
5+
// files (the "Software"), to deal in the Software without
6+
// restriction, including without limitation the rights to use,
7+
// copy, modify, merge, publish, distribute, sublicense, and/or sell
8+
// copies of the Software, and to permit persons to whom the
9+
// Software is furnished to do so, subject to the following
10+
// conditions:
11+
//
12+
// The above copyright notice and this permission notice shall be
13+
// included in all copies or substantial portions of the Software.
14+
//
15+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16+
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17+
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18+
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19+
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20+
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21+
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22+
// OTHER DEALINGS IN THE SOFTWARE.
223

3-
// MARK: -
24+
import Foundation
425

526
@objc
627
public class InfoCollector: NSObject {
28+
@MainActor
29+
@available(iOS 13.0.0, macOS 10.15, *)
30+
public static func generate() async -> String {
31+
await withCheckedContinuation { (continuation: CheckedContinuation<String, Never>) in
32+
InfoCollector.generate { string in
33+
continuation.resume(returning: string)
34+
}
35+
}
36+
}
37+
38+
@MainActor
739
public static func generate(callback: @escaping (String) -> Void) {
840
let plugins: [InfoCollectorPlugin] = [
941
MachineModelCollectorPlugin(),
@@ -13,6 +45,7 @@ public class InfoCollector: NSObject {
1345
ActiveInputSourceListCollectorPlugin(),
1446
DefaultWebBrowserCollectorPlugin(),
1547
SafaruVersionCollectorPlugin(),
48+
AppVersionCollectorPlugin(),
1649
]
1750

1851
let group = DispatchGroup()

Packages/InfoCollector/Sources/InfoCollector/InfoCollectorPlugin.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
protocol InfoCollectorPlugin {
22
var name: String { get }
33
func collect(callback: @escaping (Result<String, Error>) -> Void)
4-
@available(iOS 13.0.0, *)
4+
@available(iOS 13.0.0, macOS 10.15, *)
55
func collect() async throws -> String
66
}
77

88
extension InfoCollectorPlugin {
9-
@available(iOS 13.0.0, *)
9+
@available(iOS 13.0.0, macOS 10.15, *)
1010
func collect() async throws -> String {
1111
try await withCheckedThrowingContinuation {
1212
(continuation: CheckedContinuation<String, Error>) in

Packages/InfoCollector/Sources/InfoCollector/Plugins/ActiveInputSourceListCollectorPlugin.swift

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,26 @@
1+
// Copyright (c) 2022 and onwards The McBopomofo Authors.
2+
//
3+
// Permission is hereby granted, free of charge, to any person
4+
// obtaining a copy of this software and associated documentation
5+
// files (the "Software"), to deal in the Software without
6+
// restriction, including without limitation the rights to use,
7+
// copy, modify, merge, publish, distribute, sublicense, and/or sell
8+
// copies of the Software, and to permit persons to whom the
9+
// Software is furnished to do so, subject to the following
10+
// conditions:
11+
//
12+
// The above copyright notice and this permission notice shall be
13+
// included in all copies or substantial portions of the Software.
14+
//
15+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16+
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17+
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18+
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19+
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20+
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21+
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22+
// OTHER DEALINGS IN THE SOFTWARE.
23+
124
import AppKit
225
import Carbon.HIToolbox
326
import Foundation
@@ -9,26 +32,20 @@ struct ActiveInputSourceListCollectorPlugin: InfoCollectorPlugin {
932
func getStringValue(_ source: TISInputSource, _ property: CFString) -> String? {
1033
if let valuePts = TISGetInputSourceProperty(source, property) {
1134
let value = Unmanaged<CFString>.fromOpaque(valuePts).takeUnretainedValue()
12-
return value as? String
35+
return String(value)
1336
}
1437
return nil
1538
}
1639

1740
// Use HIToolbox TIS APIs to get current and enabled input sources
1841
// Build a query for enabled input sources
1942
let keys: [CFString: Any] = [
20-
kTISPropertyInputSourceIsEnabled: true as CFBoolean
43+
kTISPropertyInputSourceIsEnabled: kCFBooleanTrue as CFBoolean,
44+
kTISPropertyInputSourceIsSelectCapable: kCFBooleanTrue as CFBoolean,
45+
kTISPropertyInputSourceCategory: kTISCategoryKeyboardInputSource as CFString,
2146
]
2247
let dict = keys as CFDictionary
2348
var lines: [String] = []
24-
25-
// // Current input source
26-
// if let current = TISCopyCurrentKeyboardInputSource()?.takeRetainedValue() {
27-
// let currentName = getStringValue(current, kTISPropertyLocalizedName)
28-
// let currentID = getStringValue(current, kTISPropertyInputSourceID)
29-
// lines.append("- Current Input Source: \(currentName ?? "<unknown>") (\(currentID ?? ""))")
30-
// }
31-
3249
// Enabled input sources
3350
if let list = TISCreateInputSourceList(dict, false)?.takeRetainedValue()
3451
as? [TISInputSource]
@@ -37,7 +54,11 @@ struct ActiveInputSourceListCollectorPlugin: InfoCollectorPlugin {
3754
for src in list {
3855
let name = getStringValue(src, kTISPropertyLocalizedName) ?? "<unknown>"
3956
let sid = getStringValue(src, kTISPropertyInputSourceID) ?? ""
40-
let category = getStringValue(src, kTISPropertyInputSourceCategory) as? String ?? ""
57+
let category =
58+
getStringValue(
59+
src,
60+
kTISPropertyInputSourceCategory
61+
) ?? ""
4162
lines.append(" - \(name) (\(sid)) [\(category)]")
4263
}
4364
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// Copyright (c) 2022 and onwards The McBopomofo Authors.
2+
//
3+
// Permission is hereby granted, free of charge, to any person
4+
// obtaining a copy of this software and associated documentation
5+
// files (the "Software"), to deal in the Software without
6+
// restriction, including without limitation the rights to use,
7+
// copy, modify, merge, publish, distribute, sublicense, and/or sell
8+
// copies of the Software, and to permit persons to whom the
9+
// Software is furnished to do so, subject to the following
10+
// conditions:
11+
//
12+
// The above copyright notice and this permission notice shall be
13+
// included in all copies or substantial portions of the Software.
14+
//
15+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16+
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17+
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18+
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19+
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20+
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21+
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22+
// OTHER DEALINGS IN THE SOFTWARE.
23+
24+
import Foundation
25+
26+
public struct AppVersionCollectorPlugin: InfoCollectorPlugin, Sendable {
27+
var name: String { "App version collector" }
28+
29+
func collect(callback: @escaping (Result<String, Error>) -> Void) {
30+
let bundle = Bundle.main
31+
let version =
32+
bundle.object(forInfoDictionaryKey: "CFBundleShortVersionString") as? String ?? "N/A"
33+
let build =
34+
bundle.object(forInfoDictionaryKey: kCFBundleVersionKey as String) as? String ?? "N/A"
35+
36+
var result: [String] = []
37+
result.append("- App Version: \(version)")
38+
result.append("- App Build: \(build)")
39+
let string = result.joined(separator: "\n")
40+
callback(.success(string))
41+
}
42+
43+
}

Packages/InfoCollector/Sources/InfoCollector/Plugins/DefaultWebBrowserCollectorPlugin.swift

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,26 @@
1+
// Copyright (c) 2022 and onwards The McBopomofo Authors.
2+
//
3+
// Permission is hereby granted, free of charge, to any person
4+
// obtaining a copy of this software and associated documentation
5+
// files (the "Software"), to deal in the Software without
6+
// restriction, including without limitation the rights to use,
7+
// copy, modify, merge, publish, distribute, sublicense, and/or sell
8+
// copies of the Software, and to permit persons to whom the
9+
// Software is furnished to do so, subject to the following
10+
// conditions:
11+
//
12+
// The above copyright notice and this permission notice shall be
13+
// included in all copies or substantial portions of the Software.
14+
//
15+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16+
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17+
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18+
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19+
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20+
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21+
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22+
// OTHER DEALINGS IN THE SOFTWARE.
23+
124
import AppKit
225

326
struct DefaultWebBrowserCollectorPlugin: InfoCollectorPlugin {

Packages/InfoCollector/Sources/InfoCollector/Plugins/KeyboardTypeCollectorPlugin.swift

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,26 @@
1+
// Copyright (c) 2022 and onwards The McBopomofo Authors.
2+
//
3+
// Permission is hereby granted, free of charge, to any person
4+
// obtaining a copy of this software and associated documentation
5+
// files (the "Software"), to deal in the Software without
6+
// restriction, including without limitation the rights to use,
7+
// copy, modify, merge, publish, distribute, sublicense, and/or sell
8+
// copies of the Software, and to permit persons to whom the
9+
// Software is furnished to do so, subject to the following
10+
// conditions:
11+
//
12+
// The above copyright notice and this permission notice shall be
13+
// included in all copies or substantial portions of the Software.
14+
//
15+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16+
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17+
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18+
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19+
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20+
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21+
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22+
// OTHER DEALINGS IN THE SOFTWARE.
23+
124
import Carbon
225
import Foundation
326
import IOKit

Packages/InfoCollector/Sources/InfoCollector/Plugins/MacVersionCollectorPlugin.swift

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,26 @@
1+
// Copyright (c) 2022 and onwards The McBopomofo Authors.
2+
//
3+
// Permission is hereby granted, free of charge, to any person
4+
// obtaining a copy of this software and associated documentation
5+
// files (the "Software"), to deal in the Software without
6+
// restriction, including without limitation the rights to use,
7+
// copy, modify, merge, publish, distribute, sublicense, and/or sell
8+
// copies of the Software, and to permit persons to whom the
9+
// Software is furnished to do so, subject to the following
10+
// conditions:
11+
//
12+
// The above copyright notice and this permission notice shall be
13+
// included in all copies or substantial portions of the Software.
14+
//
15+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16+
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17+
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18+
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19+
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20+
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21+
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22+
// OTHER DEALINGS IN THE SOFTWARE.
23+
124
import AppKit
225

326
struct MacVersionCollectorPlugin: InfoCollectorPlugin {

0 commit comments

Comments
 (0)