IBDesignable Errors When Adding to Tests Target
Asked Answered
A

6

22

I have a simple UIButton subclass that implements IBDesignable with an IBInspectable var:

@IBDesignable class Button: UIButton {
    @IBInspectable var borderColor: UIColor = UIColor.whiteColor() {
        didSet { layer.borderColor = borderColor.CGColor }
    }
}

I am not using this within a framework and it is working in Interface Builder as intended, however, once I add this subclass to my Tests target, it stops rendering live and I get the following errors:

Main.storyboard: error: IB Designables: Failed to update auto layout status: dlopen(TestTests.xctest, 1): Library not loaded: @rpath/XCTest.framework/XCTest
Referenced from: TestTests.xctest
Reason: image not found

Main.storyboard: error: IB Designables: Failed to render instance of Button: dlopen(TestTests.xctest, 1): Library not loaded: @rpath/XCTest.framework/XCTest
Referenced from: TestTests.xctest
Reason: image not found

If I remove IBDesignable and the IBInspectable vars, the errors go away - unfortunately so does the live rendering in Interface Builder.

How do I test against an IBDesignable class without these errors?

Averett answered 25/9, 2014 at 5:9 Comment(2)
Any chance of posting to github?Kra
I had errors like this when my UIView subclass was implemented in a Cocoapod. Moving the UIView class to the main app made it work.Karenkarena
V
19

At first, I thought this was a kind of bug in Xcode. Following is the workaround I found:

STEP 1

Mark your class and properties as public.

@IBDesignable public class Button: UIButton {
    @IBInspectable public var borderColor: UIColor = UIColor.whiteColor() {
        didSet { layer.borderColor = borderColor.CGColor }
    }

    @IBInspectable public var borderWidth:CGFloat = 0.0 {
        didSet { layer.borderWidth = borderWidth }
    }
}

STEP 2

Import your application module from your "Tests" module.

For example, assuming that your application is named MyGreatApp, in your MyGreatAppTests/MyGreatAppTests.swift:

import UIKit
import XCTest
import MyGreatApp

class MyGreatAppTests: XCTestCase {

    func testExample() {
        let btn = Button()
        btn.borderColor = UIColor.redColor()
        XCTAssertEqual(UIColor(CGColor:btn.layer.borderColor), UIColor.redColor(), "borderColor")
    }
}

You don't need to add 'Button.swift' to your "Tests" target.

STEP 3 (for Swift)

In your storyboard explicitly select the module MyGreatApp for any custom classes instead of letting Xcode use the current module.

Interface Builder select main target module

Vista answered 26/9, 2014 at 11:35 Comment(9)
Adding public to the class or vars didn't fix the problem. Restarting Xcode has always cleared the errors until I reopen the storyboard.Averett
OK, I confirmed that this does not solve the problem. Sorry for that. I edited the answer.Vista
I think I may have oversimplified my example... I am using the button within another class that is also being tested and also testing a storyboard that contains @IB_ classes. The situation I am running into is that I would have to mark all classes as public for the importing of the module to work. Is the problem that the compiler just can't find @rpath/XCTest.framework/XCTest?Averett
Just in case you didn't see this #24995093Vista
Thanks for the info. I've got something going with your suggestions. The one thing that finally made it work in addition to declaring the classes and vars as public was to select the module of any classes uses in my storyboard to be the same as my primary target - otherwise Xcode was using the active target which broke when I tested using the Test target.Averett
I awarded you the bounty and added that 3rd crucial step to your answer of selecting the main target module for the class in Interface Builder. Thanks again!Averett
It may be relevant to state that the last step (adding the module) should only be done when using swift, so if you are still using Objective-C, don't set the module.Triforium
Unfortunately, it doesn't work for me:-( I still have the same errorRamachandra
Step 3 was what I needed, after setting one of my targets it worked as it should.Peremptory
P
15

Your question describes exactly the circumstances I experienced. The error is also visible in the attribute inspector under your own attributes.

This is the workaround that worked for me:

Step 1 remove all @IBDesignable and @IBInspectable from your source code

Step 2 Go back to the interface builder. The error is still there.

Step 3 Restart XCode, rebuild your project. Errors should be vanished.

Step 4 add all @IBDesignable and @IBInspectable again to your source code

After this steps I was able to go on with my project without any problems.

My theory why this works is that the interface builder caches some stuff that is not deleted (and rebuilt later) when you do a Project -> Clean.

The other answer (Importing your main module into your test module) is a good idea and solved some nasty problems for me in the past but not this one.

Paresis answered 1/3, 2015 at 8:17 Comment(5)
In addition to a Clean, have you tried manually deleting the Derived Data folder to clear out your errors?Averett
Can't check this any more, because I don't know how to create this problem deliberately.Paresis
I had this problem, deleted Derived Data, and the error was still there. Then I followed Gerd's directions, and the error was gone. I agree with Gerd's theory that IB caches stuff somewhere that isn't cleaned, and would now add that it's also somewhere outside Derived Data. If anyone knows where IB is caching things, let us know so we can delete it directly in situations like this! :)Simard
You probably also need to delete ~/Library/Caches/com.apple.dt.Xcode see this link for more details https://mcmap.net/q/16662/-how-to-empty-caches-and-clean-all-targets-xcode-4-and-later I recommend saving symlinks to common places like this or writing an applescript or shell script to delete them.Santee
Worked for me too. Thanks.Lummox
L
3

The solution is very simple. You need to remove your test target, and create it once again from the start. When I had moved the project to Xcode 7, I got an warning that my test target is damaged. So I decided to set it up once again. IT WORKED!.

Additionally you do not attach your storyboards and not even any class to your test target. Please do not do it like this:

enter image description here

Instead, do it this way:

enter image description here

So, simply remove any file from your test target (including classes with @IBDesignables), then If you need access to your classes within your test target just use @testable import MyApp:

enter image description here

It is working and every errors with IBDesignables will disappear. Enjoy:-)

Lobeline answered 26/6, 2015 at 12:23 Comment(0)
S
2

What is causing this?

This error appears when two things happen:

  1. You include any file containing @IBDesignable or @IBInspectable in your test target.
  2. You open your .storyboard or .xib file (containing your designable/inspectable views).

How can I prevent this from happening?

Either:

  1. Don’t include files containing @IBDesignable or @IBInspectable in your test target. (If you’re just testing a few isolated model files, they can remain members of your test target.)
  2. Remove all of your app’s files from your test target (as illustrated in Bartłomiej's answer), and instead import your app’s module into your test file (e.g. @testable import MyAppsee here for more details.) This is the best practice, allowing you to continue testing your designable/inspectable views as well as any model code in your app.

How can I solve it once it's already happened?

The pesky thing with this error is that it doesn’t automatically go away once the problem has been solved, potentially because IB may be caching something as Gerd suggests in his answer.

What I’ve found is that once you’ve actually performed either of the two preventative measures I listed above, simply restarting Xcode (without modifying any code) should make the error go away.

Simard answered 5/1, 2016 at 7:2 Comment(0)
M
1

I finally found the solution. Juste add "-framework XCTest" to your test target under Build Settings / other linker flags.

Maletta answered 25/9, 2015 at 13:49 Comment(0)
C
0

This issue can also be caused by including any categories or extensions on the view class in your test target.

Considerable answered 29/4, 2016 at 17:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.