9

Looking for a way to use Swift extensions in a separate file or an alternative solution. Creating an extension only works as long as the extension is written in the same file it is being used.

Here is an example of the ViewController.swift that works.

import UIKit
var TestHelper: String = "Start Value"
extension UIView {
var testValue:String{
set{
    TestHelper = newValue
}
get{
    return  TestHelper
}
}
}

class ViewController: UIViewController {
override func viewDidLoad() {
    super.viewDidLoad()
    self.view.testValue = "Some Value"
}
override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
}
}

Taking the extension out of this file and placing in a new file results in a crash giving this error:

Program ended with exit code: 9

This error is saying it doesn't exist I think. Creating the extension in each separate file that the extension is need obviously creates issues with invalid redeclaration.

Thanks in advance!

jrturton
  • 118,105
  • 32
  • 252
  • 268
user3724387
  • 91
  • 1
  • 1
  • 2
  • 1
    When I try this the compiler crashes. You may want to [file a bug](http://bugreport.apple.com). – jtbandes Jun 10 '14 at 05:27
  • I feel very uncertain about the property inside the extension. Don't have the situation as in http://stackoverflow.com/a/24115223/1726069 ? – Jens Wirth Jun 10 '14 at 11:32

4 Answers4

3

If you move the extension to another file then you have to move TestHelper, too. Or simplier: put TestHelper into the extension

  • 1
    I should have clarified I have placed the extension helper in the extension file. Does not seem to matter. If I am not mistaken testHelper placed in the extension would need the use of getter/setter and cause the same problem it solved by placing it outside? – user3724387 Jun 10 '14 at 06:01
3

I also encountered the same error and trying to solve it I found that adding static in front of the extension variable declaration seems to do the trick:

import UIKit

static var TestHelper: String = "Start Value"

extension UIView {

    static var testValue: String {
        set {
            TestHelper = newValue
        }
        get{
            return  TestHelper
        }
    }

}

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.testValue = "Some Value"
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

}

Hope it helps!

Roger Fernandez Guri
  • 970
  • 2
  • 10
  • 18
2

I tried out the problem thinking it would be easy, but it seems to more complex than I would have initially thought.

I ended up having to subclass UIView. I couldn't create an extension for UIView that added a var. I think maybe they are forcing us to subclass UIView, because of how the init or the get/set works for the class. I just made this. It's not the same but it has equivalent functionality

import UIKit

class MyView: UIView {
    var testValue: String?
    init(frame: CGRect) {
        super.init(frame: frame)
        self.backgroundColor = UIColor.greenColor()
        self.bringSubviewToFront(self.superview)
    }
}

and then used it as such

override func viewDidLoad() {
    super.viewDidLoad()

    let myRect = self.myContent.frame
    let myNewView: MyView = MyView(frame: myRect)
    myNewView.testValue = "has been set"
    self.myView.addSubview(myNewView)

    NSLog("%@", myNewView.testValue!)

}

I can extend Array with a var

extension Array {
    var last: T? {
    if self.isEmpty {
        NSLog("array crash error - please fix")
        return self [0]
    }
    else {
        return self[self.endIndex - 1]
        }
    }
}

It is easy to create an extension for UIKit if you only add functions and not a variable

extension UIView {
    func layerborders() {
        let layer = self.layer
        let frame = self.frame
        let myColor = self.backgroundColor
        layer.borderColor = UIColor.whiteColor().CGColor
        layer.borderWidth = 0.8
        layer.cornerRadius = frame.width / MyConstants.CornerRadius.toRaw()
    }
}
MGM
  • 2,379
  • 1
  • 19
  • 13
  • 1
    Thanks for the taking the time to check into this problem. I like the solution however it probably wont be something I use as a solution sadly. I feel as tho using this to style a tab bar or navigation bar is going to lead to layering issues and overlaying buttons ect. – user3724387 Jun 10 '14 at 17:27
2

"Extensions cannot add stored properties" (from "The Swift Programming Language")

Goodsquirrel
  • 1,476
  • 1
  • 15
  • 29