Is putting your class inside a struct an acceptable way to namespace your class in Swift? - swift

Is putting your class inside a struct an acceptable way to namespace your class in Swift? I did not see any mention of nested struct or struct-class in the programming guide.
struct TestNamespace {
class Test {
}
}

I'd be (even more) happy with namespaces in Swift, because they help organize the code more granularly. If you're experimenting with using struct as a namespace, consider disabling its construction:
struct PseudoNamespace {
private init() {}
//...
}
Using struct has an advantage over using class: structs does not support inheritance and with classes it needs using final modifier.
One significant disadvantage of this emulation is that there is no way no "import" such a namespace (like import PseudoNamespace.*, etc.), because Swift allows importing modules, but not structs.

Related

Namespaces between Swift Packages

I am using two swift packages with SPM. But it appears both are defining a struct with the same name. It compiles, though it seems one struct overrides the other. How can I choose which of the structs I want to use? Is there some namespace for each package?
Thank you..
Let say you have package ‘A’ and ‘B’ and the struct name is ‘SomeModel’
You can simply
import A
import B
let modelA = A.SomeModel(…)
let modelB = B.SomeModel(…)
This is the default behavior/namespacing for different modules/packages in Swift. Though there might be an additional encapsulating/name-spacing within the package. Something like
class SomeClass {
struct SomeModel{}
}
Then you can access it with the additional encapsulation

Swift reflection of static members

Is there a way to use Mirror to enumerate the static members of a class?
A good example of this is the UnitLength class that has class variables like #NSCopying class var meters: UnitLength { get }
The UnitLength class acts much like an Objective C sort of enumeration (in that all of the UnitLength units are class vars on the UnitLength class).
I was hoping to use reflection (Mirror) to grab each of the units at runtime to build the list (manually putting them in my code is hardly “DRY”).
From some experimentation with the Mirror capabilities, I’ve not been able to find these class vars. Is there some trick I’m missing?

How can a Swift module/class work around the lack of language support for "protected" members?

