A static field inherited from the base class or protocol - how? - ios

I want to be able to have the classes which have a static property (field) which is either inherited from the base class or "mixed" from a protocol. And every class should have it's own implementation of that property. Is it possible? Preferably, it to be immutable.
class C1 {
static let stProperty = "my prorepty1"
}
class C2 {
static let stProperty = "my prorepty2"
}

It's possible, but it's really hard to make this useful in Swift. How do you plan to refer to this property? Let's start with a super-simple implementation:
protocol SomeProtocol {
static var prop: String { get }
}
class C1: SomeProtocol {
static let prop = "This is One"
}
Great. So now I want a function that uses this:
func useProp(x: SomeProtocol) -> String {
return x.prop
// 'SomeProtocol' does not have a member named 'prop'
}
That doesn't work. x is an instance, but I want the type.
// Accessing members of protocol type value 'SomeProtocol.Type' is unimplemented
func useProp(x: SomeProtocol.Type) -> String {
return x.prop
}
This is probably how it will work some day given the word "unimplemented." But it doesn't work today.
func useProp(x: SomeProtocol) -> String {
// Accessing members of protocol type value 'SomeProtocol.Type' is unimplemented
return x.dynamicType.prop
}
Same thing.
Today, you really have to hang this on the object itself and not use static or class:
protocol SomeProtocol {
var prop: String { get }
}
class C1: SomeProtocol {
let prop = "This is One"
}
func useProp(x: SomeProtocol) -> String {
return x.prop
}
That's not so terrible in many cases, since the value for the class is probably also the value for any given instance of the class. And it's really all we can do today.
Of course your problem might be that you don't have an instance yet and you need this information to build an instance. That's really hard today and you should probably rethink your design. You'll generally have to use some other pattern like a Builder. See Generic Types Collection for more.
Now you also said:
or "mixed" from a protocol
I wouldn't say "mixed" here. If you really mean this like a Ruby "mixin", there is no such thing in Swift today. Swift folks often refer to this feature as "default implementation," and it's not currently possible (though I do expect it to come eventually). The only thing you can do in the protocol is say that the implementor has to provide this method somehow. You can't provide it for them.

Sure you can do that with a protocol:
protocol SomeProtocol {
static var foo: String { get }
}
class One: SomeProtocol {
class var foo: String {
get {
return "This is One"
}
}
}
Btw I agree with Rob Napier below that this is a bit off a oddball feature. I do think there are probably use-cases for it, but I also think those can be better implemented with other language features

protocol P {
class var stProperty: String { get }
}
class C1 {
class var stProperty: String {
return = "my property1"
}
}
class C2 {
class var stProperty: String {
return = "my property2"
}
}
Usage:
C2.prop //"my property2"
If you try:
C2.prop = "new value" //"cannot assign to the result of this expression"

Related

Typecasting to Generic class in Swift

