Home » Swift » Using extensions in separate .swift file

Using extensions in separate .swift file

Posted by: admin January 9, 2018 Leave a comment

Questions:

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!

Answers:

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

Questions:
Answers:

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()
    }
}

Questions:
Answers:

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!

Questions:
Answers:

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