Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

File Scope? Swift Delegates and Protocols

I'm working on building a new Swift app roughly based off an old Obj-c app. I'm currently working on the delegates

Here is what my obj-c code looked like in the .h file

@interface MyAppViewController : CustomViewController
@property (nonatomic, weak) id<MyAppViewControllerDelegate> delegate;
@end

@protocol MyAppViewControllerDelegate <NSObject>
- (void)myAppViewController:(MyAppViewController *)controller loggedInStudent:    (MYStudent *)student;
- (void)myAppViewControllerWantsSignUp:(MyAppViewController *)controller;
@end

In SWIFT I did:

class MyAppViewController: CustomViewController {

var delegate: MyAppViewControllerDelegate?
protocol MyAppViewControllerDelegate{
func myAppViewController(controller: MyAppViewController, loggedInStudent:     MYStudent)
func myAppViewControllerWantsSignUp(controller: MyAppViewController)

I've done a lot of reading and study on this, so I thought I was doing it basically right (totally new to swift though... so)

I'm getting this error though, "Declaration is only valid in file scope" on the protocol MyAppViewControllerDelegate { I assumed this had something to do with declaring it within the class, so I moved it out, only now my code within the class doesn't recognize the delegate variable I declared..

Any ideas?

like image 753
YichenBman Avatar asked Oct 14 '14 18:10

YichenBman


People also ask

What is difference between protocol and delegate in Swift?

Protocol is a set of methods (either optional or required) that would be implemented by the class which conforms to that protocol. While, delegate is the reference to that class which conforms to that protocol and will adhere to implement methods defined in protocol.

What are delegates in Swift?

In Swift, a delegate is a controller object with a defined interface that can be used to control or modify the behavior of another object.

What is difference between delegate and datasource in iOS?

A data source is almost identical to a delegate. The difference is in the relationship with the delegating object. Instead of being delegated control of the user interface, a data source is delegated control of data.

Can delegation be implemented without a protocol?

You don't have to use protocols...but you should if you want to keep things flexible. Delegation is in essence asking someone else to do something for you. If you enforce a contract, then its more likely they will do it for you.


2 Answers

Should be this:

protocol MyAppViewControllerDelegate {
    func myAppViewController(controller: MyAppViewController, loggedInStudent:     MYStudent)
    func myAppViewControllerWantsSignUp(controller: MyAppViewController)
}

class MyAppViewController: CustomViewController {

    var delegate: MyAppViewControllerDelegate?
}

Although, if you're following a common pattern where the object that owns MyAppViewController is also its delegate, this may cause memory issues. You can use class typing to allow weak delegation like so:

protocol MyAppViewControllerDelegate : class {
    func myAppViewController(controller: MyAppViewController, loggedInStudent:     MYStudent)
    func myAppViewControllerWantsSignUp(controller: MyAppViewController)
}

class MyAppViewController: CustomViewController {

    weak var delegate: MyAppViewControllerDelegate?
}

This is slightly limiting because it requires you to use a class for your delegate, but it will help avoid retain cycles :)

like image 118
Logan Avatar answered Sep 19 '22 02:09

Logan


From what I see in your source code is that you've declared your protocol inside of your class. Just declare the protocol outside of the class declaration and you'll be fine.

Update:

The default access level is set to internal which is defined as

Internal access enables entities to be used within any source file from their defining module, >but not in any source file outside of that module. You typically use internal access when >defining an app’s or a framework’s internal structure.

In contrast to Objective-C or C you don't need a forward declaration if the implementation haven't happened before the usage.

Source: The Swift Programming Language, Access Control

like image 23
marcusficner Avatar answered Sep 22 '22 02:09

marcusficner