Im trying to typecast an object to a class that uses Generics. Here is some code for better understanding
I've a protocol named wheel
protocol Wheel
I've a class named Wings
class Wings {
var count = 2
}
Now, I have a generic class named VehicleWrapper
class VehicleWrapper<T: Wings&Wheel> {
var vehicle: T
}
Now finally I have an object which I would want to typecast to VehicleWrapper and use the count property from Wings class but I dont know the type T would be while typecasting this. Is there a way to typecast this and use the count variable?
One problem with your question is that your code is illegal. You can't just say protocol Wheel like that; you need curly braces (which may or may not contains the protocol's requirements). And your VehicleWrapper has no initializer, so the compiler will never allow it.
But let's suppose we've taken care of all that. My guess, then, is that the problem you're having is that it is not permitted to cast to a generic. For example, you cannot cast to a VehicleWrapper. This is because a generic is not a type. The type is the resolved generic.
To illustrate:
protocol Wheel {}
class Wings {
var count = 2
}
class VehicleWrapper<T: Wings & Wheel> {
var vehicle: T
init(vehicle: T) { self.vehicle = vehicle }
}
class Thing: Wings, Wheel {}
let thing = Thing()
class What<T: Wings & Wheel>: VehicleWrapper<T> {}
let what = What(vehicle: thing)
if let what = what as? VehicleWrapper { // compile error
print(what.vehicle.count)
}
As you can see, our attempt cast to a VehicleWrapper is met with scorn from the compiler. We could legally, however, try casting to a VehicleWrapper<Thing>.
The real issue for your question is that it is difficult to imagine a use case where it make sense to need to do that, since how could this object come into existence in the first place without your knowing what it is?
It isn't clear what you are trying to achieve, but I don't think that generics are the way to achieve it.
Generics essentially allow you to define operations on types, independent of what those types are. This is different to inheritance or protocols that allow you define the operations that can be performed on a particular type.
Most importantly, different generic object types are not co-variant; There is no functional relationship between GenericClass<SuperClass> and GenericClass<SubclassOfSuperClass> even though the generic types do have a inheritance relationship.
Taking your example, you are probably better off using some protocols.
Consider
protocol Wheeled {
var numberOfWheels: Int { get }
}
protocol Movable {
func moveForward()
func stop()
}
Now, we can define a Vehicle class and some subclasses in terms of those protocols:
class Vehicle: Movable {
var name: String
var seatingCapacity: Int
init(name: String, seatingCapacity: Int) {
self.name = name
self.seatingCapacity = seatingCapacity
}
func moveForward() {}
func stop() {}
}
class Car: Vehicle, Wheeled {
var numberOfWheels: Int
init(name: String) {
self.numberOfWheels = 4
super.init(name: name, seatingCapacity: 5)
}
}
class Truck: Vehicle, Wheeled {
var numberOfWheels: Int
init(name: String) {
self.numberOfWheels = 18
super.init(name: name, seatingCapacity: 2)
}
}
Now, let's define a light aircraft:
protocol Winged {
var numberOfWings: Int { get }
func takeOff()
func land()
}
class LightAirplane: Vehicle, Wheeled, Winged {
var numberOfWheels: Int
var numberOfWings: Int
init(name: String) {
self.numberOfWheels = 3
self.numberOfWings = 2
super.init(name: name, seatingCapacity: 4)
}
func takeOff() {}
func land() {}
}
Using these definitions we can take an Vehicle (whether it is a car, truck or plane) and ask it to moveForward() or stop().
We can take an object that conforms to Winged and ask it to takeOff() and land().
Where could you use generics? Let's look at our Truck - We can make that a generic class:
class CargoTruck<Cargo>: Truck {
private (set) var cargo: Cargo?
init(name: String, cargo: Cargo? = nil) {
self.cargo = cargo
super.init(name: name)
}
func load(cargo: Cargo) {
self.cargo = cargo
}
func unload() {
self.cargo = nil
}
}
Now we have a subclass of Truck that can load and unload some sort of Cargo but our implementation doesn't need to care what it is:
struct Cattle {}
struct Appliance {}
var cattleTruck = CargoTruck(name:"Cattle Truck", cargo:[Cattle]())
var applianceTruck = CargoTruck(name:"Container Truck", cargo: Appliance()))
We have cattleTruck which is a CargoTruck<[Cattle]? - i.e. it can hold an array of Cattle and applianceTruck which is a CargoTruck<Appliance> - It can hold a single Appliance
What if we wanted to limit the type of the cargo - We can add a constraint to the generic type:
protocol ShippingContainer {
}
struct StandardContainer: ShippingContainer {
}
struct RefrigeratedContainer: ShippingContainer {
}
class ContainerTruck<Cargo: ShippingContainer>: CargoTruck<Cargo> {
}
let refer = ContainerTruck(name: "ReferTruck", cargo: RefrigeratedContainer())
refer.unload()
let bad = ContainerTruck(name:"Error", cargo: 12) // Error an Int is not a container
The generic doesn't define what the truck can do (move, load, unload etc), but rather what it does it to - It can load a ShippingContainer

Add protocol to super class which will force other classes that inherit from it to implement protocol

