Тип 'Boolean' не соответствует протоколу 'BooleanType'

При попытке создать помощника запуска в соответствии с документами Apple (и tutorial-ized) я, кажется, нажимаю на икоту, вызванную портированием Objective-C код в Swift... компилятор в этом случае не может быть лишним.

import ServiceManagement

let launchDaemon: CFStringRef = "com.example.ApplicationLauncher"

if SMLoginItemSetEnabled(launchDaemon, true) // Error appears here
{
    // ...
}

Кажется, что ошибка всегда:

Type 'Boolean' does not conform to protocol 'BooleanType'

Я попробовал кастинг на Bool в нескольких местах, на случай, если я просто использую избыточный, архаичный примитив (либо введенный Obj -C или Core Foundation), безрезультатно.

На всякий случай, я попытался отбросить ответ:

SMLoginItemSetEnabled(launchDaemon, true) as Bool

который дает ошибку:

'Boolean' is not convertible to 'Bool'

... серьезно?

Ответ 1

Boolean является "историческим типом Mac" и объявлен как

typealias Boolean = UInt8

поэтому это компилируется:

if SMLoginItemSetEnabled(launchDaemon, Boolean(1)) != 0 { ... }

Со следующими методами расширения для типа Boolean (и я не уверен, что это было опубликовано раньше, я не могу найти его прямо сейчас):

extension Boolean : BooleanLiteralConvertible {
    public init(booleanLiteral value: Bool) {
        self = value ? 1 : 0
    }
}
extension Boolean : BooleanType {
    public var boolValue : Bool {
        return self != 0
    }
}

вы можете просто написать

if SMLoginItemSetEnabled(launchDaemon, true) { ... }
  • Расширение BooleanLiteralConvertible позволяет автоматическое преобразование второй аргумент true - Boolean.
  • Расширение BooleanType позволяет автоматическое преобразование Boolean возвращает значение функции Bool для оператора if.

Обновление: с Swift 2/Xcode 7 beta 5, "исторический тип Mac" Boolean преобразуется в Swift как Bool, что делает вышеупомянутые методы расширения устарели.

Ответ 2

Правильно, у меня была аналогичная проблема, пытающаяся получить возврат BOOL метода objective-C в Swift.

Obj-C:

- (BOOL)isLogging
{
    return isLogging;
}

Swift:

    if (self.isLogging().boolValue)
    {
        ...
    }

именно так я избавился от ошибки.