import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
func declareName() {
print("hello")
}
declareName() //I get an error here saying :
}
Expected '{' in body of function declaration
I was working on something complex and it wasn't working. So i tried the very basics and I got this error. Any fixes?
All executable code must live in a function body. Therefore, in answer to your comment, yes, this code is illegal:
func add (a: Int) { print(a) }
add(5)
You would have to say:
func add (a: Int) { print(a) }
func callAdd() { add(5) }
Related
I have two presenters: FirstPresenter and SecondPresenter. FirstPresenter conform to protocol PresenterProtocol. SecondPresenter needs to use all functions from FirstPresenter but with two additional.
protocol PresenterProtocol: class {
func one()
func two()
func third()
}
class FirstPresenter: PresenterProtocol {
func one() {
// do something
}
func two() {
// do something
}
func third() {
// do something
}
}
And then I have SecondPresenter and I need to use exactly the same implementation from FirstPresenter (but I want to avoid inheritance, I want do it with protocols)
class SecondPresenter: PresenterProtocols {
var firstPresenter: PresenterProtocol = FirstPresenter()
func one() {
firstPresenter.one()
// do something
}
func two() {
firstPresenter.two()
// do something
}
func third() {
firstPresenter.third()
// do something
}
func additionalFunction() {
// do something more
}
}
I am not sure if calling firstpresenter function is a good way to solve this problem, because it's just rewriting. I wonder also to use default implementation. What's the best way to share functionalities?
Your code doesn't actually rely on the methods you define, so they don't need to be requirements. They're extensions. As written, your code would be:
// This is where *requirements* go. Not shared code.
protocol PresenterProtocol: class {}
// This is your shared code
extension PresenterProtocol {
func one() {
// do something
}
func two() {
// do something
}
func third() {
// do something
}
}
// And FirstPresenter needs nothing else
class FirstPresenter: PresenterProtocol {}
// SecondPresenter gets those, and also has other things
class SecondPresenter: PresenterProtocols {
func additionalFunction() {
// do something more
}
}
Now, I'm betting that one() actually has some requirements. It needs its implementers to provide something. Those are what go in your PresenterProtocol. For example:
extension PresenterProtocol {
func one() {
doFirstThing() // Something the implementer must do
doSecondThing() // Something the implementer must do
}
}
In that case, you'd add those as requirements:
protocol PresenterProtocol {
func doFirstThing()
func doSecondThing()
}
And if there were a default way to do it that some implementers might override, then you'd provide a default implementation. Or you can just have all implementers provide it directly. Or you might not have any requirements at all.
Having a parent class is the better implementation as far as I see. But, if you don't want to, swift protocols have a nifty trick: the protocols can be extended.
Let me demonstrate using your code,
protocol PresenterProtocol: class {
func one()
func two()
func third()
}
// Adding the extenstion/default implementation
extension PresenterProtocol {
func one() {
print("one was pressed")
}
func two() {
print("two was pressed")
}
func third() {
print("third was pressed")
}
}
This way, any class conforming to PresenterProtocol will use the so-called "default implementation" (which is another way to say protocol extensions) unless you override the method in the class.
So your usage will look something like the following where you don't need to implement the 3 methods all over again.
class SecondPresenter: PresenterProtocol {
// Calling default implementations
func someFunction() {
one()
two()
third()
}
}
.
.
.
class FirstPresenter: PresenterProtocol {
func someFunction() {
one()
two()
third()
}
}
If you want more help learning, I would highly suggest reading the HackingWithSwift Tutorial
overriding method signatures in extensions seems to produce unpredictable results in certain cases. The following example demonstrates two different results with a similar pattern.
class A: UIViewController {
func doThing() {
print("dothing super class")
}
override func viewDidLoad() {
print("viewdidload superclass")
super.viewDidLoad()
}
}
class B: A { }
extension B {
override func doThing() {
print("dothing sub class")
super.doThing()
}
override func viewDidLoad() {
print("viewdidload subclass")
super.viewDidLoad()
}
}
let a: A = B()
a.doThing()
let vc: UIViewController = B()
vc.viewDidLoad()
This prints :
dothing super class
viewdidload subclass
viewdidload superclass
You can see this skips the B's implementation of doThing when it is cast as A, however includes both implementations of viewDidLoad when cast as UIViewController. Is this the expected behavior? If so, what is the reason for this?
ENV: Xcode 7.3, Playground
The surprise here is that the compiler permits the override in the extension. This doesn't compile:
class A {
func doThing() {
print("dothing super class")
}
}
class B: A {
}
extension B {
override func doThing() { // error: declarations in extensions cannot override yet
print("dothing sub class")
super.doThing()
}
}
In your example, it appears that the compiler gives you a pass because A derives from NSObject — presumably in order to allow this class to interact with Objective-C. This does compile:
class A : NSObject {
func doThing() {
print("dothing super class")
}
}
class B: A {
}
extension B {
override func doThing() {
print("dothing sub class")
super.doThing()
}
}
My guess is that the fact you're allowed to do this override at all is itself possibly a bug. The docs say:
Extensions can add new functionality to a type, but they cannot override existing functionality.
And overriding is nowhere listed as one of the things an extension can do. So it seems like this should not compile. However, perhaps this is permitted deliberately for compatibility with Objective-C, as I said before. Either way, we are then exploring an edge case, and you have very nicely elicited its edginess.
In particular, the preceding code still doesn't cause dynamic dispatch to become operational. That's why you either have to declare doThing as dynamic, as suggested by #jtbandes, or put it in the actual class rather than the extension — if you want polymorphism to operate. Thus, this works the way you expect:
class A : NSObject {
dynamic func doThing() {
print("dothing super class")
}
}
class B: A {
}
extension B {
override func doThing() {
print("dothing sub class")
super.doThing()
}
}
And so does this:
class A : NSObject {
func doThing() {
print("dothing super class")
}
}
class B: A {
override func doThing() {
print("dothing sub class")
super.doThing()
}
}
My conclusion would be: Very nice example; submit it to Apple as a possible bug; and Don't Do That. Do your overriding in the class, not in the extension.
While playing around in playground with protocol extension I came to strange error. More precisely I declared a protocol and used it as type in the following manner :
protocol InvokeProtocol{
func invokeA()
func invokeB()
}
class Controller{
var invoker : InvokeProtocol?
func methodA(){
invoker?.invokeA()
}
func methodB(){
invoker?.invokeB()
}
}
What I did next was creating a subclass of Controller and tried to extend the InvokeProtocol for that particular type
extension InvokeProtocol where Self: SpecificController{
func invokeC(){
}
}
class SpecificController : Controller {
override func methodA() {
super.methodA()
}
override func methodB() {
super.methodB()
}
func methodC(){
invoker?.invokeC()
}
}
But this give me the following compile time error while I try to call invokeC on SpecificController
#opened("70A8B09C-65E3-11E5-9A8E-6C40088AF546") InvokeProtocol' is not a subtype of 'SpecificController'
I just jumped to Swift 2.0 and this is my first time I see errors starting with #opened. What does this mean? Is this a known bug waiting to be fixed? If so do you guys have any workaround about this?
To reply to your comment. It is achievable. You just haven't implemented the protocol in the first place. The following will work:
protocol InvokeProtocol {
func invokeA()
func invokeB()
}
class Controller : InvokeProtocol {
func invokeA(){
}
func invokeB() {
}
}
extension InvokeProtocol where Self: SpecificController{
func invokeC() {
}
}
class SpecificController : Controller {
override func invokeA() {
super.invokeA()
}
override func invokeB() {
super.invokeB()
}
func invokeC() {
}
}
I guess the where Self: SpecificController, the Self means var invoke: InvokeProtocol?
if invoke conform the protocol and invoke is SpecificController, that invoke can call the method named invokeC()
I don't understand what's wrong with this code in my View Controller, the very bottom line (with the single } bracket) keeps getting two errors, one that states "Consecutive declarations on a line must be separated by ';'" and "expected declaration". When I add the semicolon where it directs me to it still says an expected declaration error....but for what? Can anyone find anything wrong with it?
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
var testObject = PFObject(className:"TestObject")
testObject["foo"] = "bar"
testObject.saveInBackgroundWithTarget(nil, selector: nil)
var voteCount = PFObject(className:"VoteCount")
voteCount["votes"] = 0
voteCount["optionName"] = "Crepes"
voteCount.incrementKey("votes")
voteCount.saveEventually()
var query = PFQuery(className:"VoteCount")
query.getObjectInBackgroundWithId("e8KhneiSfw") {
(voteCount: PFObject!, error: NSError!) -> Void in
if error != nil {
NSLog("%#", error)
} else {
voteCount["votes"] = 1
voteCount.incrementKey("votes")
voteCount.saveEventually()
}
}
class Counter {
var voteCount: Int = 0
func incrementBy(amount: Int, numberOfTimes times: Int) { voteCount += amount * times
}
}
func didReceiveMemoryWarning() {
didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
There's a missing closing brace before this line:
class Counter {
Your viewDidLoad() method is not properly closed, so what happens is that the class and didReceiveMemoryWarning are defined as local to viewDidLoad.
A proper indentation usually reveals errors like that... are you properly indenting your code?
As written, class Counter and func didReceiveMemoryWarning() are inside viewDidLoad. Fix your braces.
I am trying to grasp the concept of delegates and protocols in swift. So I have implemented my own PlayableMedia protocol with two concrete classes BlueRayMedia and DVDMedia like so:
#protocol PlayableMedia {
func play()
func stop()
}
class BlueRayMedia:PlayableMedia {
func play() {
println("BlueRayMedia is playing")
}
func stop() {
println("BlueRayMedia has stopped playing")
}
}
class DVDMedia:PlayableMedia {
func play() {
println("DVD is playing")
}
func stop() {
println("DVD has stopped playing")
}
}
So now I have a DVDPlayer class that uses this setup:
class DVDPlayer {
var media:PlayableMedia // delegate property
init(media:PlayableMedia){
self.media = media
}
func didStartPlaying() {
media.play()
}
func didStopPlaying() {
media.stop()
}
}
But when I try to use it like this:
var dvdPlayer:DVDPlayer = DVDPlayer(media: BlueRayMedia())
dvdPlayer.didStartPlaying()
I get (no results) in my playground console. What am I doing wrong?
Ok so the simple mistake I made was use #protocol instead of just protocol
So this works:
protocol PlayableMedia {
func play()
func stop()
}
Inside the Playground println() doesn't work.
Add some other expression like let x = 5