Использование sysctlbyname() из Swift

Im, используя код this Gist, чтобы определить, какое устройство iOS (например, iPhone5,1) работает на моем приложении:

- (NSString *)platform
{
    size_t size;
    sysctlbyname("hw.machine", NULL, &size, NULL, 0);
    char *machine = malloc(size);
    sysctlbyname("hw.machine", machine, &size, NULL, 0);
    NSString *platform = [NSString stringWithUTF8String:machine];
    free(machine);
    return platform;
}

Документация Swift указывает, что типы данных C хорошо поддерживаются, но ничего не говорят о функциях C. Есть ли чистый способ Swift для получения идентификатора машины, или мне нужно перейти на Objective-C для этого?

Ответы

Ответ 1

Вы можете сделать то же самое в Swift (ошибка проверки опущена для краткости):

func platform() -> String {
    var size : Int = 0 // as Ben Stahl noticed in his answer
    sysctlbyname("hw.machine", nil, &size, nil, 0)
    var machine = [CChar](count: size, repeatedValue: 0)
    sysctlbyname("hw.machine", &machine, &size, nil, 0)
    return String.fromCString(machine)!
}

Обновление для Swift 3:

func platform() -> String {
    var size = 0
    sysctlbyname("hw.machine", nil, &size, nil, 0)
    var machine = [CChar](repeating: 0,  count: size)
    sysctlbyname("hw.machine", &machine, &size, nil, 0)
    return String(cString: machine)
}

Ответ 2

По состоянию на Swift 1.2 (Xcode 6.3 beta-2) код @MartinR выше нужно немного изменить. Для параметра sysctlbyname требуется массив CChar (например, строка C) для первого параметра и Int (вместо Uint) для параметра "size".

func platformModelString() -> String? {
    if let key = "hw.machine".cString(using: String.Encoding.utf8) {
        var size: Int = 0
        sysctlbyname(key, nil, &size, nil, 0)
        var machine = [CChar](repeating: 0, count: Int(size))
        sysctlbyname(key, &machine, &size, nil, 0)
        return String(cString: machine)
    }
    return nil
}

EDIT: Обновлено 2017-01-04 для синтаксиса Swift 3