So I'm new to iOS development and have been working on minor changes to an app at my internship that has a relatively large objective-c code base. I've been learning swift from Treehouse(Wow, love them!) and I just learned about protocols. Currently, they should be used in certain instances and the instructor used this example.
Say you have a company with two different types of employees: Salary and Hourly(Pretty common). Now, they both would inherit from a super class called Employee and both would have to call a function called "pay" which would pay the employee. How do you enforce these classes to implement that function? Sure, use a protocol but that would require you to remember to add that to the function declaration. Is there a way to just add the protocol to the super class "Employee" and then whatever inherits from that class would have to follow that protocol that's part of that superclass. Is there another way to do this? Thanks!
What you are looking for is an abstract class. The purpose of an abstract class is to behave as a base class for concrete classes to inherit from, but an abstract class cannot be instantiated directly.
If Employee was an an abstract class then any attempt to actually instantiate an instance of Employee would be reported as an error by the compiler. You would need to instantiate a concrete subclass of Employee, such as SalariedEmployee or HourlyEmployee.
The definition of the Employee class would include that the calculatePay method was required and again a compile time error would occur if a concrete subclass did not implement that method.
Now, the bad news. Neither Objective-C nor Swift supports abstract classes.
You can provide a similar kind of class by providing an implementation of a method that throws an exception if it isn't overridden by a subclass. This gives a runtime error rather than a compile time error.
e.g.
class Employee {
var givenName: String
var surname: String
...
init(givenName: String, surname: String) {
self.givenName = givenName
self.surname = surname
}
func calculatePay() -> Float {
fatalError("Subclasses must override calculatePay")
}
}
class SalariedEmployee: Employee {
var salary: Float
init(givenName: String, surname: String, annualSalary: Float) {
salary = annualSalary
super.init(givenName: givenName, surname: surname)
}
override func calculatePay() -> Float {
return salary/12 // Note: No call to super.calculatePay
}
}
Whether the calculatePay is part of the base class or assigned to the base class through an extension that adds conformance to a protocol, the result is the same;
The Employee class will need a default implementation of the function that generates some sort of error
Failure of a subclass to implement the method will not cause a compile time error
You could assign a protocol, say, Payable to each subclass individually, but then as the protocol was not part of the base class, you couldn't say something like:
var employees[Employee]
for e in employees {
let pay = e.calculatePay()
}
You would have to use the slightly more complicated:
for e in employees {
if e is Payable {
let pay = e.calculatePay()
}
}
Unfortunately abstract functions are not yet supported. A possible workaround is to launch a fatalError when such function is not overridden by a subclass, doing so:
protocol YourProtocol {
func pay()
}
class Employee: YourProtocol {
func pay() {
fatalError("Must Override")
}
}
class SubEmployee: Employee {
func pay() {
print("stuff here")
}
}
My approach to this is to include the delegate as a parameter in the class initializer. See the code below:
protocol ProtocolExample {
func somethingNeedsToHappen()
}
// typical class example with delegate property for the required protocol
class ClassExampleA {
var delegate: ProtocolExample!
init() {
}
func aCriticalMethodWithUpdates() {
delegate.somethingNeedsToHappen()
}
}
// use class example in a view controller. Can easily forget to invoke the delegate and protocol
class MySampleViewControllerA: UIViewController {
var classExampleA : ClassExampleA!
func loadMyData() {
classExampleA = ClassExampleA()
}
}
// an alternative approach for the class is to include the delegate parameter in the initializer.
class ClassExampleB {
var delegate: ProtocolExample!
init(delegateForUpdates: ProtocolExample) {
delegate = delegateForUpdates
}
func doSomething() {
delegate.somethingNeedsToHappen()
}
}
// go to use it and you're reminded that the parameter is required...
class MySampleViewControllerB: UIViewController {
var classExampleB: ClassExampleB!
func loadMyData() {
classExampleB = ClassExampleB() // error: Missing argument for parameter 'delegateForUpdates' in call
}
}
// so to avoid error:
class MySampleViewControllerC: UIViewController {
var classExampleB: ClassExampleB!
func loadMyData() {
classExampleB = ClassExampleB(delegateForUpdates: <#ProtocolExample#>)
}
}

Building composable objects in Swift with protocols

I'm trying to create a way to build compassable objects in Swift. I feel like I'm almost there with what I have but it's still not 100% correct.
What I'm aiming for is to have a FlowController object that can create our UIViewControllers and then give them any of the dependencies that they need.
What I'd also like to do is make this work as loosely as possible.
I have a small example here that works but is not ideal. I'll explain...
Here are two objects that can be used as components... Wallet and User.
class Wallet {
func topUp(amount: Int) {
print("Top up wallet with £\(amount)")
}
}
class User {
func sayHello() {
Print("Hello, world!")
}
}
We then define a Component enum that has cases for each of these...
enum Component {
case Wallet
case User
}
... And a protocol that defines a method requiresComponents that returns an array of Components.
This is where the problem arises. In order for the "factory object" to put the components into a Composable object we need to define the user and wallet properties in the protocol also.
protocol Composable {
var user: User? {get set}
var wallet: Wallet? {get set}
func requiresComponents() -> [Component]
}
In an attempt to make these properties "optional" (not Optional) I have defined an extension to the Composable protocol that defines these vars as nil.
extension Composable {
var user: User? {
get {return nil}
set {}
}
var wallet: Wallet? {
get {return nil}
set {}
}
}
Now I declare the class that I want to make Composable. As you can see it requires the User component and declares the variable.
class SomeComposableClass: Composable {
var user: User?
func requiresComponents() -> [Component] {
return [.User]
}
}
Now the FlowController that will create these and add the components to them. You can see here that I have had to take the object, create a local var version of it and then return the updated object. I think this is because it doesn't know the type of objects that will be conforming to the protocol so the parameter can't be mutated.
class FlowController {
func addComponents<T: Composable>(toComposableObject object: T) -> T {
var localObject = object
for component in object.requiresComponents() {
switch component {
case .Wallet:
localObject.wallet = Wallet()
print("Wallet")
case .User:
localObject.user = User()
print("User")
}
}
return localObject
}
}
Here I create the objects.
let flowController = FlowController()
let composable = SomeComposableClass()
And here I add the components. In production this would be done all inside the FlowController.
flowController.addComponents(toComposableObject: composable) // prints "User" when adding the user component
compassable.user?.sayHello() // prints "Hello, world!"
As you can see, it works here. The user object is added.
However, as you can also see. Because I have declared the vars in the protocol the composable object also has a reference to a wallet component (although it will always be nil).
composable.wallet // nil
I feel like I'm about 95% of the way there with this but what I'd like to be able to do is improve how the properties are declared. What I'd like is for that last line... composable.wallet to be a compile error.
I could do this by moving the declaration of the properties out of the protocol but then I have the problem of not being able to add the properties to any object that conforms to the Composable protocol.
What would be awesome is for the factory object to be able to add the properties without relying on the declaration. Or even have some sort of guard that says "if this object has a property call user then add the user component to it". Or something like that.
If anyone knows how I could get the other 5% of this working it would be awesome. Like I said, this works, just not in an ideal way.
Thanks :D
Hacky Edit
Hmm... As a quick tacky, horrible, "no-one-should-do-this" edit. I have changed my protocol extension to be like this...
extension Composable {
var user: User? {
get {fatalError("Access user")}
set {fatalError("Set user")}
}
var wallet: Wallet? {
get {fatalError("Access wallet")}
set {fatalError("Set waller")}
}
}
Now at least the program will crash if I try to access a variable I have not defined. But it's still not ideal.
Edit after reading Daniel's blog
OK, I think I've done what I wanted. Just not sure that it's exactly Swifty. Although, I also think it might be. Looking for a second opinion :)
So, my components and protocols have become this...
// these are unchanged
class Wallet {
func topUp(amount: Int) {
print("Top up wallet with £\(amount)")
}
}
// each component gets a protocol
protocol WalletComposing {
var wallet: Wallet? {get set}
}
class User {
func sayHello() {
print("Hello, world!")
}
}
protocol UserComposing {
var user: User? {get set}
}
Now the factory method has changed...
// this is the bit I'm unsure about.
// I now have to check for conformance to each protocol
// and add the components accordingly.
// does this look OK?
func addComponents(toComposableObject object: AnyObject) {
if var localObject = object as? UserComposing {
localObject.user = User()
print("User")
}
if var localObject = object as? WalletComposing {
localObject.wallet = Wallet()
print("Wallet")
}
}
This allows me to do this...
class SomeComposableClass: UserComposing {
var user: User?
}
class OtherClass: UserComposing, WalletComposing {
var user: User?
var wallet: Wallet?
}
let flowController = FlowController()
let composable = SomeComposableClass()
flowController.addComponents(toComposableObject: composable)
composable.user?.sayHello()
composable.wallet?.topUp(amount: 20) // this is now a compile time error which is what I wanted :D
let other = OtherClass()
flowController.addComponents(toComposableObject: other)
other.user?.sayHello()
other.wallet?.topUp(amount: 10)
This seems like a good case for applying the Interface Segregation Principle
Specifically, rather than having a master Composable protocol, have many smaller protocols like UserComposing and WalletComposing. Then your concrete types that wish to compose those various traits, would just list their "requiredComponents" as protocols they conform to, i.e:
class FlowController : UserComposing, WalletComposing
I actually wrote a blog post that talks about this more extensively and gives more detailed examples at http://www.danielhall.io/a-swift-y-approach-to-dependency-injection
UPDATE:
Looking at the updated question and sample code, I would only suggest the following refinement:
Going back to your original design, it might make sense to define a base Composing protocol that requires any conforming class to create storage for composed traits as a dictionary. Something like this:
protocol Composing : class {
var traitDictionary:[String:Any] { get, set }
}
Then, use protocol extensions to add the actual composable trait as a computed property, which reduces the boilerplate of having to create those properties in every conforming class. This way any class can conform to any number of trait protocols without having to declare a specific var for each. Here's a more complete example implementation:
class FlowController {
static func userFor(instance:UserComposing) -> User {
return User()
}
static func walletFor(instance:WalletComposing) -> Wallet {
return Wallet()
}
}
protocol Composing : class {
var traitDictionary:[String:Any] { get, set }
}
protocol UserComposing : Composing {}
extension UserComposing {
var user:User {
get {
if let user = traitDictionary["user"] as? User {
return user
}
else {
let user = FlowController.userFor(self)
traitDictionary["user"] = user
return user
}
}
}
}
protocol WalletComposing {}
extension WalletComposing {
var wallet:Wallet {
get {
if let wallet = traitDictionary["wallet"] as? Wallet {
return wallet
}
else {
let wallet = FlowController.walletFor(self)
traitDictionary["wallet"] = wallet
return wallet
}
}
}
}
class AbstractComposing {
var traitDictionary = [String:Any]()
}
Not only does this get rid of those pesky optionals you have to unwrap everywhere, but it makes the injection of user and wallet implicit and automatic. That means that your classes will already have the right values for those traits even inside their own initializers, no need to explicitly pass each new instance to an instance of FlowController every time.
For example, your last code snippet would now become simply:
class SomeComposableClass: AbstractComposing, UserComposing {} // no need to declare var anymore
class OtherClass: AbstractComposing, UserComposing, WalletComposing {} //no vars here either!
let composable = SomeComposableClass() // No need to instantiate FlowController and pass in this instance
composable.user.sayHello() // No unwrapping the optional, this is guaranteed
composable.wallet.topUp(amount: 20) // this is still a compile time error which is what you wanted :D
let other = OtherClass() // No need to instantiate FlowController and pass in this instance
other.user.sayHello()
other.wallet.topUp(amount: 10) // It all "just works" ;)

