Swift Complex type in parameter - swift

In order to be a bit more clear I am looking for a solution for the user to pass a class with a specific subclass and protocol, i.e. a class that inherits a viewController and delegate protocol. I know its possible to create a protocol list but cannot find a solution that works correctly. Currently I use a initializer and use the viewcontroller as a parameter and check for delegate inside the function but I would rather if I can have these types in the parameter instead.
EDIT:
Looking to do something similar to this
Protocol prot:Delegate{}
class cla:ViewController{}
class impl{
init(mainUI: cla, prot){
do things
}
}
That way back in the main view controller I can do something like this
class viewController: cla, prot{
var view:impl
override func loadView() {
//Attach to Screen
view = impl(mainUI: self);
}
}
Their is a bit more happening but that's the only part thats really relevant. Currently I use a initializer to just fail if the class doesn't inherit the correct protocols

You could create a dummy type that represents your requirements. A typealias doesn't work in this case, but this might:
class DummyClass: MyViewController, MyDelegateProtocol {}
func needsRequiredClass(input: DummyClass) {...}
With MyViewController and MyDelegateProtocol being the superclass and delegate you mentioned. The DummyClass would have an empty implementation.
Then, make your specific classes sub classes of DummyClass:
class TestClass: DummyClass {...}
And you can pass in that new class:
let test = TestClass()
self.needsRequiredClass(test)

You're asking the wrong question. In other words trying to shoe-horn in a serious design mistake.
A view should not know that its delegate is a UIViewController or a subclass.
A delegate should be any class that obeys (adopts) a specific delegate protocol.
A view should only delegate specific responsibilities. Each of those responsibilities must be described by a protocol method or property.
If you explain what your issue is in more detail (why you think you need direct access to the entire definition of a UIViewController within a UIView), we can help you avoid this mistake.

Related

Is there a way to know that method is protocol implementation in Swift?

