How do I declare a class level function in Swift? - swift

I can't seem to find it in the docs, and I'm wondering if it exists in native Swift. For example, I can call a class level function on an NSTimer like so:
NSTimer.scheduledTimerWithTimeInterval(0.2, target: self, selector: "someSelector:", userInfo: "someData", repeats: true)
But I can't seem to find a way to do it with my custom objects so that I could call it like:
MyCustomObject.someClassLevelFunction("someArg")
Now, I know we can mix Objective-C w/ Swift and it's possible that the NSTimer class method is a remnant from that interoperability.
Question
Do class level functions exist in Swift?
If yes, how do I define a class level function in Swift?

Yes, you can create class functions like this:
class func someTypeMethod() {
//body
}
Although in Swift, they are called Type methods.

You can define Type methods inside your class with:
class Foo {
class func Bar() -> String {
return "Bar"
}
}
Then access them from the class Name, i.e:
Foo.Bar()
In Swift 2.0 you can use the static keyword which will prevent subclasses from overriding the method. class will allow subclasses to override.

UPDATED: Thanks to #Logan
With Xcode 6 beta 5 you should use static keyword for structs and class keyword for classes:
class Foo {
class func Bar() -> String {
return "Bar"
}
}
struct Foo2 {
static func Bar2() -> String {
return "Bar2"
}
}

From the official Swift 2.1 Doc:
You indicate type methods by writing the static keyword before the method’s func keyword. Classes may also use the class keyword to allow subclasses to override the superclass’s implementation of that method.
In a struct, you must use static to define a Type method. For classes, you can use either static or class keyword, depending on if you want to allow your method to be overridden by a subclass or not.

you need to define the method in your class
class MyClass
{
class func myString() -> String
{
return "Welcome"
}
}
Now you can access it by using Class Name eg:
MyClass.myString()
this will result as "Welcome".

Related

Is final necessary for a singleton class in Swift?

To create a singleton class, I wrote something like this:
class SingletonEx{
var name = ""
private init(){}
static let sharedInstance = SingletonEx()
func instanceMethod(){
}
static func classMethod(){
}
}
Some tutorials say final is necessary while others just ignore final keyword. After I tried subclassing SingletonEx, I got the following results.
It seems I can't write an initializer for subclass, which means I can't use an override instance method in a subclass.
As far as I know, singleton definition is all about single instantiation and accessing instance methods through the only instance. So I don't think it is necessary to use final in the singleton definition. But both my teachers and some online tutorials say it is necessary.
I got confused, since you can't create a subclass instance anyway, even you override the instance methods, you can't use it or access it, what's the point to say final is necessary for a singleton class?
If I am wrong, please point out.
Super Class
First of all you need to know the properties and methods that are marked with private are just known to the Super class and Sub classes won't access them!
A class can inherit methods, properties, and other characteristics from another class. When one class inherits from another, the inheriting class is known as a subclass, and the class it inherits from is known as its superclass. Inheritance is a fundamental behavior that differentiates classes from other types in Swift.
Classes in Swift can call and access methods, properties, and subscripts belonging to their superclass and can provide their own overriding versions of those methods, properties, and subscripts to refine or modify their behavior. Swift helps to ensure your overrides are correct by checking that the override definition has a matching superclass definition.
In your case in SingletonEx class you market init with private which means that you can create object just in the body of the class! that means no one, no where, can't create an object of SingletonEx!
If you want to a method end up in Super Class and you don't want to Sub classes overide that method you need to mark that method with final which means it's not private but its available only from Super class!
Sub Class
When class Y Inheritance from SingletonEx which means that cant create an object outside of the class ! because Super class initializer is unavailable during init() method from class Y ! While you need to call the super.init() if you want to initialize an object from Y class !
if you remove private from private init() {} from SingletonEx class you be able to create object from SingletonEx class and also from Y class !
your code should looks like this :
Swift 4 :
class SingletonEx{
var name = ""
init(){}
static let sharedInstance = SingletonEx()
func instanceMethod(){
}
static func classMethod(){
}
}
class Y : SingletonEx {
private var yName = "Y name is : "
init(name:String) {
super.init()
self.name = self.yName + name
}
}
Usage :
override func viewDidLoad() {
super.viewDidLoad()
let yObject = Y.init(name: "badGirl :D ")
print(yObject)
// --> Output : Y name is : badGirl :D
}

