I'm developing an app which uses a singleton pattern to store single-session user state data. It uses a framework which requires access to the same data, but currently the framework only finds nil
when trying to access the class properties. Here's how I have it set up currently.
In the framework:
open class UserStateBase {
var locationManager : LocationManagerDelegate!
var currentUser : String?
var currentPass : String?
// ... a dozen other properties
}
public var UserState : UserStateBase!
In the app:
import Framework
class UserStateClass : UserStateBase {
var locationManager = LocationManager()
var currentUser : String?
var currentPass : String?
// ... many more properties
}
var UserState = UserStateClass()
In the app's AppDelegate
class:
func application(...) {
// Override point for customisation after application launch
Framework.UserState = App_Module.UserState
}
Throughout both the framework and the app, I call UserState.username
to access the properties.
I know passing by value instead of by reference would work, but it's much more tedious due to the number of properties and the need to update them whenever they change in the app.
I originally tried making UserStateBase
a protocol, but that wouldn't work because it contains several properties which are defined as protocols for the implementing class to have implementations of, and the compiler complained it needed the implementations to be declared in the same way (eg locationManager
in the protocol needs the implemention to declare it as var locationManager: LocationManagerDelegate = LocationManager()
, meaning I'd have to cast to LocationManager
every time I want to access a function not in the LocationManagerDelegate
protocol).
This is why currentUser
and currentPass
are declared twice - my intention is for the subclass to override the base class, which I assume is what's happening since the compiler isn't complaining about ambiguous references.
Will this pattern work, with modifications, or do I need to pass all UserState values to the framework individually?
Because everything in Swift is implicitly internal
, the properties in UserStateBase
aren't actually exposed to the app (though the class itself is), so UserStateClass
can't override them (and the redefinitions don't cause a compiler error), hence when the framework is given a reference to the app's UserState
instance, all of the properties it knows about (the ones in UserStateBase
) are still uninitialised.
Realising this, I decided to bite the bullet and revert to using a protocol. This is the resulting pattern I used.
In the framework:
public protocol UserStateDelegate {
var locationManagerDelegate : LocationManagerDelegate { get }
var currentUser : String? { get }
var currentPass : String? { get }
// ... a dozen other properties
}
public var UserState : UserStateDelegate!
In the app:
import Framework
class UserStateClass : UserStateDelegate {
var locationManagerDelegate : LocationManagerDelegate = LocationManager()
// This computed property saves me from having to perform the cast everywhere it's used
var locationManager : LocationManager { return locationManagerDelegate as! LocationManager }
var currentUser : String?
var currentPass : String?
// ... many more properties
}
var UserState = UserStateClass()
And everything works as expected.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.