Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Import Extension file in Swift

Tags:

ios

swift

uiview

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

like image 727
javienegas Avatar asked Jun 03 '14 17:06

javienegas


People also ask

Where do I put SWIFT extensions?

swift file. If your extending one of your own classes I find it best to keep it in the same file as the original class so that other developers know about it. If you have multiple extensions for a particular global class such as String , you could group them into a StringExtensions.

What is the file extension for SWIFT?

A file with . swift extension refers to SWIFT programming language introduced by Apple for writing software applications and apps for macOS, iOS, tvOS and beyond. Before SWIFT, Objective-C was the prime programming language for writing applications.

How do I create a SWIFT file extension?

Creating an extension in Swift When creating an extension, you add the word extension before the name. extension SomeNamedType { // Extending SomeNamedType, and adding new // functionality to it. }


2 Answers

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 {
      }
      }
    }
    
like image 97
Nicholas H. Avatar answered Oct 11 '22 22:10

Nicholas H.


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)")
    }
}
like image 21
taylorjcase Avatar answered Oct 11 '22 21:10

taylorjcase