Оператору Swift Switch не удается сопоставить строки: что могло вызвать это? - PullRequest
0 голосов
/ 26 мая 2020

У меня есть код для определения серии Apple Watch на основе его идентификатора компьютера . Во всех тестах, которые мне удалось провести на настоящих часах Apple Watch, они работают, как ожидалось.

Однако, оказавшись в дикой природе, в некоторых случаях они не подходят и возвращаются к default кейс. Я добавил запись в default, чтобы увидеть значение model, которое было передано, когда оно не соответствовало, чтобы увидеть, были ли переданы в функцию неожиданные значения.

К моему удивлению , значения, которые передаются, похоже, совпадают, но по-прежнему используется регистр по умолчанию. Например, Watch3,4 часто регистрируется как значение model, которое было передано, что должно соответствовать регистру, чтобы создать Series 3 , и выполняется в моем тестировании, но по какой-то причине это не всегда соответствие в моем приложении когда-то выпущено. То же самое касается и многих других модельных струн.

Кажется, что-то мне здесь не хватает? Например, возможность того, что в проверяемой строке окажутся другие невидимые символы? Или что-то, что мне не хватает о том, как switch операторы работают в Swift?

Чтобы было ясно, это не все время. Он работает большую часть времени, но иногда дает сбой, даже если журнал показывает, что переданное значение является ожидаемым значением, которое соответствует случаю, отличному от значения по умолчанию.

Вот мой код за вычетом журналов, используемых для диагностики:

import Foundation

func getWatchModel() -> String? {
    var size: size_t = 0
    sysctlbyname("hw.machine", nil, &size, nil, 0)
    var machine = CChar()
    sysctlbyname("hw.machine", &machine, &size, nil, 0)
    return String(cString: &machine, encoding: String.Encoding.utf8)
}

func getSeries(model: String) -> String {
    switch model {
    case "Watch2,3", "Watch2,4":
        return "Series 2"
    case "Watch2,6", "Watch2,7":
        return "Series 1"
    case "Watch3,1", "Watch3,2", "Watch3,3", "Watch3,4":
        return "Series 3"
    case "Watch4,1", "Watch4,2", "Watch4,3", "Watch4,4":
        return "Series 4"
    case "Watch5,1", "Watch5,2", "Watch5,3", "Watch5,4":
        return "Series 5"
    default:
        return "Unknown Series"
    }
}

let series: String?

if let model = getWatchModel() {
    series = getSeries(model: model)
} else {
    series = nil
}

print(series ?? "Apple Watch machine ID could not be determined")

1 Ответ

1 голос
/ 26 мая 2020

Я подозреваю, что проблема на самом деле в вашем методе getWatchModel, а именно в строке:

var machine = CChar()

Это выделяет один байт. Вам нужно выделить size байт. Вот один из способов сделать это:

    func getWatchModel() -> String? {
        var size: size_t = 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, encoding: .utf8)
    }

Я подозреваю, что это приводит к String содержащему мусор. Я действительно удивлен, что вы не видели сбоев.

...