Swift singleton pattern in a framework - ios

I have a workspace in Xcode with my framework and with a test-app, so two xcode projects in one workspace.
In the framework I am building a singleton class, like so:
public let sharedInstance = MKUserPreferences()
class func A() {}
class func B() {}
But when I am in the app project and trying to call MKUserPreferences.sharedInstance.A(), it won't autocomplete and the method is not available. How do I solve this?
EDIT: please keep in mind that MKUserPreferences is in a dynamically linked framework and I want to use it in my app (other project).

A and B are defined as class methods. Therefore, they can be accessed from the class MKUserPreferences.A() but not from an instance.
If you want them to be instance methods, just remove class from their definition:
public class MKUserPreferences {
public static let sharedInstance = MKUserPreferences()
private init() {} // Prevents using the default '()' initializer
public func A() {}
public func B() {}
}
Also, you need to explicitly define the methods you want to be public. In Apple's words:
A public type defaults to having internal members, not public members. If you want a type member to be public, you must explicitly mark it as such. This requirement ensures that the public-facing API for a type is something you opt in to publishing, and avoids presenting the internal workings of a type as public API by mistake.

In swift ,you can build a OneLine singleton class like this:
static let sharedInstance = MKUserPreferences()
private override init() {
super.init()
}
func otherFunc(){}
and you can use like this:
MKUserPreferences.sharedInstance.otherFunc()
hope this will helped you .

Related

How to create Singleton in generic class using swift 4.2?

I have been trying to convert a singleton class to generic. Since swift doesn't support stored property in generic class Singleton could not be implemented. I tried all the possible solutions that I know but nothing works. Other Stackoverflow answers related to this topic doesn't help either. Can someone help me to get on the right path, please? Thanks in advance.
I have added the sample code below.
class SingleTonClass<T: Equatable & RawRepresentable>: NSObject where T.RawValue == String {
private var catlog: CatlogModelClass<T>?
private var catlogArray = [CatlogModelClass<T>]()
**// This stored property Now has to be changed to support Generic**
private static var shared : SingleTonClass = {
return SingleTonClass()
}()
// Accessor for Singleton
static func sharedInstance() -> SingleTonClass {
return shared
}
private override init () {}
}
If you want it to be non-singleton, you need to create a public constructor.
You should pass in the catalog and catalogArray into the constructor and initialize self.catalog and self.catalogArray. You then need to remove the static shared instance of the class, because your new setup would require you to create an instance of it.

Instance member "xxx" cannot be used on type "XXX" - Specifically iOS Swift 4 Tutorial on Workout Extensions [duplicate]

I'm trying to access the name variable from Indicator class, which inherits from Person. However, I believe I'm not doing my initialization right.
I get the following: 'error: instance member 'name' cannot be used on type 'Indicator'`.
class Person {
var name: String
init(myName: String){
self.name = myName
}
deinit {
Indicator.letKnowPersonDeinitialized()
}
}
class Indicator: Person {
convenience init() {
self.init()
}
static func letKnowPersonDeinitialized() {
print("\(name)")
}
}
You cannot access non-static stuff directly in a static method.
The method letKnowPersonDeinitialized is static because it is modified with the static modifier:
static func letKnowPersonDeinitialized() {
^
|
here!
}
The name property of Person is not static because it is not modified by static.
Since non-static members belong to each individual instance of that class and static members belong to the class itself, static members have no direct access to non-static members. They can only access non-static members when an instance is present.
To solve your problem, add a parameter to the letKnowPersonDeinitialized method:
static func letKnowPersonDeinitialized(person: Person) {
print(person.name)
}
And in the deinitializer:
deinit {
Indicator.letKnowPersonDeinitialized(self)
}
VERY IMPORTANT STUFF:
I don't think your code is designed well. This is not how you use inheritance.
Inheritance means "is a kind of". So if Indicator inherits from Person, it means that an indicator is a kind of person.
According to common sense, an indicator is not a person. Therefore, it is not suitable to use inheritance here. It makes little sense.

How to use a generic class without the type argument in Swift?

I want to encapsulate a generic object in another class without setting the generic type argument. I created a base Animal<T> class and defined other subclasses from it. Example:
public class Animal<T: YummyObject> {
// Code
}
public class Dog: Animal<Bark> {
// Code
}
public class Cat: Animal<Meow> {
// Code
}
and defined an Animal property, without the type argument, in the UITableView extension bellow:
extension UITableView {
private static var animal: Animal!
func addAnimal(animal: Animal) {
UITableView.animal = animal
}
}
but I get the following compile error when doing so:
Reference to generic type Animal requires arguments in <...>.
This seems to work fine in Java. How can I accomplish the same thing in Swift as well?
Swift doesn’t yet support wildcard-style generics like Java does (i.e., Animal<?>). As such, a common pattern is to define a type-erased superclass, protocol (or wrapper) to enable such usage instead. For instance:
public class AnyAnimal {
/* non-generic methods */
}
and then use it as your superclass:
public class Animal<T: YummyObject>: AnyAnimal {
...
}
Finally, use AnyAnimal in your non-generic code instead:
private static var animal: AnyAnimal!
Examples in the Swift Standard Library. For a practical example, see the KeyPath, PartialKeyPath, and AnyKeyPath classes hierarchy. They follow the same pattern I outlined above. The Collections framework provides even further type-erasing examples, but using wrappers instead.

Using Typhoon, create instance of a subclass of a class which has dependencies

I am using Typhoon for dependencies injection in Swift for iOS.
I have created an assembly to inject dependencies in a class called BaseRequest like this:
public class NetworkAssembly: TyphoonAssembly {
public dynamic func baseRequest() -> AnyObject {
return TyphoonDefinition.withClass(BaseRequest.self){
(definition) in
definition.useInitializer("initWithRetryCount:userUmbrella:networkQueueManager:"){
(initializer) in
initializer.injectParameterWith((TyphoonConfig("network.request.retry.count") as! NSNumber).integerValue)
initializer.injectParameterWith(self.coreComponents.userUmbrella())
initializer.injectParameterWith(self.networkQueueManager())
}
}
}
}
Now, I am trying to create a subclass of BaseRequest with a factory method like this:
class DownloadLibrariesRequest: BaseRequest {
var libraries:Array<String> = []
class func downloadLibraries(libraries:Array<String>)->Void{
let request: DownloadLibrariesRequest = DownloadLibrariesRequest(.....)
request.libraries = libraries
}
}
I need to be able to create an instance of DownloadLibrariesRequest and call the NetworkAssembly for BaseRequest since I need to use another init in the subclasses.
Also, I need to mention that I will have around 50 such subclasses, so creating assemblies for all of them doesn't sound too great at the moment.
To create a definition with shared configuration, in order to avoid repetition, use the parent feature.

How do you make a static class in swift?

I want to create a static class in swift, is this possible? If so how?
I tried:
static class MyClass
but get the error Declaration cannot be marked 'static'
There's no static class, but you can make one by just adding static methods only.
The problem is that (as of today) classes cannot have static properties, so you have 2 options:
use a struct instead of a class, defining all its methods and properties as static
use the singleton pattern
The second option is in my opinion a better solution, unless you have specific reason for not wanting it.
static means no instance, so I would make it a struct with no initializer:
struct MyStruct {
#available(*, unavailable) private init() {}
static var foo = "foo"
static func doSomething(a: String) -> String {
return a + foo
}
}

Resources