I'm faced with a situation where I am defining a reusable base class in a module, and I want to provide certain functions that should be callable only by subclasses, not external users of that subclass.
I'm writing a framework and packaging it as a Swift module. Part of my framework includes a base class that can be subclassed to add functionality, but whereby the derived class also has a further external purpose as well. Imagine defining a new kind of view: it derives from UIView or NSView, then provides additional logic, and is then itself instantiated by another party.
In this case, I'm the one defining the UIView-like class that is intended to be subclassed, and along with it comes a lot of private UIView internal stuff, like measurement, arranging, who knows, internal stuff.
The point is, end users of this new view class don't want to see the internals of the architecture that supported the subclassing, those should be completely inside the black box of what the subclass represents.
And it strikes me that this is now impossible in Swift.
I really don't understand why Swift got rid of protected access control. According to Apple, the function that I want to expose only to subclasses "isn't really useful outside the subclass, so protection isn’t critical".
Am I missing something? Is this a whole class of design patterns that Swift simply cannot support?
One thought that occurs to me is I could perhaps split up the public-public and the private-public parts of my class into two parts, perhaps using protocols, whereby public-public users would only see the public protocol and "private" public users would see the "private" protocol as well. Alas this seems like a lot of engineering for something that used to be free.
FWIW — I've been continually asking for better access control in Swift (including protected) since before there was access control in Swift. Now, 3.5 years after we were told to give the Swift approach to access control a try, Swift has been my primary language for almost 3 of those years and I still think the access control paradigm is clumsy and unable to model concepts that are easy in almost all similar languages.
The largest mitigating factor for me is that Swift has steered me away from ever using inheritance and subclassing 95% of the time, which I think is a good thing. So this issue comes up less than it may have otherwise. But for situations exactly as you are describing, there isn't an equivalent way to accomplish what you are doing using only protocols and protocol extensions, so you are stuck either polluting a public API with possibly harmful internal details, or using some workaround (like the one that follows) which has the smallest possible public API exposure, and simulates what you want at the cost of boilerplate and awkwardness.
That said, the approach I take is somewhat inspired by Objective C, where there is also no real protected access control, but the convention is to declare a public API header (which client code will import and reference) and a special "+Subclassing" header which only subclasses will import in their implementation, giving them visibility into the not-for-public-consumption internals.
In Swift, this isn't directly possible either, but given a class like this:
open class SomeClass {
private var foo: String
private var bar: Data
public init(){
foo = "foo"
bar = Data()
}
private func doInternalThing() {
print(foo)
}
}
You can add a nested "Protected" wrapper via extension (has to be in the same file as your class declaration), which takes an instance of the class (or a subclass) and exposes the protected-level internals as a sort of proxy:
// Create a nested "Protected" type, which can accept an instance of SomeClass (or one of its subclasses) and expose the internal / protected members on it
public extension SomeClass {
public class Protected {
unowned private var someClass: SomeClass
public var foo: String {
get {
return someClass.foo
}
set {
someClass.foo = newValue
}
}
public init(_ someClass: SomeClass) {
self.someClass = someClass
}
public func doInternalThing() {
someClass.doInternalThing()
}
}
}
Outside of the framework, in the client application, the protected members are accessed in a subclass like this:
class SomeSubclass: SomeClass {
private lazy var protected: SomeClass.Protected = { SomeClass.Protected(self) }()
func doSomething() {
protected.foo = "newFoo" // Accesses the protected property foo and sets a new value "newFoo"
protected.doInternalThing() // Prints "newFoo" by calling the protected method doInternalThing which prints the foo property.
}
}
There are pros and cons for this approach. The cons are mainly the amount of boilerplate you need to write to map all your properties and functions from the Protected wrapper to the actual class instance as shown above. Also, there is no avoiding the fact that consumers will see SomeClass.Protected as a publicly visible type, but hopefully it's clear that it shouldn't be used and it's difficult enough to use it arbitrarily that it won't happen.
The pros are that there isn't a lot of boilerplate or pain for clients when creating subclasses, and its easy to declare a lazy "protected" var to get the desired API. It's pretty unlikely that non-subclass would stumble upon or use this API accidentally or unwittingly, and it's mostly hidden as desired. Instances of SomeSubclass will not show any extra protected API in code completion or to outside code at all.
I encourage anyone else who thinks access control — or really in this case, API visibility and organization — to be easier than it is in Swift today to let the Swift team know via the Swift forums, Twitter, or bugs.swift.org.
You can kinda, sorta work around it by separating out the for-subclasses stuff into a separate protocol, like this:
class Widget {
protocol SubclassStuff {
func foo()
func bar()
func baz()
}
func makeSubclassStuff() -> SubclassStuff {
// provide some kind of defaults, or throw a fatalError if this is
// an abstract superclass
}
private lazy var subclassStuff: SubclassStuff = {
return self.makeSubclassStuff()
}()
}
Then you can at least group the stuff that's not to be called in one place, to avoid it polluting the public interface any more than absolutely necessary and getting called by accident.
You can also reconsider whether you really need the subclass pattern here, and consider using a protocol instead. Unfortunately, since protocols can't nest types yet, this involves giving the subclass-specific protocol an Objective-C-style prefixed name:
protocol WidgetConcreteTypeStuff {
...
}
protocol Widget {
var concreteTypeStuff: WidgetConcreteTypeStuff { get }
}

How to visualize Protocols and Extensions in UML?