Singleton in one line on Swift 2.0

Please help me with Swift,
I need singleton with can inheritance.
I can do like this
class A {
var defaultPort: Int
required init() {
self.defaultPort = 404
}
class var defaultClient: A {
struct Static {
static var onceToken: dispatch_once_t = 0
static var instance: A? = nil
}
dispatch_once(&Static.onceToken) {
Static.instance = self.init()
}
return Static.instance!
}
}
but in swift 2.0 we can do like this
static let defaultClient = A() //self.init()
but it creates an instance of the class A any way.
How i can use like this self.init()
static let defaultClient = self.init()
in order to be able to inherit
UPD
best way for now
class A {
class func defaultClient() -> Self {
struct Static {
static var onceToken: dispatch_once_t = 0
static var instance: A? = nil
}
dispatch_once(&Static.onceToken) {
Static.instance = self.init()
}
return instance(Static.instance, asType: self)
}
}
here we need helper as
func instance<T>(instance: Any, asType type: T.Type) -> T {
let reurnValue = instance as! T
return reurnValue
}
because another way cast A to Self not exist, for now.
p.s. crazy swift way!
why i can not do instance as! Self
Your question isn't very clear. You're looking for something like the class constant solution posted in this answer, but which automatically uses "my own class" instead of explicitly creating an instance of a specific class... right?
That is, you want to turn this:
class Singleton {
static let sharedInstance = Singleton()
}
into this:
class Singleton {
static let sharedInstance = SomeMagicThing()
}
class SingletonSubclass {}
where SomeMagicThing automatically creates a Singleton instance when you call Singleton.sharedInstance, and a SingletonSubclass instance when you call SingletonSubclass.sharedInstance. Correct?
Sorry, that can't be done (as of Swift 2.1).
Part of your issue is that static and class mean two different things. The static modifier means that the declaration it modifies is associated only with a specific type declaration. So, the Singleton type owns a pointer to a specific object -- its subclasses don't inherit that pointer. (And if they did, would it point to the same object or a subclass-specific one?)
If you could create a class var or class let, that'd (in theory) give you the kind of dispatch/inheritance you want. But trying that gives you an error (emphasis mine):
class stored properties not yet supported in classes; did you mean static?
So it sounds like this sort of thing might show up someday.
Of course, the other side of the problem is finding a way to dynamically refer to the "current" type responsible for executing some statement. In the context of an instance method, you have self.dynamicType for such things... but there's no equivalent for classes. (Self is a type constraint, not an actual type.) This is a side effect of the type system in Swift being much more strict and static than that of Objective-C (for example, metatypes aren't just a special flavor of otherwise normal objects). File a bug if you'd like to see a change to that effect?

