@capgo/capacitor-device-info 8.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CapgoCapacitorDeviceInfo.podspec +17 -0
- package/LICENSE +373 -0
- package/Package.swift +28 -0
- package/README.md +426 -0
- package/android/build.gradle +59 -0
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/java/app/capgo/deviceinfo/DeviceInfo.java +765 -0
- package/android/src/main/java/app/capgo/deviceinfo/DeviceInfoPlugin.java +195 -0
- package/android/src/main/res/.gitkeep +0 -0
- package/dist/docs.json +1285 -0
- package/dist/esm/definitions.d.ts +612 -0
- package/dist/esm/definitions.js +2 -0
- package/dist/esm/definitions.js.map +1 -0
- package/dist/esm/index.d.ts +4 -0
- package/dist/esm/index.js +7 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/web.d.ts +29 -0
- package/dist/esm/web.js +182 -0
- package/dist/esm/web.js.map +1 -0
- package/dist/plugin.cjs.js +196 -0
- package/dist/plugin.cjs.js.map +1 -0
- package/dist/plugin.js +199 -0
- package/dist/plugin.js.map +1 -0
- package/ios/Sources/DeviceInfoPlugin/DeviceInfo.swift +279 -0
- package/ios/Sources/DeviceInfoPlugin/DeviceInfoPlugin.swift +157 -0
- package/ios/Tests/DeviceInfoPluginTests/DeviceInfoTests.swift +22 -0
- package/package.json +95 -0
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
import CoreMotion
|
|
2
|
+
import Darwin
|
|
3
|
+
import Foundation
|
|
4
|
+
import Metal
|
|
5
|
+
|
|
6
|
+
@objc public class DeviceInfo: NSObject {
|
|
7
|
+
private var previousCpuLoad: host_cpu_load_info?
|
|
8
|
+
|
|
9
|
+
@objc public func getInfo() -> [String: Any] {
|
|
10
|
+
var result: [String: Any] = [
|
|
11
|
+
"timestamp": currentTimestamp(),
|
|
12
|
+
"platform": "ios",
|
|
13
|
+
"cpu": cpuInfo(),
|
|
14
|
+
"memory": memoryInfo(),
|
|
15
|
+
"storage": storageInfo(),
|
|
16
|
+
"thermalState": thermalState(),
|
|
17
|
+
"lowPowerMode": ProcessInfo.processInfo.isLowPowerModeEnabled,
|
|
18
|
+
"sensors": onboardSensorsInfo()
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
if let gpu = gpuInfo() {
|
|
22
|
+
result["gpu"] = gpu
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return result
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
@objc public func getPluginVersion() -> String {
|
|
29
|
+
return "8.0.0"
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
private func cpuInfo() -> [String: Any] {
|
|
33
|
+
var info: [String: Any] = [
|
|
34
|
+
"cores": ProcessInfo.processInfo.processorCount,
|
|
35
|
+
"activeCores": ProcessInfo.processInfo.activeProcessorCount,
|
|
36
|
+
"architecture": cpuArchitecture(),
|
|
37
|
+
"model": modelIdentifier()
|
|
38
|
+
]
|
|
39
|
+
|
|
40
|
+
if let usagePercent = cpuUsagePercent() {
|
|
41
|
+
info["usagePercent"] = usagePercent
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return info
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
private func cpuUsagePercent() -> Double? {
|
|
48
|
+
guard let currentLoad = currentCpuLoad() else {
|
|
49
|
+
return nil
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
defer {
|
|
53
|
+
previousCpuLoad = currentLoad
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
guard let previousLoad = previousCpuLoad else {
|
|
57
|
+
return nil
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
let user = tickDelta(currentLoad.cpu_ticks.0, previousLoad.cpu_ticks.0)
|
|
61
|
+
let system = tickDelta(currentLoad.cpu_ticks.1, previousLoad.cpu_ticks.1)
|
|
62
|
+
let idle = tickDelta(currentLoad.cpu_ticks.2, previousLoad.cpu_ticks.2)
|
|
63
|
+
let nice = tickDelta(currentLoad.cpu_ticks.3, previousLoad.cpu_ticks.3)
|
|
64
|
+
let total = user + system + idle + nice
|
|
65
|
+
|
|
66
|
+
guard total > 0 else {
|
|
67
|
+
return nil
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return clampPercent((Double(total - idle) / Double(total)) * 100)
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
private func currentCpuLoad() -> host_cpu_load_info? {
|
|
74
|
+
var cpuInfo = host_cpu_load_info()
|
|
75
|
+
var count = mach_msg_type_number_t(MemoryLayout<host_cpu_load_info>.stride / MemoryLayout<integer_t>.stride)
|
|
76
|
+
|
|
77
|
+
let result = withUnsafeMutablePointer(to: &cpuInfo) {
|
|
78
|
+
$0.withMemoryRebound(to: integer_t.self, capacity: Int(count)) {
|
|
79
|
+
host_statistics(mach_host_self(), HOST_CPU_LOAD_INFO, $0, &count)
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return result == KERN_SUCCESS ? cpuInfo : nil
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
private func memoryInfo() -> [String: Any] {
|
|
87
|
+
let totalBytes = Double(ProcessInfo.processInfo.physicalMemory)
|
|
88
|
+
var info: [String: Any] = [
|
|
89
|
+
"totalBytes": totalBytes,
|
|
90
|
+
"pressure": "normal"
|
|
91
|
+
]
|
|
92
|
+
|
|
93
|
+
if let vmInfo = vmMemoryInfo(totalBytes: totalBytes) {
|
|
94
|
+
info.merge(vmInfo) { _, new in new }
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
if let appUsedBytes = appMemoryBytes() {
|
|
98
|
+
info["appUsedBytes"] = appUsedBytes
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return info
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
private func vmMemoryInfo(totalBytes: Double) -> [String: Any]? {
|
|
105
|
+
var stats = vm_statistics64()
|
|
106
|
+
var count = mach_msg_type_number_t(MemoryLayout<vm_statistics64_data_t>.stride / MemoryLayout<integer_t>.stride)
|
|
107
|
+
|
|
108
|
+
let result = withUnsafeMutablePointer(to: &stats) {
|
|
109
|
+
$0.withMemoryRebound(to: integer_t.self, capacity: Int(count)) {
|
|
110
|
+
host_statistics64(mach_host_self(), HOST_VM_INFO64, $0, &count)
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
guard result == KERN_SUCCESS else {
|
|
115
|
+
return nil
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
var pageSize: vm_size_t = 0
|
|
119
|
+
host_page_size(mach_host_self(), &pageSize)
|
|
120
|
+
let pageBytes = Double(pageSize)
|
|
121
|
+
let freeBytes = Double(UInt64(stats.free_count) + UInt64(stats.inactive_count)) * pageBytes
|
|
122
|
+
let usedBytes = max(totalBytes - freeBytes, 0)
|
|
123
|
+
|
|
124
|
+
return [
|
|
125
|
+
"freeBytes": freeBytes,
|
|
126
|
+
"usedBytes": usedBytes,
|
|
127
|
+
"usedPercent": percent(usedBytes, totalBytes)
|
|
128
|
+
]
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
private func appMemoryBytes() -> Double? {
|
|
132
|
+
var info = task_vm_info_data_t()
|
|
133
|
+
var count = mach_msg_type_number_t(MemoryLayout<task_vm_info_data_t>.stride / MemoryLayout<natural_t>.stride)
|
|
134
|
+
|
|
135
|
+
let result = withUnsafeMutablePointer(to: &info) {
|
|
136
|
+
$0.withMemoryRebound(to: integer_t.self, capacity: Int(count)) {
|
|
137
|
+
task_info(mach_task_self_, task_flavor_t(TASK_VM_INFO), $0, &count)
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
return result == KERN_SUCCESS ? Double(info.phys_footprint) : nil
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
private func storageInfo() -> [String: Any] {
|
|
145
|
+
let url = URL(fileURLWithPath: NSHomeDirectory())
|
|
146
|
+
|
|
147
|
+
do {
|
|
148
|
+
let values = try url.resourceValues(forKeys: [
|
|
149
|
+
.volumeTotalCapacityKey,
|
|
150
|
+
.volumeAvailableCapacityKey,
|
|
151
|
+
.volumeAvailableCapacityForImportantUsageKey
|
|
152
|
+
])
|
|
153
|
+
let totalBytes = values.volumeTotalCapacity.map(Double.init)
|
|
154
|
+
let importantFreeBytes = values.volumeAvailableCapacityForImportantUsage.map(Double.init)
|
|
155
|
+
let freeBytes = importantFreeBytes ?? values.volumeAvailableCapacity.map(Double.init)
|
|
156
|
+
var info: [String: Any] = [:]
|
|
157
|
+
|
|
158
|
+
if let totalBytes {
|
|
159
|
+
info["totalBytes"] = totalBytes
|
|
160
|
+
}
|
|
161
|
+
if let freeBytes {
|
|
162
|
+
info["freeBytes"] = freeBytes
|
|
163
|
+
}
|
|
164
|
+
if let totalBytes, let freeBytes {
|
|
165
|
+
let usedBytes = max(totalBytes - freeBytes, 0)
|
|
166
|
+
info["usedBytes"] = usedBytes
|
|
167
|
+
info["usedPercent"] = percent(usedBytes, totalBytes)
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
return info
|
|
171
|
+
} catch {
|
|
172
|
+
return [:]
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
private func gpuInfo() -> [String: Any]? {
|
|
177
|
+
guard let device = MTLCreateSystemDefaultDevice() else {
|
|
178
|
+
return nil
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
return [
|
|
182
|
+
"api": "metal",
|
|
183
|
+
"vendor": "Apple",
|
|
184
|
+
"renderer": device.name
|
|
185
|
+
]
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
private func onboardSensorsInfo() -> [String: Any] {
|
|
189
|
+
let motionManager = CMMotionManager()
|
|
190
|
+
var availableSensors: [[String: Any]] = []
|
|
191
|
+
|
|
192
|
+
if motionManager.isAccelerometerAvailable {
|
|
193
|
+
availableSensors.append(sensorDescriptor(type: "accelerometer", name: "Accelerometer"))
|
|
194
|
+
}
|
|
195
|
+
if motionManager.isGyroAvailable {
|
|
196
|
+
availableSensors.append(sensorDescriptor(type: "gyroscope", name: "Gyroscope"))
|
|
197
|
+
}
|
|
198
|
+
if motionManager.isMagnetometerAvailable {
|
|
199
|
+
availableSensors.append(sensorDescriptor(type: "magnetometer", name: "Magnetometer"))
|
|
200
|
+
}
|
|
201
|
+
if motionManager.isDeviceMotionAvailable {
|
|
202
|
+
availableSensors.append(sensorDescriptor(type: "deviceMotion", name: "Device Motion"))
|
|
203
|
+
}
|
|
204
|
+
if CMAltimeter.isRelativeAltitudeAvailable() {
|
|
205
|
+
availableSensors.append(sensorDescriptor(type: "barometer", name: "Barometer"))
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
return [
|
|
209
|
+
"availableSensors": availableSensors,
|
|
210
|
+
"readings": []
|
|
211
|
+
]
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
private func sensorDescriptor(type: String, name: String) -> [String: Any] {
|
|
215
|
+
return [
|
|
216
|
+
"type": type,
|
|
217
|
+
"name": name,
|
|
218
|
+
"vendor": "Apple"
|
|
219
|
+
]
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
private func thermalState() -> String {
|
|
223
|
+
switch ProcessInfo.processInfo.thermalState {
|
|
224
|
+
case .nominal:
|
|
225
|
+
return "nominal"
|
|
226
|
+
case .fair:
|
|
227
|
+
return "fair"
|
|
228
|
+
case .serious:
|
|
229
|
+
return "serious"
|
|
230
|
+
case .critical:
|
|
231
|
+
return "critical"
|
|
232
|
+
@unknown default:
|
|
233
|
+
return "unknown"
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
private func modelIdentifier() -> String {
|
|
238
|
+
var systemInfo = utsname()
|
|
239
|
+
uname(&systemInfo)
|
|
240
|
+
|
|
241
|
+
return withUnsafeBytes(of: &systemInfo.machine) { rawBuffer in
|
|
242
|
+
let pointer = rawBuffer.bindMemory(to: CChar.self).baseAddress
|
|
243
|
+
return pointer.map { String(cString: $0) } ?? "unknown"
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
private func cpuArchitecture() -> String {
|
|
248
|
+
#if arch(arm64)
|
|
249
|
+
return "arm64"
|
|
250
|
+
#elseif arch(arm)
|
|
251
|
+
return "arm"
|
|
252
|
+
#elseif arch(x86_64)
|
|
253
|
+
return "x86_64"
|
|
254
|
+
#elseif arch(i386)
|
|
255
|
+
return "i386"
|
|
256
|
+
#else
|
|
257
|
+
return "unknown"
|
|
258
|
+
#endif
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
private func currentTimestamp() -> Double {
|
|
262
|
+
return Date().timeIntervalSince1970 * 1000
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
private func tickDelta(_ current: natural_t, _ previous: natural_t) -> UInt64 {
|
|
266
|
+
return UInt64(current >= previous ? current - previous : 0)
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
private func percent(_ used: Double, _ total: Double) -> Double {
|
|
270
|
+
guard total > 0 else {
|
|
271
|
+
return 0
|
|
272
|
+
}
|
|
273
|
+
return clampPercent((used / total) * 100)
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
private func clampPercent(_ value: Double) -> Double {
|
|
277
|
+
return min(max(value, 0), 100)
|
|
278
|
+
}
|
|
279
|
+
}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import Capacitor
|
|
2
|
+
import Foundation
|
|
3
|
+
|
|
4
|
+
@objc(DeviceInfoPlugin)
|
|
5
|
+
public class DeviceInfoPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
6
|
+
private let pluginVersion = "8.0.0"
|
|
7
|
+
private let defaultIntervalMs = 1000
|
|
8
|
+
private let minimumIntervalMs = 250
|
|
9
|
+
|
|
10
|
+
public let identifier = "DeviceInfoPlugin"
|
|
11
|
+
public let jsName = "DeviceInfo"
|
|
12
|
+
public let pluginMethods: [CAPPluginMethod] = [
|
|
13
|
+
CAPPluginMethod(name: "getInfo", returnType: CAPPluginReturnPromise),
|
|
14
|
+
CAPPluginMethod(name: "startMonitoring", returnType: CAPPluginReturnPromise),
|
|
15
|
+
CAPPluginMethod(name: "stopMonitoring", returnType: CAPPluginReturnPromise),
|
|
16
|
+
CAPPluginMethod(name: "isMonitoring", returnType: CAPPluginReturnPromise),
|
|
17
|
+
CAPPluginMethod(name: "removeAllListeners", returnType: CAPPluginReturnPromise),
|
|
18
|
+
CAPPluginMethod(name: "getPluginVersion", returnType: CAPPluginReturnPromise)
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
private let implementation = DeviceInfo()
|
|
22
|
+
private var timer: Timer?
|
|
23
|
+
private var intervalMs: Int?
|
|
24
|
+
private var startedAt: Double?
|
|
25
|
+
private var sampleLimit: Int?
|
|
26
|
+
private var stopAt: Double?
|
|
27
|
+
private var samplesEmitted = 0
|
|
28
|
+
|
|
29
|
+
@objc func getInfo(_ call: CAPPluginCall) {
|
|
30
|
+
call.resolve(implementation.getInfo())
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
@objc func startMonitoring(_ call: CAPPluginCall) {
|
|
34
|
+
stopMonitoringInternal()
|
|
35
|
+
|
|
36
|
+
let effectiveIntervalMs = max(call.getInt("intervalMs") ?? defaultIntervalMs, minimumIntervalMs)
|
|
37
|
+
let now = currentTimestamp()
|
|
38
|
+
intervalMs = effectiveIntervalMs
|
|
39
|
+
startedAt = now
|
|
40
|
+
samplesEmitted = 0
|
|
41
|
+
sampleLimit = positiveInt(call.getInt("sampleCount"))
|
|
42
|
+
|
|
43
|
+
if let durationMs = positiveDouble(call.getDouble("durationMs")) {
|
|
44
|
+
stopAt = now + durationMs
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if call.getBool("emitImmediately") != false {
|
|
48
|
+
emitSample()
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if startedAt != nil {
|
|
52
|
+
let timer = Timer(timeInterval: Double(effectiveIntervalMs) / 1000, repeats: true) { [weak self] _ in
|
|
53
|
+
self?.emitSample()
|
|
54
|
+
}
|
|
55
|
+
RunLoop.main.add(timer, forMode: .common)
|
|
56
|
+
self.timer = timer
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
call.resolve([
|
|
60
|
+
"monitoring": startedAt != nil,
|
|
61
|
+
"intervalMs": effectiveIntervalMs,
|
|
62
|
+
"startedAt": now
|
|
63
|
+
])
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
@objc func stopMonitoring(_ call: CAPPluginCall) {
|
|
67
|
+
stopMonitoringInternal()
|
|
68
|
+
call.resolve(["monitoring": false])
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
@objc func isMonitoring(_ call: CAPPluginCall) {
|
|
72
|
+
var result: [String: Any] = [
|
|
73
|
+
"monitoring": timer != nil
|
|
74
|
+
]
|
|
75
|
+
|
|
76
|
+
if let intervalMs {
|
|
77
|
+
result["intervalMs"] = intervalMs
|
|
78
|
+
}
|
|
79
|
+
if let startedAt {
|
|
80
|
+
result["startedAt"] = startedAt
|
|
81
|
+
}
|
|
82
|
+
if timer != nil {
|
|
83
|
+
result["samplesEmitted"] = samplesEmitted
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
call.resolve(result)
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
@objc override public func removeAllListeners(_ call: CAPPluginCall) {
|
|
90
|
+
super.removeAllListeners(call)
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
@objc func getPluginVersion(_ call: CAPPluginCall) {
|
|
94
|
+
call.resolve(["version": pluginVersion])
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
deinit {
|
|
98
|
+
stopMonitoringInternal()
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
private func emitSample() {
|
|
102
|
+
guard let startedAt else {
|
|
103
|
+
return
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
var sample = implementation.getInfo()
|
|
107
|
+
samplesEmitted += 1
|
|
108
|
+
let timestamp = sample["timestamp"] as? Double ?? currentTimestamp()
|
|
109
|
+
sample["sequence"] = samplesEmitted
|
|
110
|
+
sample["startedAt"] = startedAt
|
|
111
|
+
sample["elapsedMs"] = timestamp - startedAt
|
|
112
|
+
|
|
113
|
+
notifyListeners("deviceInfoUpdate", data: sample)
|
|
114
|
+
|
|
115
|
+
if shouldStopMonitoring() {
|
|
116
|
+
stopMonitoringInternal()
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
private func shouldStopMonitoring() -> Bool {
|
|
121
|
+
if let sampleLimit, samplesEmitted >= sampleLimit {
|
|
122
|
+
return true
|
|
123
|
+
}
|
|
124
|
+
if let stopAt, currentTimestamp() >= stopAt {
|
|
125
|
+
return true
|
|
126
|
+
}
|
|
127
|
+
return false
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
private func stopMonitoringInternal() {
|
|
131
|
+
timer?.invalidate()
|
|
132
|
+
timer = nil
|
|
133
|
+
intervalMs = nil
|
|
134
|
+
startedAt = nil
|
|
135
|
+
sampleLimit = nil
|
|
136
|
+
stopAt = nil
|
|
137
|
+
samplesEmitted = 0
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
private func positiveInt(_ value: Int?) -> Int? {
|
|
141
|
+
guard let value, value > 0 else {
|
|
142
|
+
return nil
|
|
143
|
+
}
|
|
144
|
+
return value
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
private func positiveDouble(_ value: Double?) -> Double? {
|
|
148
|
+
guard let value, value > 0 else {
|
|
149
|
+
return nil
|
|
150
|
+
}
|
|
151
|
+
return value
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
private func currentTimestamp() -> Double {
|
|
155
|
+
return Date().timeIntervalSince1970 * 1000
|
|
156
|
+
}
|
|
157
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import XCTest
|
|
2
|
+
@testable import DeviceInfoPlugin
|
|
3
|
+
|
|
4
|
+
class DeviceInfoTests: XCTestCase {
|
|
5
|
+
func testGetInfo() {
|
|
6
|
+
let implementation = DeviceInfo()
|
|
7
|
+
let result = implementation.getInfo()
|
|
8
|
+
|
|
9
|
+
XCTAssertEqual("ios", result["platform"] as? String)
|
|
10
|
+
XCTAssertNotNil(result["cpu"])
|
|
11
|
+
XCTAssertNotNil(result["memory"])
|
|
12
|
+
XCTAssertNotNil(result["storage"])
|
|
13
|
+
XCTAssertNotNil(result["sensors"])
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
func testGetPluginVersion() {
|
|
17
|
+
let implementation = DeviceInfo()
|
|
18
|
+
let result = implementation.getPluginVersion()
|
|
19
|
+
|
|
20
|
+
XCTAssertEqual("8.0.0", result)
|
|
21
|
+
}
|
|
22
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@capgo/capacitor-device-info",
|
|
3
|
+
"version": "8.0.0",
|
|
4
|
+
"description": "Capacitor plugin for reading CPU, memory, GPU, storage, and onboard sensor metrics.",
|
|
5
|
+
"main": "dist/plugin.cjs.js",
|
|
6
|
+
"module": "dist/esm/index.js",
|
|
7
|
+
"types": "dist/esm/index.d.ts",
|
|
8
|
+
"unpkg": "dist/plugin.js",
|
|
9
|
+
"files": [
|
|
10
|
+
"android/src/main/",
|
|
11
|
+
"android/build.gradle",
|
|
12
|
+
"dist/",
|
|
13
|
+
"ios/Sources",
|
|
14
|
+
"ios/Tests",
|
|
15
|
+
"Package.swift",
|
|
16
|
+
"CapgoCapacitorDeviceInfo.podspec"
|
|
17
|
+
],
|
|
18
|
+
"author": "Cap-go <contact@capgo.app>",
|
|
19
|
+
"license": "MPL-2.0",
|
|
20
|
+
"repository": {
|
|
21
|
+
"type": "git",
|
|
22
|
+
"url": "git+https://github.com/Cap-go/capacitor-device-info.git"
|
|
23
|
+
},
|
|
24
|
+
"bugs": {
|
|
25
|
+
"url": "https://github.com/Cap-go/capacitor-device-info/issues"
|
|
26
|
+
},
|
|
27
|
+
"homepage": "https://capgo.app/docs/plugins/device-info/",
|
|
28
|
+
"keywords": [
|
|
29
|
+
"capacitor",
|
|
30
|
+
"plugin",
|
|
31
|
+
"device",
|
|
32
|
+
"metrics",
|
|
33
|
+
"cpu",
|
|
34
|
+
"memory",
|
|
35
|
+
"gpu",
|
|
36
|
+
"storage",
|
|
37
|
+
"sensors",
|
|
38
|
+
"temperature",
|
|
39
|
+
"barometer",
|
|
40
|
+
"capgo"
|
|
41
|
+
],
|
|
42
|
+
"scripts": {
|
|
43
|
+
"verify": "bun run verify:ios && bun run verify:android && bun run verify:web",
|
|
44
|
+
"verify:ios": "xcodebuild -scheme CapgoCapacitorDeviceInfo -destination generic/platform=iOS",
|
|
45
|
+
"verify:android": "cd android && ./gradlew clean build test && cd ..",
|
|
46
|
+
"verify:web": "bun run build",
|
|
47
|
+
"lint": "bun run eslint && bun run prettier -- --check && bun run swiftlint -- lint",
|
|
48
|
+
"fmt": "bun run eslint -- --fix && bun run prettier -- --write && bun run swiftlint -- --fix --format",
|
|
49
|
+
"eslint": "eslint \"**/*.ts\"",
|
|
50
|
+
"prettier": "prettier-pretty-check \"**/*.{css,html,ts,js,java}\" --plugin=prettier-plugin-java",
|
|
51
|
+
"swiftlint": "node-swiftlint",
|
|
52
|
+
"docgen": "docgen --api DeviceInfoPlugin --output-readme README.md --output-json dist/docs.json",
|
|
53
|
+
"build": "bun run clean && bun run docgen && tsc && rollup -c rollup.config.mjs",
|
|
54
|
+
"clean": "rimraf ./dist",
|
|
55
|
+
"watch": "tsc --watch",
|
|
56
|
+
"prepublishOnly": "bun run build",
|
|
57
|
+
"check:wiring": "node scripts/check-capacitor-plugin-wiring.mjs"
|
|
58
|
+
},
|
|
59
|
+
"devDependencies": {
|
|
60
|
+
"@capacitor/android": "^8.3.4",
|
|
61
|
+
"@capacitor/cli": "^8.3.4",
|
|
62
|
+
"@capacitor/core": "^8.3.4",
|
|
63
|
+
"@capacitor/docgen": "^0.3.1",
|
|
64
|
+
"@capacitor/ios": "^8.3.4",
|
|
65
|
+
"@eslint/js": "^10.0.1",
|
|
66
|
+
"@ionic/prettier-config": "^4.0.0",
|
|
67
|
+
"@ionic/swiftlint-config": "^2.0.0",
|
|
68
|
+
"@types/node": "^25.9.1",
|
|
69
|
+
"eslint": "^10.4.0",
|
|
70
|
+
"eslint-config-prettier": "^10.1.8",
|
|
71
|
+
"eslint-plugin-import": "^2.32.0",
|
|
72
|
+
"husky": "^9.1.7",
|
|
73
|
+
"prettier": "^3.8.3",
|
|
74
|
+
"prettier-plugin-java": "^2.9.2",
|
|
75
|
+
"prettier-pretty-check": "^0.2.0",
|
|
76
|
+
"rimraf": "^6.1.3",
|
|
77
|
+
"rollup": "^4.60.4",
|
|
78
|
+
"swiftlint": "^2.0.0",
|
|
79
|
+
"typescript": "^6.0.3",
|
|
80
|
+
"typescript-eslint": "^8.59.4"
|
|
81
|
+
},
|
|
82
|
+
"peerDependencies": {
|
|
83
|
+
"@capacitor/core": ">=8.0.0"
|
|
84
|
+
},
|
|
85
|
+
"prettier": "@ionic/prettier-config",
|
|
86
|
+
"swiftlint": "@ionic/swiftlint-config",
|
|
87
|
+
"capacitor": {
|
|
88
|
+
"ios": {
|
|
89
|
+
"src": "ios"
|
|
90
|
+
},
|
|
91
|
+
"android": {
|
|
92
|
+
"src": "android"
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|