For example, I have such a protocol
public protocol MyProtocol
{
func foo()
}
Protocol implementation
class MyClass : MyProtocol
{
public func foo() {...}
}
there is no way to know if the method foo() is a (direct) class method or protocol implementation
So, sometimes (eg:) if a certain class implements few protocols where each of them has few methods it is hard to know which method related to which protocol.
So the question is - is there actually no way to know it?
UPD
I need to know it just for a better understanding of the code and in addition, it is easier to navigate when I know which method related to which protocol.
When you are writing code, it is usually a good idea to write implementations of protocol methods in their own separate extensions. For example:
class MyClass {
// implement methods unrelated to any protocols here
}
extension MyClass : Protocol1 {
// implement the methods in Protocol1
}
extension MyClass : Protocol2 {
// implement the methods in Protocol2
}
// etc
This way you know exactly what methods belong to which protocol.
However, let's say you are reading someone else's code that you can't change.
In Xcode, you can see if a method in a class implements a protocol by holding the command key and then clicking on its name, then the "quick actions" menu comes up:
If you click on "Jump to definition",
you will be taken to the method declaration in the protocol, if the method implements a method declared in a protocol, or
you will stay where you are, if it's just a regular old method
Do note that you will also stay where you are, if the method implements a protocol method, but is overridden. So if you see an overridden method, and wants to know if it is a requirement for a protocol or not, you'll have to go to the superclass first.
Or, use AppCode, where there are markers beside these methods:
The "I" markers with a red upwards arrow are what you're looking for. Clicking on them takes you to the declaration in the protocol. For overridden methods, they look no different from regular overridden methods, and you still need to go to the superclass first by clicking on the "O" marker with a red upwards arrow.
The only downside of this is of course, you need to pay for AppCode :(

When and why would i use Protocols in Swift?

So I came across the subject of protocols and I have searched the internet a bunch for an answer but I couldn't find one, atleast one that solved my problem.
So I understand that Protocols are a "blueprint" of methods, properties and such and that it can be implemented in a class or struct and that it needs to conform to its requirements and such, but why would one use one?
I mean you could also just create a function inside a struct itself. It seems a bit of a hassle to write a protocol and then for the implementation of said protocol you would have to write all the requirements again with more code this time.
Is there a particular reason why one would use a protocol? Is it for safety of your code or some other reason?
For example:
In swift you have the CustomStringConvertible protocol which has a required computed property to control how custom types are represented as a printable String value, but you could also create a function inside your class which could solve this issue aswel. You could even have computed property which does the same as this protocol without even implementing this protocol.
So if someone could please shed some light onto this subject, that would be great.
Thank you in advance!
but why would one use one?
Protocols in swift are similar to Abstractions in some other languages.
before answering your question, we have to clear things out, Protocols declaration could be various but considering you have already read tons of it,
It will also be great to mention this answer here.
Now lets get into the real use case here.
Consider you have this protocol.
protocol Printable {
var name: String { get }
}
Now we need some type of structs or classes to confirm to it, or Multiple ones.
And here where it lays one of the biggest benefit of it.
Consider you have to print the name propriety of an objects.
For example those.
struct Human {
var name: String
}
struct Animal {
var name: String
}
You would simply type this without Protocols
func printOut(human: Human){
human.name
}
func printOut(animal: Animal){
animal.name
}
Which is correct, now observe the code below using protocol Printable.
struct Human: Printable {
var name: String
}
struct Animal: Printable {
var name: String
}
func printOut(object: Printable){
print(object.name)
}
It only takes us one func and so on using the Protocols.
Conclusion
Protocols used to minimize the unnecessary chunks of code.
It's name represent the effect applied on the confirm party.
Protocols can be injected as parameters types.
You can also read more about them here.
And more about the use cases here.
Protocol in swift is a pattern for allowing your classes to confirm to particular set of rules.
In other words a protocol is a blueprint of methods and properties that are necessary for a particular task.
You implement a protocol by confirming to it. If your class miss implementation of any method defined in the protocol, swift compiler tells you.
As an example lets consider that you want to make a Car class. Now there are particular requirements for a car. Like it has wheels, a trunk, etc. Each requirement can be defined as a protocol that is then implemented by the Car class. If your class don't have a trunk, you just drop the implementation.
Protocol oriented programming is a new programming paradigm. That solves some problems incurred by object oriented programming. Like multiple inheritance. Swift doesn't allow multiple inheritance but it allows confirmation to multiple protocols.
It's very easy to remove some functionality from a class in Protocol oriented programming. You just stop conforming to it. Comparative to OOP its very easy to do such things in POP.
The concept of the protocol is very simple: it's nothing more than a promise that specific methods and/or properties will exist in whatever object has taken on that protocol. And so we use them for typing and type safety.
Imagine creating a custom control, like an action sheet:
class CustomActionSheet: UIControl {
func userTappedOnSomething() {
// user tapped on something
}
}
...and you implemented it in one of your view controllers.
class SomeViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let actionSheet = CustomActionSheet()
}
}
This isn't much use without allowing the action sheet to communicate with the view controller when the user taps on a button. So we use a delegate:
class CustomActionSheet: UIControl {
weak var delegate: UIViewController?
func userTappedOnSomething() {
delegate?.userTookAction()
}
}
class SomeViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let actionSheet = CustomActionSheet()
actionSheet.delegate = self
}
func userTookAction() {
// update the UI
}
}
Now when the user taps on a button in the action sheet, the view controller underneath can update its UI. But this actually won't compile. You will get an error that UIViewController has no member userTookAction. That is because the UIViewController class doesn't have a method called userTookAction, only this instance of the view controller does. So we use a protocol:
protocol ActionSheetProtocol: AnyObject {
func userTookAction()
}
This protocol says that whatever object that conforms to it must include this method. So we change the action sheet's delegate to be of that protocol type and we conform the view controller to that protocol since it has such method:
class CustomActionSheet: UIControl {
weak var delegate: ActionSheetProtocol?
func userTappedOnSomething() {
delegate?.userTookAction()
}
}
class SomeViewController: UIViewController, ActionSheetProtocol {
override func viewDidLoad() {
super.viewDidLoad()
let actionSheet = CustomActionSheet()
actionSheet.delegate = self
}
func userTookAction() {
// update the UI
}
}
This is a classic example of protocol use in Swift and once you understand it, you will learn how to get crafty with protocols and use them in very clever ways. But no matter how you use them, the concept remains: promises that things will exist.
Note: In this example, I named the protocol ActionSheetProtocol, because to someone learning protocols, it makes the most sense. However, in the Swift world, in today's practice, most programmers (including the guys at Apple) would name it ActionSheetDelegate. This can be confusing for someone learning protocols so in this example I tried to make it as clear as possible. I personally don't like naming protocols delegates but there’s a lot of things I don’t like.
Note 2: I also made the protocol of type AnyObject which is Swift's syntax for making the protocol a class protocol. Not all protocols need to be of type AnyObject.

There is a code involves the Delegate Up, I hope I understand it right