Swift Generics & Upcasting

I've got a quick question regarding generics in Swift. The problem is I'm trying to store a variable that takes a generic as a parameter, but am unable to cast it up to the type it is restricted by. It's best explained in a short example:
class Foo { }
class Thing<T: Foo> {
func produceBar() -> Bar {
return Bar(aThing: self as! Thing<Foo>)
}
}
class Bar {
var thing: Thing<Foo>
init(var aThing: Thing<Foo>) {
self.thing = aThing
}
}
The code above produces the error: "Cast from Thing<T> to unrelated type Thing<Foo> always fails"
Shouldn't it never fail, since T is restricted to being a subclass of Foo? I must be misunderstanding the way generics work in Swift, any guidance or help would be much appreciated!
Swift generics are not covariant. That is to say, exactly what the error says: you can't automatically say a Basket<Apple> is a kind of Basket<Fruit> even if Apple is a kind of Fruit. There is good reason for this.
Consider the following code:
class Fruit {}
class Apple: Fruit {}
class Orange: Fruit {}
class Basket<T: Fruit> {
private var items: [T]
func add(item: T) {
items.append(item)
}
init() {}
}
func addItem<T: Fruit>(var basket: Basket<T>, item: T) {
basket.add(item)
}
let basket:Basket<Apple> = Basket()
addItem(basket as Basket<Fruit>, Orange())
This would be legal code if Basket<Apple> were considered a Basket<Fruit>, and I'd be allowed to add an orange to a basket of apples.

Resources