It seems reasonable to use UML Interfaces to visualize Swift Protocols in UML. But how should I visualize an extension that provides a default implementation for a specific protocol? Should I just use a class like <<extension>>ProtocolName that inherits from that protocol?
An extension exists in the scope of a certain class and just adds some functionality to it. So I would represent the extension as subclass (eventually packaging might be preferred). To show that it's an extension I would use a stereotype. The dependency on the class which is extended is somewhat optional since in the context it is a naming convention.
If the extension will additionally adhere to some protocol you just add realization relations to the according interface classes.
This is one way to express this. Since there is no native UML construct for an extension you are relatively free to invent you own idiom here.
In short
A Swift protocol is in principle an UML interface: a class does not inherit anything from an interface/protocol, but must implement the feature that the interface/protocol promises.
Protocol extensions change this semantic equivalence: a protocol extension can provide features that the conformant classes would inherit. This is incompatible with an UML interface and corresponds to the semantic of an abstract class. But using abstract classes would make it confusing in regard to multiple inheritance. A stereotype «protocol» would seem preferable.
More explanations
Protocols
A swift protocol that is not extended corresponds indeed to an UML interface, despite slight differences in the wording:
Swift: A protocol defines a blueprint of methods, properties, and other requirements that suit a particular task or piece of functionality. The protocol can then be adopted by a class, structure, or enumeration to provide an actual implementation of those requirements.
vs:
UML: An Interface is a kind of Classifier that represents a declaration of a set of public Features and obligations that together constitute a coherent service. An Interface specifies a contract; any instance of a Classifier that realizes the Interface shall fulfill that contract.
Class extensions
There are different kind of extensions. A class extension adds features to the classes that they extend. If the extension occurs in the same file, it even has access to the private members of the class.
class MyClass {
func hello()->Void { print ("Hello, World !"); }
}
var c = MyClass()
extension MyClass { // first extension
func hellobye() -> Void { hello(); print(" Good bye!"); }
}
extension MyClass { // second extension
func bye() -> Void { print("Au revoir!"); }
}
c.hello() // the object has all the features of class + extension
c.hellobye() // even if it was defined befor the extension
c.bye()
The extension does not have a distinct name: it just redefines the original type, and the class behaves as if the initial definition and extensions would be the same classifier, just split up in the source code:
If the extensions and the initial class are defined in the same package, the cleanest way to represent it in UML would be to enrich the initial class, in the UML diagram.
If the extensions are defined in another package you could represent the full set of extensions to the same class as an own class, and a merge package to combine both. Since the original class is required for the extension to work you could in addition show a dependency between the two. Alternatively you could also think of an «class extension» stereotype. But again, grouping all the extensions to the same class in the package, because of the UML unique naming constraint.
Protocol extensions
Protocol extensions change the nature of the underlying protocol. While the original protocol was an interface without any implementation, the extended protocol will provide some implementations:
protocol MyProto {
var v1:String { get }
func op1() -> Void
func op2() -> Void
}
class Test : MyProto {
var v1:String = "abc"
func op1() -> Void { print("Op 1"); }
func op2() -> Void { print("Op 2"); }
}
extension MyProto {
var dev1:String { get { return "de"+v1; }}
func combo() -> Void { op1(); op2(); print("Combo 1 and 2"); }
}
var test = Test()
test.combo()
print (test.dev1);
In UML, the extended protocol would correspond to an «abstract» class, i.e a class that cannot be directly instantiated because of some missing features, but which may have some features well defined that are inherited. This situation is not fully supported in UML, since there is no modelling way to transform an interface into an abstract class:
The cleanest way would then be to use an UML profile that defines the stereotype «protocol» as a special form of «abstract» classes. The protocol extensions would then be dealt with as explained above for the classes, using a «protocol extension» in the situation where a «class extension» was mentioned.

Extensions in my own custom class

I was reading through another SO question, Swift do-try-catch syntax. In his answer, rickster creates an extension for the OP's custom class. Konrad77 comments that it's a "Really nice way to keep your code clean." I respect their knowledge which leads me to believe I'm missing the point somewhere in my own code.
Are there any other benefits (aside from cleanliness) or reasons to create an extension for a class I created? I can just put the same functionality directly into the class. And does the answer change if I am the only one using the class or if someone else will be accessing it?
In the case of a class that you create from scratch extensions are a powerful type of documentation through structure. You put the core of your class in the initial definition and then add on extensions to provide additional features. For example, adding adherence to a protocol. It provides locality to the contained code:
struct Foo {
let age: Int
}
extension Foo: CustomStringConvertible {
var description:String { return "age: \(age)" }
}
Could I have put the protocol and computed property in the struct declaration? Absolutely but when you have more than one or two properties it starts to get messy and difficult to read. It's easier to create bugs if the code isn't clean and readable. Using extensions is a great way to stave off the difficulties that come with complexity.