Я пишу AudioManager in Swift 3 (пожалуйста, помогите мне с лучшим именем, чем «AudioManager»), который обертывает AVPlayer
. Цель состоит в том, чтобы заставить игрока обрабатывать прерывания, изменять маршрут и поддерживать пользовательскую скорость воспроизведения, таймер сна, командный центр, теперь воспроизводить информацию и т. Д. Так как AVFoundation
в значительной степени событие, приводимое в движение, с использованиеми NSNotification
имеет смысл сделать мой проект также управляется. Я включил систему обмена сообщениями, где разные части приложения отправляют события вверх по цепочке, вплоть до корневого узла, AudioManager. Поэтому я хотел представить событие как enum
, потому что это имеет смысл. Тем не менее, я хочу, чтобы мои события группировались, например. RouteChange, BufferingEvent, InterruptionEvent и т.д. Так что я, наконец, получил это работает, используя вложенными перечислений.Вложенные косвенные перечисления в Swift
Я пишу пример GUI, который затем может настроиться на события из AudioManager, вместо того, чтобы использовать NSNotification
или закрытых участков.
Editted используя ответ предоставленного @ andyvn22
enum AudioError: Error {
indirect case buffering(Buffering)
enum Buffering {
case unknown
}
indirect case playback(Playback)
enum Playback {
case failedToSetupAVAsset
case failedToSetupAVItem
}
init(_ buffering: Buffering) {
self = .buffering(buffering)
}
init(_ playback: Playback) {
self = .playback(playback)
}
}
enum Event {
case failure(AudioError)
init(_ error: AudioError) {
self = .failure(error)
}
init(_ bufferingError: AudioError.Buffering) {
self = .failure(AudioError.buffering(bufferingError))
}
init(_ playbackError: AudioError.Playback) {
self = .failure(AudioError.playback(playbackError))
}
indirect case buffering(Buffering)
enum Buffering {
case idle, started, finished
}
indirect case playback(Playback)
enum Playback {
case tick, wasPaused
}
indirect case route(RouteChange)
enum RouteChange {
case unavailable, available
}
indirect case interruption(Interruption)
enum Interruption {
case interrupted, interruptionEnded
}
}
Вы можете вставить все это в к Swift Playground и добавьте handle
метод и называя это на примере вызовов ниже:
func handle(_ error: AudioError.Buffering) {
handle(AudioError.buffering(error))
}
func handle(_ error: AudioError) {
handle(Event.failure(error))
}
func handle(_ event: Event) {
switch event {
case .failure(let errorType):
print("failure", terminator: " ")
switch errorType {
case .playback(let error):
print("playback", terminator: " ")
switch error {
case .failedToSetupAVAsset:
print("setupAVAsset")
case .failedToSetupAVItem:
print("setupAVItem")
}
case .buffering(let error):
print("buffering", terminator: " ")
switch error {
case .unknown:
print("unknown")
}
}
case .buffering(let buffering):
print("buffering", terminator: " ")
switch buffering {
case .idle:
print("idle")
case .started:
print("started")
case .finished:
print("finished")
}
case .playback(let playback):
print("playback", terminator: " ")
switch playback {
case .tick:
print("tick")
case .wasPaused:
print("wasPaused")
}
default:
print("unhandled case")
}
}
/* All these are equivalent */
handle(Event.failure(.buffering(.unknown)))
handle(Event(.buffering(.unknown)))
handle(Event(AudioError(.unknown)))
handle(Event(.unknown))
handle(.unknown)
ORIGINAL ВОПРОС
Однако немного утомительно написать handle(Event(.buffering(.unknown)))
, который уже является короткой версией handle(Event.failure(.buffering(.unknown)))
.
Мой вопрос:
Можно ли создать Event
с case .failure
, используя только внутренний корпус внутри либо AudioError.Buffering или AudioError.Playback?
Которые позволяют бы сделать что-то вроде этого:
handle(Event(.unknown))
Предполагая AudioError.Buffering и AudioError.Playback не разделяет дело с таким же названием ...
Возможно, я пропустил какую-то крутую часть Swift 3, что бы это разрешило?
очень приятно, мне пришлось добавить еще несколько элементов, чтобы заставить его работать, обновит мои вопросы с помощью решения, спасибо! – Sajjon
Я добавил два события к событию, одно для AudioError.Buffering и одно для AudioError.Playback, и я добавил два входа в AudioError. Я также создал два удобных 'func handle', которые обеспечивают очень хороший синтаксис. – Sajjon
Возможно ли еще обновить код? :) – Sajjon