Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using extensions in separate .swift file

Tags:

xcode

ios

swift

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!

like image 364
user3724387 Avatar asked Jun 10 '14 05:06

user3724387


4 Answers

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

like image 93
user3724687 Avatar answered Oct 06 '22 03:10

user3724687


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()
    }
}
like image 33
MGM Avatar answered Oct 06 '22 02:10

MGM


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!

like image 38
Roger Fernandez Guri Avatar answered Oct 06 '22 02:10

Roger Fernandez Guri


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

like image 21
Goodsquirrel Avatar answered Oct 06 '22 03:10

Goodsquirrel