diff --git a/Sources/Extensions/Foundation/Observable.swift b/Sources/Extensions/Foundation/Observable.swift index 069486d49b86ac461db123d9226e4f4b67462341..3df5521d1f51584adcfbe33545123ed2d49b5e1d 100644 --- a/Sources/Extensions/Foundation/Observable.swift +++ b/Sources/Extensions/Foundation/Observable.swift @@ -6,25 +6,14 @@ * Copyright © 2019 Videolabs * * Authors: Soomin Lee <bubu # mikan.io> + * Craig Reyenga <craig.reyenga # gmail.com> * * Refer to the COPYING file of the official project for license. *****************************************************************************/ -// MARK: - Observer - -// Since weak is a property assigned to anything that is of class type and not struct -// you have to explicitly constraint your generic parameter to be of class type -class Observer<T: AnyObject> { - weak var observer: T? - - init(_ observer: T) { - self.observer = observer - } -} - class Observable<T: AnyObject> { // Using ObjectIdentifier to avoid duplication and facilitate identification of observing object - private(set) var observers = [ObjectIdentifier: Observer<T>]() + private var observers = [ObjectIdentifier: Observer<T>]() func addObserver(_ observer: T) { let identifier = ObjectIdentifier(observer) @@ -35,4 +24,30 @@ class Observable<T: AnyObject> { let identifier = ObjectIdentifier(observer) observers.removeValue(forKey: identifier) } + + /// Notify observers by executing the provided action upon each. + /// - Parameter action: the action to execute upon each observer + func notifyObservers(action: (T) -> Void) { + // Copy keys before iterating so we can detect observers that have been + // removed as a side effect of calling out to a previous observer. + let keys = Array(observers.keys) + + for k in keys { + guard let observer = observers[k]?.observer else { continue } + action(observer) + } + } + +} + +// MARK: - Observer + +// Since weak is a property assigned to anything that is of class type and not struct +// you have to explicitly constraint your generic parameter to be of class type +fileprivate class Observer<T: AnyObject> { + weak var observer: T? + + init(_ observer: T) { + self.observer = observer + } } diff --git a/Sources/Media Library/MediaLibraryModel/AlbumModel.swift b/Sources/Media Library/MediaLibraryModel/AlbumModel.swift index 9307edb2e57313535ab3a372f60594ae5da00129..a2ccfa9f2a58cc0588d918d6cc7cafd3546a437f 100644 --- a/Sources/Media Library/MediaLibraryModel/AlbumModel.swift +++ b/Sources/Media Library/MediaLibraryModel/AlbumModel.swift @@ -87,8 +87,8 @@ extension AlbumModel { } sortModel.currentSort = criteria sortModel.desc = desc - observable.observers.forEach() { - $0.value.observer?.mediaLibraryBaseModelReloadView() + observable.notifyObservers { + $0.mediaLibraryBaseModelReloadView() } } } @@ -112,8 +112,8 @@ extension VLCMLAlbum: SearchableMLModel { extension AlbumModel: MediaLibraryObserver { func medialibrary(_ medialibrary: MediaLibraryService, didAddAlbums albums: [VLCMLAlbum]) { albums.forEach({ append($0) }) - observable.observers.forEach() { - $0.value.observer?.mediaLibraryBaseModelReloadView() + observable.notifyObservers { + $0.mediaLibraryBaseModelReloadView() } } @@ -134,8 +134,8 @@ extension AlbumModel: MediaLibraryObserver { fileArrayLock.lock() files = swapModels(with: albums) - observable.observers.forEach() { - $0.value.observer?.mediaLibraryBaseModelReloadView() + observable.notifyObservers { + $0.mediaLibraryBaseModelReloadView() } } @@ -147,8 +147,8 @@ extension AlbumModel: MediaLibraryObserver { files.removeAll { albumsIds.contains(NSNumber(value: $0.identifier())) } - observable.observers.forEach() { - $0.value.observer?.mediaLibraryBaseModelReloadView() + observable.notifyObservers { + $0.mediaLibraryBaseModelReloadView() } } diff --git a/Sources/Media Library/MediaLibraryModel/ArtistModel.swift b/Sources/Media Library/MediaLibraryModel/ArtistModel.swift index fdb169ad05239e81752fba751fc62e3c89c2986b..4934fab6e74f0e9e862abe0e7fdafe38c1e4c2a9 100644 --- a/Sources/Media Library/MediaLibraryModel/ArtistModel.swift +++ b/Sources/Media Library/MediaLibraryModel/ArtistModel.swift @@ -94,8 +94,8 @@ extension ArtistModel { medialibrary.artists(sortingCriteria: criteria, desc: desc, listAll: true) sortModel.currentSort = criteria sortModel.desc = desc - observable.observers.forEach() { - $0.value.observer?.mediaLibraryBaseModelReloadView() + observable.notifyObservers { + $0.mediaLibraryBaseModelReloadView() } } } @@ -112,8 +112,8 @@ extension VLCMLArtist: SearchableMLModel { extension ArtistModel: MediaLibraryObserver { func medialibrary(_ medialibrary: MediaLibraryService, didAddArtists artists: [VLCMLArtist]) { artists.forEach({ append($0) }) - observable.observers.forEach() { - $0.value.observer?.mediaLibraryBaseModelReloadView() + observable.notifyObservers { + $0.mediaLibraryBaseModelReloadView() } } @@ -137,8 +137,8 @@ extension ArtistModel: MediaLibraryObserver { files = swapModels(with: artists) addNewArtists(artists) filterGeneratedArtists() - observable.observers.forEach() { - $0.value.observer?.mediaLibraryBaseModelReloadView() + observable.notifyObservers { + $0.mediaLibraryBaseModelReloadView() } } @@ -150,8 +150,8 @@ extension ArtistModel: MediaLibraryObserver { files.removeAll { artistsIds.contains(NSNumber(value: $0.identifier())) } - observable.observers.forEach() { - $0.value.observer?.mediaLibraryBaseModelReloadView() + observable.notifyObservers { + $0.mediaLibraryBaseModelReloadView() } } diff --git a/Sources/Media Library/MediaLibraryModel/CollectionModel.swift b/Sources/Media Library/MediaLibraryModel/CollectionModel.swift index ab4a6c14673759ebbc0f6608cd9586927e794fca..9bd87f214be04a9b3cac52b6c72d9a0cbf5f9242 100644 --- a/Sources/Media Library/MediaLibraryModel/CollectionModel.swift +++ b/Sources/Media Library/MediaLibraryModel/CollectionModel.swift @@ -110,8 +110,8 @@ class CollectionModel: MLBaseModel { files = mediaCollection.files(with: criteria, desc: desc) ?? [] sortModel.currentSort = criteria sortModel.desc = desc - observable.observers.forEach() { - $0.value.observer?.mediaLibraryBaseModelReloadView() + observable.notifyObservers { + $0.mediaLibraryBaseModelReloadView() } } } @@ -126,8 +126,8 @@ extension CollectionModel: MediaLibraryObserver { if mediaCollection is VLCMLPlaylist { fileArrayLock.lock() files = mediaCollection.files() ?? [] - observable.observers.forEach() { - $0.value.observer?.mediaLibraryBaseModelReloadView() + observable.notifyObservers { + $0.mediaLibraryBaseModelReloadView() } sort(by: sortModel.currentSort, desc: sortModel.desc) @@ -140,8 +140,8 @@ extension CollectionModel: MediaLibraryObserver { } fileArrayLock.lock() files = mediaCollection.files() ?? [] - observable.observers.forEach() { - $0.value.observer?.mediaLibraryBaseModelReloadView() + observable.notifyObservers { + $0.mediaLibraryBaseModelReloadView() } sort(by: sortModel.currentSort, desc: sortModel.desc) @@ -153,8 +153,8 @@ extension CollectionModel: MediaLibraryObserver { } fileArrayLock.lock() files = mediaCollection.files() ?? [] - observable.observers.forEach() { - $0.value.observer?.mediaLibraryBaseModelReloadView() + observable.notifyObservers { + $0.mediaLibraryBaseModelReloadView() } sort(by: sortModel.currentSort, desc: sortModel.desc) @@ -171,8 +171,8 @@ extension CollectionModel: MediaLibraryObserver { } fileArrayLock.lock() files = mediaCollection.files() ?? [] - observable.observers.forEach() { - $0.value.observer?.mediaLibraryBaseModelReloadView() + observable.notifyObservers { + $0.mediaLibraryBaseModelReloadView() } sort(by: sortModel.currentSort, desc: sortModel.desc) diff --git a/Sources/Media Library/MediaLibraryModel/GenreModel.swift b/Sources/Media Library/MediaLibraryModel/GenreModel.swift index 004e07a70924891da42e65a5bd32092d6a808ea6..6824e031eea5f28fe3d8c7dcd15e9c8d352c524f 100644 --- a/Sources/Media Library/MediaLibraryModel/GenreModel.swift +++ b/Sources/Media Library/MediaLibraryModel/GenreModel.swift @@ -53,8 +53,8 @@ class GenreModel: AudioCollectionModel { extension GenreModel: MediaLibraryObserver { func medialibrary(_ medialibrary: MediaLibraryService, didAddGenres genres: [VLCMLGenre]) { genres.forEach({ append($0) }) - observable.observers.forEach() { - $0.value.observer?.mediaLibraryBaseModelReloadView() + observable.notifyObservers { + $0.mediaLibraryBaseModelReloadView() } } @@ -74,8 +74,8 @@ extension GenreModel: MediaLibraryObserver { fileArrayLock.lock() files = swapModels(with: genres) - observable.observers.forEach() { - $0.value.observer?.mediaLibraryBaseModelReloadView() + observable.notifyObservers { + $0.mediaLibraryBaseModelReloadView() } } @@ -87,8 +87,8 @@ extension GenreModel: MediaLibraryObserver { files.removeAll { genresIds.contains(NSNumber(value: $0.identifier())) } - observable.observers.forEach() { - $0.value.observer?.mediaLibraryBaseModelReloadView() + observable.notifyObservers { + $0.mediaLibraryBaseModelReloadView() } } @@ -111,8 +111,8 @@ extension GenreModel { files = medialibrary.genres(sortingCriteria: criteria, desc: desc) sortModel.currentSort = criteria sortModel.desc = desc - observable.observers.forEach() { - $0.value.observer?.mediaLibraryBaseModelReloadView() + observable.notifyObservers { + $0.mediaLibraryBaseModelReloadView() } } } diff --git a/Sources/Media Library/MediaLibraryModel/HistoryModel.swift b/Sources/Media Library/MediaLibraryModel/HistoryModel.swift index 04a0897576d76d62ee50720790975539799726ab..c168736371b7fb5d45ef5d23f8fa96d327fe20fb 100644 --- a/Sources/Media Library/MediaLibraryModel/HistoryModel.swift +++ b/Sources/Media Library/MediaLibraryModel/HistoryModel.swift @@ -57,8 +57,8 @@ extension HistoryModel: MediaLibraryObserver { } else { files = medialibrary.medialib.videoHistory() ?? [] } - observable.observers.forEach() { - $0.value.observer?.mediaLibraryBaseModelReloadView() + observable.notifyObservers { + $0.mediaLibraryBaseModelReloadView() } } @@ -72,8 +72,8 @@ extension HistoryModel: MediaLibraryObserver { } else { files = medialibrary.medialib.videoHistory() ?? [] } - observable.observers.forEach() { - $0.value.observer?.mediaLibraryBaseModelReloadView() + observable.notifyObservers { + $0.mediaLibraryBaseModelReloadView() } } diff --git a/Sources/Media Library/MediaLibraryModel/MediaGroupViewModel.swift b/Sources/Media Library/MediaLibraryModel/MediaGroupViewModel.swift index 688a92d2bf2c01a5e180943d3e674a2c622b2bbc..43bdd193d32d2842cbb5edc4af7d546c7da2176f 100644 --- a/Sources/Media Library/MediaLibraryModel/MediaGroupViewModel.swift +++ b/Sources/Media Library/MediaLibraryModel/MediaGroupViewModel.swift @@ -95,8 +95,8 @@ class MediaGroupViewModel: MLBaseModel { } sortModel.currentSort = criteria sortModel.desc = desc - observable.observers.forEach() { - $0.value.observer?.mediaLibraryBaseModelReloadView() + observable.notifyObservers { + $0.mediaLibraryBaseModelReloadView() } } @@ -172,8 +172,8 @@ extension MediaGroupViewModel: MediaLibraryObserver { } } } - observable.observers.forEach() { - $0.value.observer?.mediaLibraryBaseModelReloadView() + observable.notifyObservers { + $0.mediaLibraryBaseModelReloadView() } } @@ -192,8 +192,8 @@ extension MediaGroupViewModel: MediaLibraryObserver { fileArrayQueue.sync { files = swapModels(with: mediaGroups) } - observable.observers.forEach() { - $0.value.observer?.mediaLibraryBaseModelReloadView() + observable.notifyObservers { + $0.mediaLibraryBaseModelReloadView() } } @@ -204,18 +204,18 @@ extension MediaGroupViewModel: MediaLibraryObserver { mediaGroupsIds.contains(NSNumber(value: $0.identifier())) } } - observable.observers.forEach() { - $0.value.observer?.mediaLibraryBaseModelReloadView() + observable.notifyObservers { + $0.mediaLibraryBaseModelReloadView() } } // MARK: - VLCMLMedia func medialibrary(_ medialibrary: MediaLibraryService, didModifyVideos videos: [VLCMLMedia]) { - if !videos.isEmpty { - observable.observers.forEach() { - $0.value.observer?.mediaLibraryBaseModelReloadView() - } + guard !videos.isEmpty else { return } + + observable.notifyObservers { + $0.mediaLibraryBaseModelReloadView() } } @@ -227,8 +227,8 @@ extension MediaGroupViewModel: MediaLibraryObserver { guard success else { return } - observable.observers.forEach() { - $0.value.observer?.mediaLibraryBaseModelReloadView() + observable.notifyObservers { + $0.mediaLibraryBaseModelReloadView() } } } diff --git a/Sources/Media Library/MediaLibraryModel/PlaylistModel.swift b/Sources/Media Library/MediaLibraryModel/PlaylistModel.swift index 43311aa91630a11530d6f7b247a7cb6369f25fdb..25c1e973220ac424dfdb39742ded4d9b91322d0e 100644 --- a/Sources/Media Library/MediaLibraryModel/PlaylistModel.swift +++ b/Sources/Media Library/MediaLibraryModel/PlaylistModel.swift @@ -77,8 +77,8 @@ class PlaylistModel: MLBaseModel { // Update directly the UI without waiting the delegate to avoid showing 'ghost' items fileArrayLock.lock() filterFilesFromDeletion(of: items) - observable.observers.forEach() { - $0.value.observer?.mediaLibraryBaseModelReloadView() + observable.notifyObservers { + $0.mediaLibraryBaseModelReloadView() } } @@ -89,8 +89,8 @@ class PlaylistModel: MLBaseModel { return } append(playlist) - observable.observers.forEach() { - $0.value.observer?.mediaLibraryBaseModelReloadView() + observable.notifyObservers { + $0.mediaLibraryBaseModelReloadView() } } } @@ -105,8 +105,8 @@ extension PlaylistModel { files = medialibrary.playlists(sortingCriteria: criteria, desc: desc) sortModel.currentSort = criteria sortModel.desc = desc - observable.observers.forEach() { - $0.value.observer?.mediaLibraryBaseModelReloadView() + observable.notifyObservers { + $0.mediaLibraryBaseModelReloadView() } } } @@ -122,8 +122,8 @@ extension VLCMLPlaylist: SearchableMLModel { extension PlaylistModel: MediaLibraryObserver { func medialibrary(_ medialibrary: MediaLibraryService, didAddPlaylists playlists: [VLCMLPlaylist]) { playlists.forEach({ append($0) }) - observable.observers.forEach() { - $0.value.observer?.mediaLibraryBaseModelReloadView() + observable.notifyObservers { + $0.mediaLibraryBaseModelReloadView() } } @@ -144,8 +144,8 @@ extension PlaylistModel: MediaLibraryObserver { fileArrayLock.lock() files = swapModels(with: playlists) - observable.observers.forEach() { - $0.value.observer?.mediaLibraryBaseModelReloadView() + observable.notifyObservers { + $0.mediaLibraryBaseModelReloadView() } } @@ -160,8 +160,8 @@ extension PlaylistModel: MediaLibraryObserver { } return true } - observable.observers.forEach() { - $0.value.observer?.mediaLibraryBaseModelReloadView() + observable.notifyObservers { + $0.mediaLibraryBaseModelReloadView() } } diff --git a/Sources/Media Library/MediaLibraryModel/ShowEpisodeModel.swift b/Sources/Media Library/MediaLibraryModel/ShowEpisodeModel.swift index af6291946bc0c78804e94379c33e29ec42343f21..debed46d1d025aa2c664a9e4240eaa9c9b49fe3f 100644 --- a/Sources/Media Library/MediaLibraryModel/ShowEpisodeModel.swift +++ b/Sources/Media Library/MediaLibraryModel/ShowEpisodeModel.swift @@ -58,8 +58,8 @@ extension ShowEpisodeModel { extension ShowEpisodeModel: MediaLibraryObserver { func medialibrary(_ medialibrary: MediaLibraryService, didAddShowEpisodes showEpisodes: [VLCMLMedia]) { showEpisodes.forEach({ append($0) }) - observable.observers.forEach() { - $0.value.observer?.mediaLibraryBaseModelReloadView() + observable.notifyObservers { + $0.mediaLibraryBaseModelReloadView() } } diff --git a/Sources/Media Library/MediaLibraryModel/TrackModel.swift b/Sources/Media Library/MediaLibraryModel/TrackModel.swift index c837addd7f199c6052c83e07eb66dbbb6aa75095..f7cdb6b0c5f633eafd7d8e2c67ba2ea671f113d5 100644 --- a/Sources/Media Library/MediaLibraryModel/TrackModel.swift +++ b/Sources/Media Library/MediaLibraryModel/TrackModel.swift @@ -54,8 +54,8 @@ extension TrackModel { desc: desc) sortModel.currentSort = criteria sortModel.desc = desc - observable.observers.forEach() { - $0.value.observer?.mediaLibraryBaseModelReloadView() + observable.notifyObservers { + $0.mediaLibraryBaseModelReloadView() } } } @@ -69,8 +69,8 @@ extension TrackModel: MediaLibraryObserver { } fileArrayLock.lock() tracks.forEach({ append($0) }) - observable.observers.forEach() { - $0.value.observer?.mediaLibraryBaseModelReloadView() + observable.notifyObservers { + $0.mediaLibraryBaseModelReloadView() } } @@ -81,8 +81,8 @@ extension TrackModel: MediaLibraryObserver { } fileArrayLock.lock() files = swapModels(with: tracks) - observable.observers.forEach() { - $0.value.observer?.mediaLibraryBaseModelReloadView() + observable.notifyObservers { + $0.mediaLibraryBaseModelReloadView() } } } @@ -98,8 +98,8 @@ extension TrackModel: MediaLibraryObserver { } return true } - observable.observers.forEach() { - $0.value.observer?.mediaLibraryBaseModelReloadView() + observable.notifyObservers { + $0.mediaLibraryBaseModelReloadView() } } } diff --git a/Sources/Media Library/MediaLibraryModel/VideoModel.swift b/Sources/Media Library/MediaLibraryModel/VideoModel.swift index f5bca292857ed0d5d0574e134c3544c6b263cc24..d438d50f4517211bb1a9a81458e8125c1c677af5 100644 --- a/Sources/Media Library/MediaLibraryModel/VideoModel.swift +++ b/Sources/Media Library/MediaLibraryModel/VideoModel.swift @@ -55,8 +55,8 @@ extension VideoModel { desc: desc) sortModel.currentSort = criteria sortModel.desc = desc - observable.observers.forEach() { - $0.value.observer?.mediaLibraryBaseModelReloadView() + observable.notifyObservers { + $0.mediaLibraryBaseModelReloadView() } } } @@ -70,8 +70,8 @@ extension VideoModel: MediaLibraryObserver { } fileArrayLock.lock() videos.forEach({ append($0) }) - observable.observers.forEach() { - $0.value.observer?.mediaLibraryBaseModelReloadView() + observable.notifyObservers { + $0.mediaLibraryBaseModelReloadView() } } @@ -82,8 +82,8 @@ extension VideoModel: MediaLibraryObserver { } fileArrayLock.lock() files = swapModels(with: videos) - observable.observers.forEach() { - $0.value.observer?.mediaLibraryBaseModelReloadView() + observable.notifyObservers { + $0.mediaLibraryBaseModelReloadView() } } } @@ -99,8 +99,8 @@ extension VideoModel: MediaLibraryObserver { } return true } - observable.observers.forEach() { - $0.value.observer?.mediaLibraryBaseModelReloadView() + observable.notifyObservers { + $0.mediaLibraryBaseModelReloadView() } } @@ -117,8 +117,8 @@ extension VideoModel: MediaLibraryObserver { } fileArrayLock.lock() files = swapModels(with: [media]) - observable.observers.forEach() { - $0.value.observer?.mediaLibraryBaseModelReloadView() + observable.notifyObservers { + $0.mediaLibraryBaseModelReloadView() } } } diff --git a/Sources/Media Library/MediaLibraryService.swift b/Sources/Media Library/MediaLibraryService.swift index 766b4de0789d3d4d15a542e7e0c501cbc011f9d4..4a218f2e734cc7a1f75419bc1f6f498ec7dd3775 100644 --- a/Sources/Media Library/MediaLibraryService.swift +++ b/Sources/Media Library/MediaLibraryService.swift @@ -510,9 +510,9 @@ extension MediaLibraryService: VLCMediaLibraryDelegate { let videos = media.filter {( $0.type() == .video )} let tracks = media.filter {( $0.type() == .audio )} - for observer in observable.observers { - observer.value.observer?.medialibrary?(self, didAddVideos: videos) - observer.value.observer?.medialibrary?(self, didAddTracks: tracks) + observable.notifyObservers { + $0.medialibrary?(self, didAddVideos: videos) + $0.medialibrary?(self, didAddTracks: tracks) } } @@ -534,11 +534,11 @@ extension MediaLibraryService: VLCMediaLibraryDelegate { let tracks = media.filter {( $0.type() == .audio)} // Shows and albumtracks are known only after when the medialibrary calls didModifyMedia - for observer in observable.observers { - observer.value.observer?.medialibrary?(self, didAddShowEpisodes: showEpisodes) - observer.value.observer?.medialibrary?(self, didAddAlbumTracks: albumTrack) - observer.value.observer?.medialibrary?(self, didModifyVideos: videos) - observer.value.observer?.medialibrary?(self, didModifyTracks: tracks) + observable.notifyObservers { + $0.medialibrary?(self, didAddShowEpisodes: showEpisodes) + $0.medialibrary?(self, didAddAlbumTracks: albumTrack) + $0.medialibrary?(self, didModifyVideos: videos) + $0.medialibrary?(self, didModifyTracks: tracks) } } @@ -547,16 +547,16 @@ extension MediaLibraryService: VLCMediaLibraryDelegate { mediaIds.forEach { stringIds.append("\($0)") } CSSearchableIndex.default().deleteSearchableItems(withIdentifiers: stringIds, completionHandler: nil) - for observer in observable.observers { - observer.value.observer?.medialibrary?(self, didDeleteMediaWithIds: mediaIds) + observable.notifyObservers { + $0.medialibrary?(self, didDeleteMediaWithIds: mediaIds) } } func medialibrary(_ medialibrary: VLCMediaLibrary, thumbnailReadyFor media: VLCMLMedia, of type: VLCMLThumbnailSizeType, withSuccess success: Bool) { - for observer in observable.observers { - observer.value.observer?.medialibrary?(self, thumbnailReady: media, - type: type, success: success) + observable.notifyObservers { + $0.medialibrary?(self, thumbnailReady: media, + type: type, success: success) } } } @@ -565,21 +565,21 @@ extension MediaLibraryService: VLCMediaLibraryDelegate { extension MediaLibraryService { func medialibrary(_ medialibrary: VLCMediaLibrary, didAdd artists: [VLCMLArtist]) { - for observer in observable.observers { - observer.value.observer?.medialibrary?(self, didAddArtists: artists) + observable.notifyObservers { + $0.medialibrary?(self, didAddArtists: artists) } } func medialibrary(_ medialibrary: VLCMediaLibrary, didModifyArtistsWithIds artistsIds: [NSNumber]) { - for observer in observable.observers { - observer.value.observer?.medialibrary?(self, didModifyArtistsWithIds: artistsIds) + observable.notifyObservers { + $0.medialibrary?(self, didModifyArtistsWithIds: artistsIds) } } func medialibrary(_ medialibrary: VLCMediaLibrary, didDeleteArtistsWithIds artistsIds: [NSNumber]) { - for observer in observable.observers { - observer.value.observer?.medialibrary?(self, didDeleteArtistsWithIds: artistsIds) + observable.notifyObservers { + $0.medialibrary?(self, didDeleteArtistsWithIds: artistsIds) } } } @@ -588,21 +588,21 @@ extension MediaLibraryService { extension MediaLibraryService { func medialibrary(_ medialibrary: VLCMediaLibrary, didAdd albums: [VLCMLAlbum]) { - for observer in observable.observers { - observer.value.observer?.medialibrary?(self, didAddAlbums: albums) + observable.notifyObservers { + $0.medialibrary?(self, didAddAlbums: albums) } } func medialibrary(_ medialibrary: VLCMediaLibrary, didModifyAlbumsWithIds albumsIds: [NSNumber]) { - for observer in observable.observers { - observer.value.observer?.medialibrary?(self, didModifyAlbumsWithIds: albumsIds) + observable.notifyObservers { + $0.medialibrary?(self, didModifyAlbumsWithIds: albumsIds) } } func medialibrary(_ medialibrary: VLCMediaLibrary, didDeleteAlbumsWithIds albumsIds: [NSNumber]) { - for observer in observable.observers { - observer.value.observer?.medialibrary?(self, didDeleteAlbumsWithIds: albumsIds) + observable.notifyObservers { + $0.medialibrary?(self, didDeleteAlbumsWithIds: albumsIds) } } } @@ -611,22 +611,22 @@ extension MediaLibraryService { extension MediaLibraryService { func medialibrary(_ medialibrary: VLCMediaLibrary, didAdd genres: [VLCMLGenre]) { - for observer in observable.observers { - observer.value.observer?.medialibrary?(self, didAddGenres: genres) + observable.notifyObservers { + $0.medialibrary?(self, didAddGenres: genres) } } func medialibrary(_ medialibrary: VLCMediaLibrary, didModifyGenresWithIds genresIds: [NSNumber]) { - for observer in observable.observers { - observer.value.observer?.medialibrary?(self, didModifyGenresWithIds: genresIds) + observable.notifyObservers { + $0.medialibrary?(self, didModifyGenresWithIds: genresIds) } } func medialibrary(_ medialibrary: VLCMediaLibrary, didDeleteGenresWithIds genresIds: [NSNumber]) { - for observer in observable.observers { - observer.value.observer?.medialibrary?(self, didDeleteGenresWithIds: genresIds) + observable.notifyObservers { + $0.medialibrary?(self, didDeleteGenresWithIds: genresIds) } } } @@ -635,21 +635,21 @@ extension MediaLibraryService { extension MediaLibraryService { func medialibrary(_ medialibrary: VLCMediaLibrary, didAdd playlists: [VLCMLPlaylist]) { - for observer in observable.observers { - observer.value.observer?.medialibrary?(self, didAddPlaylists: playlists) + observable.notifyObservers { + $0.medialibrary?(self, didAddPlaylists: playlists) } } func medialibrary(_ medialibrary: VLCMediaLibrary, didModifyPlaylistsWithIds playlistsIds: [NSNumber]) { - for observer in observable.observers { - observer.value.observer?.medialibrary?(self, didModifyPlaylistsWithIds: playlistsIds) + observable.notifyObservers { + $0.medialibrary?(self, didModifyPlaylistsWithIds: playlistsIds) } } func medialibrary(_ medialibrary: VLCMediaLibrary, didDeletePlaylistsWithIds playlistsIds: [NSNumber]) { - for observer in observable.observers { - observer.value.observer?.medialibrary?(self, didDeletePlaylistsWithIds: playlistsIds) + observable.notifyObservers { + $0.medialibrary?(self, didDeletePlaylistsWithIds: playlistsIds) } } } @@ -658,25 +658,22 @@ extension MediaLibraryService { extension MediaLibraryService { func medialibrary(_ medialibrary: VLCMediaLibrary, didAdd mediaGroups: [VLCMLMediaGroup]) { - for observer in observable.observers { - observer.value.observer?.medialibrary?(self, - didAddMediaGroups: mediaGroups) + observable.notifyObservers { + $0.medialibrary?(self, didAddMediaGroups: mediaGroups) } } func medialibrary(_ medialibrary: VLCMediaLibrary, didModifyMediaGroupsWithIds mediaGroupsIds: [NSNumber]) { - for observer in observable.observers { - observer.value.observer?.medialibrary?(self, - didModifyMediaGroupsWithIds: mediaGroupsIds) + observable.notifyObservers { + $0.medialibrary?(self, didModifyMediaGroupsWithIds: mediaGroupsIds) } } func medialibrary(_ medialibrary: VLCMediaLibrary, didDeleteMediaGroupsWithIds mediaGroupsIds: [NSNumber]) { - for observer in observable.observers { - observer.value.observer?.medialibrary?(self, - didDeleteMediaGroupsWithIds: mediaGroupsIds) + observable.notifyObservers { + $0.medialibrary?(self, didDeleteMediaGroupsWithIds: mediaGroupsIds) } } } @@ -717,16 +714,16 @@ extension MediaLibraryService { extension MediaLibraryService { func medialibraryDidStartRescan(_ medialibrary: VLCMediaLibrary) { - for observer in observable.observers { - observer.value.observer?.medialibraryDidStartRescan?() + observable.notifyObservers { + $0.medialibraryDidStartRescan?() } } } extension MediaLibraryService { func medialibrary(_ medialibrary: VLCMediaLibrary, historyChangedOf type: VLCMLHistoryType) { - for observer in observable.observers { - observer.value.observer?.medialibrary?(self, historyChangedOfType: type) + observable.notifyObservers { + $0.medialibrary?(self, historyChangedOfType: type) } } }