Delegation is a new concept for me. To my understanding, it asks someone else to do some job for me. I then, delegate some tasks to him.
class Vehicle {
var numberOfWheels = 0
var description: String {
return "\(numberOfWheels) wheel(s)"
}
}
class Bicycle: Vehicle {
override init() {
super.init() //# Delegate up
numberOfWheels = 2
}
}
The code super.init() is a delegate up action in class initialization. The subclass initializer calls the initializer of the superclass first. The superclass' default initializer assigning the integer 0 to the variable numberOfWheels. This is Phase one initialization. After that, the overriding action of the subclass' initializer further customizes the variable by numberOfWheels = 2.
Question Is there any incorrectness of my understanding? and I hope the delegate up description I'm used here is correct.
Please correct any error and misunderstandings I have it here. Thanks
What you are depicting here has nothing to do with delegation-pattern at all, it's the concept of inheritance. Your bicycle class is inheriting from Vehicle. Vehicle has already implemented some code, so instead of writing it again you can use the code of the super-class (the class that is inherited from). Your super-class doesn't have a defined initializer, therefore the super.init() wont even do anything. You should read about inheritance and try to understand this concept better.
Here's what delegation does: You are right about the idea of delegation. It allows you to "outsource" some work to another class. This can be achieved with protocols. A delegate has to conform a delegation protocol to ensure that it has the methods you want to call on it. You are using protocols instead of inherited classes here, because you don't care about the implementation of the specific methods, you just want to tell your delegate to handle a situation, it's up to the delegate to know what to do.
Delegation is most commonly used in MVC applications for macOS and iOS. You can read more about delegation in the Apple Documentation. There are also dozens of tutorials like this one on the internet that show how delegation works in practice.

Understanding Swift extension usage in your API design [duplicate]

This question already has an answer here:
Extensions in my own custom class
(1 answer)
Closed 6 years ago.
The Alamofire API has extensions such as extension Request in ResponseSerialization.swift. When designing a Swift API why would you take this approach as opposed to just adding these methods to the Request class (Request.swift)?
I understand the use of extensions to extend API's when you don't control the source. This question is about using them to extend your own API.
For cleanliness or adding functionality to other classes you didn't create (i.e. extension UIColor). You can create separate extensions to add in separate bits of functionality.
For example, if you have a UIViewController and you add a table view to it's view, instead of making the declaration of ViewController look like this:
class ViewController : UIViewController, UITableViewDataSource, UITableViewDelegate
you could separate it all with extensions so you don't clutter your ViewController file.
Like so:
extension ViewController : UITableViewDataSource, UITableViewDelegate
which you could separate from the main body of the ViewController class or extract into a new file.
Extensions are one of the best features of Swift programming language and there are several use cases for them. Once you hold a grip of them you can come up with some really good and understandable code. Some of the use cases are:
1. Extending system types
With Swift you can any system type like Int or String to make some code more readable and to get some more functionality you would otherwise have to write on your own. For example, check out following code that repeats some task a number of times:
extension Int {
func repetitions(task: () -> Void) {
for _ in 0..<self {
task()
}
}
}
Instead of creating separate function for task repetition and managing several parameters you can just extend Int and make it more readable:
3.repetitions({
print("Hello!")
})
// Hello!
// Hello!
// Hello!
Everybody can agree that this is the simplest and cleanest code you can ever create.
2. Make messy code readable
Check the following definition:
class MyTableViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, CLLocationManagerDelegate {
// a lot of functions
}
If you put everything inside one class or structure, code will get messy at one point and it'll be hard to track which method belongs to which protocol or class. Instead you should be using this:
class MyTableViewController: UIViewController {
}
extension MyTableViewController: UITableViewDelegate {
}
extension MyTableViewController: UITableViewDataSource {
}
// etc...
3. Protocol extensions
Protocol extension are one of the coolest features of Swift. They enable adding methods to any class that adopts the protocol you are extending. For example let's extend CollectionType protocol.
extension CollectionType {
func printAll() {
print(self)
}
}
Now you can use method printAll() on any structure that adopt this protocol! Some of them are native Swift types like Array, Dictionary or Set.
These are just some of the main usages of extensions and they can do a lot more:
Add computed instance properties and computed type properties
Define instance methods and type methods
Provide new initializers
Define subscripts
Define and use new nested types
Make an existing type conform to a protocol

Using extensions for protocol conformance when superclass also conforms

In Swift, a general best practice has come about to place protocol conformance for a class into a separate extension. This helps separate out code into logical sections:
class SuperClass: UIViewController {
...
}
extension SuperClass: UITableViewDelegate {
...
}
However, in an app I am currently working on, a base superclass and subclass both need to provide methods for UITableViewDelegate.
To logically separate the code, one would think to do:
class Subclass: SuperClass {
...
}
extension Subclass: UITableViewDelegate {
...
}
However, Swift complains that the class already conforms to the protocol. At the moment, I have simply removed the : UITableViewDelegate part of the extension.
This seems to be a bit of a caveat of using this best practice. Are there any better ways of organising code in this case?