Предотвращение принудительной распаковки в рамках Swift Combine

В видео 721 WWDC 2019 основа основного примера начинается следующим образом:

let trickNamePublisher = NotificationCenter.default.publisher(for: .newTrickDownloaded)
    .map { notification in
        return notification.userInfo?["data"] as! Data
    }

Это кажется нецелесообразным. Что будет, если нет userInfoили не содержит "data" ключ, или это не данные? Мы насильно развернем nil и сбой. Какова лучшая практика здесь?

1 ответ

Решение

Использование compactMap вместо:

let trickNamePublisher = NotificationCenter.default.publisher(for: .newTrickDownloaded)
    .compactMap { $0.userInfo?["data"] as? Data }

Если наше закрытие дает дополнительные данные, они развернуты, и мы публикуем данные. Если наше закрытие производит nilничего не происходит (ничего не опубликовано).

(Удивительно, что видео так не пишет. В защиту Apple, как указывают MartinR и Итай Фербер, видео предполагает, что мы сами публикуем уведомление, поэтому мы точно знаем, что находится в пользовательской информации и силах. - Развертывание является разумным. Этот вопрос и ответ сфокусированы на общей ситуации, когда вы подписались на уведомление от фреймворка, такого как Cocoa. Кроме того, я не могу поверить, что когда-либо это плохая идея - безопасно развернуть, в моем собственном коде перед комбинатом я всегда разворачивался userInfo значения безопасно, даже когда я сам отправляю уведомление.)

Другие вопросы по тегам