Reputation: 3088
Can you please advise me how to initialize a Singleton in an iOS storyboard? My understanding so far is that the standard pattern looks like this inside the class that we want to be a singleton and this code works:
class var sharedInstance: LibraryAPI {
struct Singleton {
static let instance = LibraryAPI()
}
return Singleton.instance
}
The same pattern does not work for MusicPlayer:
I'm making a custom MusicPlayer object that relies on AVPlayer to play audio. I would like this MusicPlayer to exist as soon as the App is activated. At present the MusicPlayer is create in the Storyboard to allow me to use IBOutlets and IBActions to connect the buttons and labels to the MusicPlayer. The challenge is the MusicPlayer gets deallocated when I navigate back up the viewController stack. As shown in the figure below.
Which methods can I override to see when the Storyboard creates and destroys the MusicPlayer? So far you can see that override init() is called but deinit is not. I'm not having any luck finding the answer in the docs or online yet.
It's possible there is a better way to design this app. I think that Singleton makes sense because there should only ever be one MusicPlayer. Only it's state will change throughout the life of the app.
Thank you for your advice.
Upvotes: 0
Views: 425
Reputation: 299465
class var sharedInstance: LibraryAPI {
struct Singleton {
static let instance = LibraryAPI()
}
return Singleton.instance
}
This seems very over-complicated. You can generally just use:
final class MusicPlayer {
let sharedInstance = MusicPlayer()
init() {}
}
Things do get a bit more complex if Something
is not final
, but usually it can be for singletons.
At present the MusicPlayer is create in the Storyboard to allow me to use IBOutlets and IBActions to connect the buttons and labels to the MusicPlayer.
This won't work. See rdar:25450179 for my version of the problem. The latest explanation from Apple is that this probably won't be fixed. It would require too much redesign of Storyboards. They may change their mind, but it's a big change.
The closest you can come is to expose the singleton through your class.
class MyClass: UIViewController {
var musicPlayer: MusicPlayer { return MusicPlayer.sharedInstance() }
}
But this probably isn't going to do what you want, either. Generally, you need to tie your IBOutlets directly to the view controller. The view controller can then proxy to other objects as needed.
Upvotes: 1