🍁

iOSでシステム全体のCPU使用率を取得する

に公開

たぶんAppStoreにリリースできる仕組みだと思います。
指定した間隔でのCPU使用率を算出します。そのため、初回は0しか取得できません。

import Darwin
import MachO
import Synchronization

struct Ticks {
    var used: Double
    var total: Double

    static let zero = Ticks(used: .zero, total: .zero)
}

public struct CPURepository {
    private var previousTicks: Ticks?

    public init() {}

    public mutating func get() -> Double {
        var count: natural_t = .zero
        var info: processor_info_array_t?
        var infoCount: mach_msg_type_number_t = .zero

        let result = host_processor_info(mach_host_self(), PROCESSOR_CPU_LOAD_INFO, &count, &info, &infoCount)
        guard result == KERN_SUCCESS, let info else {
            return .zero
        }

        defer {
            vm_deallocate(mach_task_self_, vm_address_t(bitPattern: info), vm_size_t(Int(infoCount) * MemoryLayout<integer_t>.size))
        }

        let currentTicks = (0 ..< Int(count)).reduce(into: Ticks.zero) { partialResult, i in
            let base = i * Int(CPU_STATE_MAX)
            let user = info[base + Int(CPU_STATE_USER)]
            let system = info[base + Int(CPU_STATE_SYSTEM)]
            let idle = info[base + Int(CPU_STATE_IDLE)]
            let nice = info[base + Int(CPU_STATE_NICE)]
            partialResult.used += Double(user + system)
            partialResult.total += Double(user + system + idle + nice)
        }

        var value = Double.zero
        if let previousTicks {
            let usedDiff = currentTicks.used - previousTicks.used
            let totalDiff = currentTicks.total - previousTicks.total

            if totalDiff > 0 {
                value = usedDiff / totalDiff
            }
        }
        previousTicks = currentTicks

        return value
    }
}
var cpuRepository = CPURepository()

Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { _ in
    let value = cpuRepository.get()
    print(String(format: "CPU使用率: %.2f%%", 100 * value))
}

Discussion