Swift: "failable initializer 'init()' cannot override a non-failable initializer" vs. default parameters

If I declare
public class A: NSObject {
public class X { }
public init?(x: X? = nil) { }
}
all is fine. When using it like let a = A(), the initializer is called as expected.
Now, I'd like to have the nested class X private, and the parameterized init as well (has to be, of course). But a simple init?() should stay publicly available as it was before. So I write
public class B: NSObject {
private class X { }
private init?(x: X?) { }
public convenience override init?() { self.init(x: nil) }
}
But this gives an error with the init?() initializer: failable initializer 'init()' cannot override a non-failable initializer with the overridden initializer being the public init() in NSObject.
How comes I can effectively declare an initializer A.init?() without the conflict but not B.init?()?
Bonus question: Why am I not allowed to override a non-failable initializer with a failable one? The opposite is legal: I can override a failable initializer with a non-failable, which requires using a forced super.init()! and thus introduces the risk of a runtime error. To me, letting the subclass have the failable initializer feels more sensible since an extension of functionality introduces more chance of failure. But maybe I am missing something here – explanation greatly appreciated.
This is how I solved the problem for me:
I can declare
public convenience init?(_: Void) { self.init(x: nil) }
and use it like
let b = B(())
or even
let b = B()
— which is logical since its signature is (kind of) different, so no overriding here. Only using a Void parameter and omitting it in the call feels a bit strange… But the end justifies the means, I suppose. :-)
After a bit of fiddling I think I understand. Let's consider a protocol requiring this initializer and a class implementing it:
protocol I {
init()
}
class A : I {
init() {}
}
This gives the error: "Initializer requirement 'init()' can only be satisfied by a required initializer in non-final class 'A'". This makes sense, as you could always declare a subclass of A that doesn't inherit that initializer:
class B : A {
// init() is not inherited
init(n: Int) {}
}
So we need to make our initializer in A required:
class A : I {
required init() {}
}
Now if we look at the NSObject interface we can see that the initializer is not required:
public class NSObject : NSObjectProtocol {
[...]
public init()
[...]
}
We can confirm this by subclassing it, adding a different initializer and trying to use the normal one:
class MyObject : NSObject {
init(n: Int) {}
}
MyObject() // Error: Missing argument for parameter 'n:' in call
Now here comes the weird thing: We can extend NSObject to conform to the I protocol, even though it doesn't require this initializer:
extension NSObject : I {} // No error (!)
I honestly think this is either a bug or a requirement for ObjC interop to work (EDIT: It's a bug and already fixed in the latest version). This error shouldn't be possible:
extension I {
static func get() -> Self { return Self() }
}
MyObject.get()
// Runtime error: use of unimplemented initializer 'init()' for class '__lldb_expr_248.MyObject'
Now to answer your actual question:
In your second code sample, the compiler is right in that you cannot override a non-failable with a failable initializer.
In the first one, you aren't actually overriding the initializer (no override keyword either), but instead declaring a new one by which the other one can't be inherited.
Now that I wrote this much I'm not even sure what the first part of my answer has to do with your question, but it's nice to find a bug anyways.
I suggest you to do this instead:
public convenience override init() { self.init(x: nil)! }
Also have a look at the Initialization section of the Swift reference.

Extending a class with instance method

I'm trying to extend the functionality of a existing type in Swift. I want to use dot syntax to call the methods on the type.
I want to say:
existingType.example.someMethod()
existingType.example.anotherMethod()
I'm currently using an extension like so:
extension ExistingType {
func someMethod() {
}
func anotherMethod() {
}
}
existingType.someMethod()
existingType.anotherMethod()
Doing this will expose too many functions. So, I want to write these methods in a class, and just extend the ExistingType to use an instance of the class. I'm not sure the right way to go about this.
if I were actually implementing the existing type, I would do the following:
struct ExistingType {
var example = Example()
}
struct Example {
func someMethod() {
}
func anotherMethod() {
}
}
Allowing me to call the methods by:
let existingType = ExistingType()
existingType.example.someMethod()
The issue is I'm not implementing the type, because it already exists. I just need to extend it.
It looks like you are trying to add another property example the existing class ExistingType and call methods of that property. You cannot add properties in extensions, though. The only way to add another property to the existing class is to subclass it.
You can create a new struct.
struct NewType {
let existingType: ExistingType
func someMethod() {
}
func anotherMethod() {
}
}

Final self class for generics, in method signature, in Swift

I have a BaseObject model that defines common behaviour I want to share across all my data entities. It has a method like this:
class BaseObject {
static func fetch(block: ((Results<BaseObject>) -> Void)) {
// networking code here
}
}
Naturally, I need the signature of this method be dynamic enough so that a model of class Products
class Products: BaseObject { //...
yields a Results<Product> list instead of Results<BaseObject>. I don't want to re-implement the fetch method in every subclass, because, save for the exact final subclass name used in the body and in the signature, it would be identical.
I cannot use Self:
Do I have any options at all?
You can now do this as of Swift 2.0 as it allows default implementations of methods in protocols. To do so, you would make your base class a protocol, and use Self, as you tried in your example.
https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Protocols.html#//apple_ref/doc/uid/TP40014097-CH25-ID521
Edit:
This compiles in Swift 2.0 / Xcode 7.0 Beta:
class Results<T> {
}
protocol BaseObject {
static func fetch(block: ((Results<Self>) -> Void))
}
extension BaseObject {
static func fetch(block: ((Results<Self>) -> Void)) {
// networking code here
}
}
This feature is only available in Swift 2.0, to my knowledge, there is no solution in Swift 1.2 or previous.

Why is `required` not a valid keyword on class functions in Swift?

It seems that there are a few situations in which a required keyword on Swift class functions would be extremely beneficial, particularly due to the ability of class functions to return Self.
When returning Self from a class func, there are unfortunately two restrictions that make implementing said function very difficult/inhibitive:
You cannot use Self as a type check inside the function implementation, ie:
class Donut {
class func gimmeOne() -> Self {
// Compiler error, 'Self' is only available in a protocol or as the result of a class method
return Donut() as Self
}
}
You cannot return the actual type of the class itself, ie:
class Donut {
class func gimmeOne() -> Self {
// Compiler error, 'Donut' is not convertible to 'Self'
return Donut()
}
}
The reason for these compiler errors is valid. If you have a GlazedDonut subclass that does not override this class function, it is possible that calling GlazedDonut.gimmeOne() will give you back a Donut, which is not a Self.
It seems this situation could be alleviated by allowing classes to specify these functions with required. This would ensure that any subclasses override the method and encur their own round of type checking, making sure that a GlazedDonut returns itself in all cases, eliminating the possibility for a Donut to come back.
Is there a technical, authoritative reason why this has not been added? I'd like to suggest it as an improvement to the Swift team, but want to ensure there isn't an obvious reason why it has been omitted, or cannot be accomplished.
The idea for this question originates here:
https://stackoverflow.com/a/25924224/88111
required is generally only used on initializers, because initializers are not always inherited in Swift. Therefore, to allow you to call an initializer on a variable class (i.e. a value of metaclass type, say Foo.Type), you need to know that that class Foo, and all possible subclasses, have this initializer.
However, methods (both instance methods and class methods) are always inherited. Therefore, required is not necessary.
By the way, your assertion that "You cannot return the actual type of the class itself" is not true. (In fact, the error "'Self' is only available in a protocol or as the result of a class method" itself says you can return the type of the class itself.) Similar to in Objective-C, you can do:
class Donut {
required init() { }
class func gimmeOne() -> Self {
return self()
}
}
You could use a protocol to make the method 'required'
protocol IDonut{
class func gimmeOne()->Donut;
}
class Donut:IDonut {
class func gimmeOne() -> Donut {
return Donut();
}
}
class GlazedDonut: Donut, IDonut{
override class func gimmeOne()->Donut{
return GlazedDonut();
}
}