I'm trying to make a singleton class from a protocol, my intentions with this is to have multiple xxxxxHandlers, eg. SpotifyHandler, AppleMusicHandler and so on... and create the correct one when a user logs in with their music-account, then make the handler accessible all throughout the program.
But when i try to make SpotifyHandler i run into this error:
Property 'shared' in non-final class 'SpotifyHandler' must specify type 'Self' to conform to protocol 'MusicHandler'
On this line: static var shared: SpotifyHandler = SpotifyHandler()
Here's the code for the singleton class and protocol (separate files)
import Foundation
import SwiftUI
class SpotifyHandler : MusicHandler {
static var shared: SpotifyHandler = SpotifyHandler()
var is_logged_in: Bool = false;
func set_is_logged_in(is_logged_in: Bool) {
self.is_logged_in = is_logged_in
}
func print_status() {
print("--- Status ---")
print("Is logged in: \(self.is_logged_in)")
}
}
public protocol MusicHandler {
static var shared: Self { get }
var is_logged_in: Bool { get }
func set_is_logged_in(is_logged_in: Bool)
func print_status()
}
I am quite new to swift but have experience in other languages, i am open to suggestions on alternative ways to solve this if you have any. :)
The problem arises because
SpotifyHandlerbeing a class can have subclasses. If you create a sub class that inherits fromSpotifyHandlerit will not conform to the protocol becauseSelfhas got to simultaneously have typeSpotifyHandlerand the type of the subclass e.g.What type would you expect
footo have?There are two solution: you can do what @lorum ipsum suggests and make the shared instance of type
MusicHandleror you can stop people from subclassingSpotifyHandlerby making itfinali.e.As a general rule, as soon as your protocol has any
Selfrequirements or an associated type, you can't make non final classes conform to it.I don't recommend @lorum ipsum's approach on the whole because if I have
We know
foois aMusicHandler, but it's not anAdFreeSpotifyHandlerwhich is what you'd really want in the above fragment.