javienegas
javienegas

Reputation: 658

Import Extension file in Swift

I create an extension for UIView in Swift. Anyone knows how to import that file to my UIViewController?

I want to import the extension file in the controller file, in that way I can reuse the extension file. For example an structure like this:

UIViewExtension.swift

import UIKit

extension UIView {
    var myVar : Float {
        get {
            return myVar
        }
        set (newMyVar) {
            myVar = newMyVar
        }
    }
}

ViewController.swift

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        var squareView: UIView = UIView(frame: CGRect(x: 0, y: 0, width: 200, height: 200))

        squareView.myVar = 50

        self.view.addSubview(squareView)
        println("Offset: \(squareView.myVar)")
    }
}

This is the error given by the compiler:

Command /Applications/Xcode6-Beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift failed with exit code 254

Upvotes: 14

Views: 15573

Answers (4)

Nicholas H.
Nicholas H.

Reputation: 1311

There several things going on here.

  1. There is no need to import extensions as you have to for Objective-C, as everything in the same module is automatically available to you in Swift. This means that your extension is actually successfully visible to the compiler in your view controller.
  2. You can only add computed properties to an extension. This means that you do not actually have a myVar to assign to or read from. So when you access myVar you are actually recursing infinitely. That is actually what the warning is alluding to (albeit in vague way):

    warning: attempting to access 'myVar' within its own getter
      return myVar
             ^
    
  3. As far as I know, there is no way to add non-computed properties to a type using an extension. This is also true of Objective-C where the only way to actually store a property added to a class using a class extension is to use Objective-C object association via objc_getAssociatedObject and objc_setAssociatedObject from objc/runtime.h.

  4. Finally there is definitely a bug in the compiler if your extension's computed property has a setter. The minimum working example to reproduce the bug, which does not include recursion (by eliminating the access to myVar) and just ignore the value is:

    import UIKit
    
    extension UIView {
      var myVar : Float {
      get {
        return 0
      }
      set {
      }
      }
    }
    

Upvotes: 8

Roger Fernandez Guri
Roger Fernandez Guri

Reputation: 988

Using static in front of the property declaration seems to do the trick.

extension UIView {
    static var myVar : Float {
        get {
            return myVar
        }
        set (newMyVar) {
            myVar = newMyVar
        }
    }
}

Hope it helps!

Upvotes: -1

taylorjcase
taylorjcase

Reputation: 72

I encountered this issue as well. It appears that it is a compiler bug. The compiler seems to crash if you have computed properties in a standalone extension file. The workaround I have found is to create the extension in non-standalone file. So in this case you could move your extension into your ViewController.swift file. Like so:

import UIKit

extension UIView {
    var myVar : Float {
        get {
            return myVar
        }
        set (newMyVar) {
            myVar = newMyVar
        }
    }
}

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        var squareView: UIView = UIView(frame: CGRect(x: 0, y: 0, width: 200, height: 200))

        squareView.myVar = 50

        self.view.addSubview(squareView)
        println("Offset: \(squareView.myVar)")
    }
}

Upvotes: 2

Encore PTL
Encore PTL

Reputation: 8214

After selecting the file in Xcode in the Project navigator on the left, make sure you check the app and test in the Target Membership section in the Inspector view on the right.

If it is not checked then it won't be included in the project and hence you will get the compile error.

enter image description here

Upvotes: 0

Related Questions