🌊

iOS アプリで CPU 使用率を Swift で取得する

2024/11/18に公開

背景

Flutter で iOS アプリを開発していて, CPU 使用率を取得したいことがあり, パッケージや OS の API を探したところ見つからなかったため自前で実装しました.

以下の記事を参考に, よりコンパクトに実装しました.

https://qiita.com/rinov/items/f30d386fb7b8b12278a5

コード

percentile で値を返すようにしています.

import Foundation

func getCPUUsage() -> Float {
    var activeUsage: Float = 0
    var result: Int32

    // Allocate space for thread list
    var threadList: thread_act_array_t?
    var threadCount = mach_msg_type_number_t()

    // Retrieve thread list and ensure memory is deallocated
    result = task_threads(mach_task_self_, &threadList, &threadCount)
    guard result == KERN_SUCCESS, let threadList = threadList else { return 0 }

    defer {
        vm_deallocate(mach_task_self_, vm_address_t(bitPattern: threadList), vm_size_t(Int(threadCount) * MemoryLayout<thread_t>.size))
    }

    // Calculate CPU usage for each thread
    for index in 0..<Int(threadCount) {
        var threadInfo = thread_basic_info()
        var threadInfoCount = mach_msg_type_number_t(THREAD_INFO_MAX)

        result = withUnsafeMutablePointer(to: &threadInfo) {
            $0.withMemoryRebound(to: integer_t.self, capacity: 1) {
                thread_info(threadList[index], thread_flavor_t(THREAD_BASIC_INFO), $0, &threadInfoCount)
            }
        }

        // Skip this thread if information retrieval failed
        guard result == KERN_SUCCESS else { continue }

        let usage = (Float(threadInfo.cpu_usage) / Float(TH_USAGE_SCALE)) * 100
        if (threadInfo.flags & TH_FLAGS_IDLE) != TH_FLAGS_IDLE {
            activeUsage += usage
        }
    }

    return activeUsage
}

Discussion