IBDesignable Errors When Adding to Tests Target - ios

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?

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.

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.

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:
Instead, do it this way:
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:
It is working and every errors with IBDesignables will disappear. Enjoy:-)

What is causing this?
This error appears when two things happen:
You include any file containing #IBDesignable or #IBInspectable in your test target.
You open your .storyboard or .xib file (containing your designable/inspectable views).
How can I prevent this from happening?
Either:
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.)
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 MyApp—see 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.

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

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

Related

Storyboard, does not recognize UIControl actions anymore

This project runs and compiles fine, but in all storyboards if I was on a UIControl (such as a UIButton) interface builder doesn't seems able to detect it as the correct class.
As you can see in the connection inspector the action. The connection is spotted with an exclamation mark.
The identity inspector shows the class correctly.
I already tried to fully clean the project, even derived data.
Project build and runs fine but I can't connect actions anymore.
Any suggestion?
Apparently this seems a bug in Xcode.
To reproduce it you just need to make a protocol and make a UIButton conform to it.
This test few lines, breaks everything and you are no longer able to create and make connections from IB and the source file:
protocol TestProcol {
var test: String { get set }
}
extension UIButton: TestProcol {
var test: String {
set(val) {
titleLabel?.text = val
}
get {
return (titleLabel?.text!)!
}
}
}

Know at runtime that you are running in IBDesignable

(programming in swift 2)
In my iOS application I am using frameworks. I am also using the IBDesignable feature with great success. I have a bunch of views and buttons in frameworks that are IBDesignable and thus render nicely on the screen of interface builder.
Problem is that one of these views executes code when its initialized that will do an assertion if its being run just in the context of the IBDesignable interfacebuilder (executed just to render the IB screen). The reason for the assertion is valid, and really does not matter, bottom line is that I do not want to loose this functionality during "normal" operation.
My idea for a solution is to know when the code is being executed just for rendering in IB for IBDesignable mode, and thus build in a switch to not/do the assert.
I tried using the #if !TARGET_INTERFACE_BUILDER but this is not working, as this is a preprocessor directive and thus only evaluated a compile time, and the frameworks are precompiled (when used in the actual app).
I also thought about using prepareForInterfaceBuilder() but this is not applicable because the class throwing the assert has nothing todo with UIView itself.
Is there a function or any other way to check AT RUNTIME (in a framework) that your code is being run as part of IB screen rendering for IBDesignable mode?
After testing a few dozens solutions, I found the following to work reliably:
/**
Returns true if the code is being executed as part of the Interface Builder IBDesignable rendering,
so not for testing the app but just for rendering the controls in the IB window. You can use this
to do special processing in this case.
*/
public func runningInInterfaceBuilder() -> Bool {
//get the mainbundles id
guard let bundleId = NSBundle.mainBundle().bundleIdentifier else {
//if we don't have a bundle id we are assuming we are running under IBDesignable mode
return true
}
//when running under xCode/IBDesignable the bundle is something like
//com.apple.InterfaceBuilder.IBCocoaTouchPlugin.IBCocoaTouchTool
//so we check for the com.apple. to see if we are running in IBDesignable rendering mode
//if you are making an app for apple itself this would not work, but we can live with that :)
return bundleId.rangeOfString("com.apple.") != nil
}
SWIFT 4 version
/**
Returns true if the code is being executed as part of the Interface Builder IBDesignable rendering,
so not for testing the app but just for rendering the controls in the IB window. You can use this
to do special processing in this case.
*/
public func runningInInterfaceBuilder() -> Bool {
//get the mainbundles id
guard let bundleId = Bundle.main.bundleIdentifier else {
//if we don't have a bundle id we are assuming we are running under IBDesignable mode
return true
}
//when running under xCode/IBDesignable the bundle is something like
//com.apple.InterfaceBuilder.IBCocoaTouchPlugin.IBCocoaTouchTool
//so we check for the com.apple. to see if we are running in IBDesignable rendering mode
//if you are making an app for apple itself this would not work, but we can live with that :)
return bundleId.contains("com.apple.")
}

'Use of Unresolved Identifier' in Swift

So I have been making an app, and everything has been working great. But today I made a new class like usual and for some reason in this class I can't access Public/Global variable from other classes. All the other classes can, but now when ever I try to make a new class I can't. How would this be fixed?
I am using Swift and Xcode 6.
Working Class:
import UIKit
import Foundation
import Parse
import CoreData
var signedIn = true
class ViewController: UIViewController {
New Class:
import UIKit
class NewClass: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
signedIn = false
}
But on signedIn = false
I get the error:
use of unresolved identifier "signedIn"
One possible issue is that your new class has a different Target or different Targets from the other one.
For example, it might have a testing target while the other one doesn't. For this specific case, you have to include all of your classes in the testing target or none of them.
Once I had this problem after renaming a file. I renamed the file from within Xcode, but afterwards Xcode couldn't find the function in the file. Even a clean rebuild didn't fix the problem, but closing and then re-opening the project got the build to work.
'Use of Unresolved Identifier' in Swift my also happen when you forgot to import a library. For example I have the error:
In which I forgot the UIKit
import UIKit
Sometimes the compiler gets confused about the syntax in your class. This happens a lot if you paste in source from somewhere else.
Try reducing the "unresolved" source file down to the bare minimum, cleaning and building. Once it builds successfully add all the complexity back to your class.
This has made it go away for me when re-starting Xcode did not work.
Another place I've seen this error is when your project has multiple targets AND multiple bridging headers. If it's a shared class, make sure you add the resource to all bridging headers.
A good tip to is to look in the left Issue Navigator panel; the root object will show the target that is issuing the complaint.
For me this error happened because I was trying to call a nested function. Only thing I had to do to have it fixed was to bring the function out to a scope where it was visible.
In my case, I had an Object-C file which was also in the same Target Membership. I fixed by adding #import "YourObjectCFileHeader.h" inside file Bridging-Header.h
Because you haven't declared it. If you want to use a variable of another class you must use
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
var DestViewController : ViewController = segue.destinationViewController as ViewController
DestViewController.signedIn = false
}
You have to put this code at the end of the NewClass code
Your NewClass inherits from UIViewController. You declared signedIn in ViewController. If you want NewClass to be able to identify that variable it will have to be declared in a class that your NewClass inherits from.
I got this error for Mantle Framework in my Objective-Swift Project.
What i tried is ,
Check if import is there in Bridging-Header.h file
Change the Target Membership for Framework in Mantle.h file as shown in below screenshot.
Toggle between Private Membership first build the project , end up with errors.
Then build the project with Public Membership for all the frameworks appeared for Mantle.h file, you must get success.
It is just a bug of building with multiple framework in Objective-C Swift project.
If this is regarding a class you created, be sure that the class is not nested.
F.e
A.swift
class A {
class ARelated {
}
}
calling var b = ARelated() will give 'Use of unresolved identifier: ARelated'.
You can either:
1) separate the classes if wanted on the same file:
A.swift
class A {
}
class ARelated {
}
2) Maintain your same structure and use the enclosing class to get to the subclass:
var b = A.ARelated
I did a stupid mistake. I forgot to mention the class as public or open while updating code in cocoapod workspace.
Please do check whether accesor if working in separate workspace.
You forgot to declare the variable. Just put var in front of signedIn = false
My issue was calling my program with the same name as one of its cocoapods. It caused a conflict. Solution: Create a program different name.
This is not directly to your code sample, but in general about the error. I'm writing it here, because Google directs this error to this question, so it may be useful for the other devs.
Another use case when you can receive such error is when you're adding a selector to method in another class, eg:
private class MockTextFieldTarget {
private(set) var didCallDoneAction = false
#objc func doneActionHandler() {
didCallDoneAction = true
}
}
And then in another class:
final class UITextFieldTests: XCTestCase {
func testDummyCode() {
let mockTarget = MockTextFieldTarget()
UIBarButtonItem(barButtonSystemItem: .cancel, target: mockTarget, action: MockTextFieldTarget.doneActionHandler)
// ... do something ...
}
}
If in the last line you'd simply call #selector(cancelActionHandler) instead of #selector(MockTextFieldTarget.cancelActionHandler), you'd get
use of unresolved identifier
error.

unable to execute command: Segmentation fault: 11 swift frontend command failed due to signal (use -v to see invocation)

I have an iOS swift program that compiles and runs fine on Xcode Beta2. When I downloaded beta4, I got a few syntax errors for the new swift language which I corrected. I now get this error:
<unknown>:0: error: unable to execute command: Segmentation fault: 11
<unknown>:0: error: swift frontend command failed due to signal (use -v to see invocation)
The problem is that it does not tell me where this error is so that I can further troubleshoot it. Where can I type -v in order to "see the invocation" and troubleshoot further? Without this, there is absolute no way to figure out the problem. Thanks in advance.
Here's how I was able to find out what the problem was:
Click on the issue in the issue navigator (⌘ + 4, then click on the line with the red ! at the start)
At the bottom of the file that appears, there should be a line that says something like:
1. While emitting IR SIL function #_TToZFC4Down8Resource12getInstancesfMS0_U__FTSS6paramsGVSs10DictionarySSPSs9AnyObject__9onSuccessGSqFGSaQ__T__7onErrorGSqFT5errorCSo7NSError8responseGSqCSo17NSHTTPURLResponse__T___T_ for 'getInstances' at /path/to/file.swift:112:5
The location where your error occurred is at the end of that line. (In this case, on line 112 of file.swift in getInstances).
I was trying to add the PayPal framework to my iOS Project (Xcode 7.2 and Objective C language). When building it did not throw any error, but when I tried to archive the Project and make the IPA, I was getting that error
unable to execute command: Segmentation fault: 11
Screenshot:
After struggling for a long time, I disabled the Bitcode in Project's Target > Build Settings > Enable Bitcode. Now the project can be archived. Please check the following screenshot.
Can't really give a straight solution on this (although I'm sure it's an Apple bug), but I just came across the exact same error message and happen to solve it. Here's what I did:
In General
Comment out recently changed Swift code (check commits) until the app compiles again
Command-click each called method in the failing line and check if there could be an ambiguity
My Example
In my case (I was using the XMPPFramework written in Objective-C) the failing code looked like this:
for roomMessage: XMPPRoomMessage in self.messages {
let slices = split(roomMessage.nickname(), { $0 == "_" }, allowEmptySlices: false)
}
Once I replaced roomMessage.nickname() with "0_test" the code didn't fail any more. So I command-clicked the method nickname() (twice) and here's what I saw:
My guess was that the Swift 1.1 compiler has problems with figuring out which method to call if the exact type of an object is not clear. So I made the type of roomMessage explicit and got another error which I fixed by removing the braces behind the nickname() method call. This made my app build again. Here's the working code:
for roomMessage: XMPPRoomMessageCoreDataStorageObject in self.messages {
let slices = split(roomMessage.nickname, { $0 == "_" }, allowEmptySlices: false)
}
I hope this helps someone out there to investigate the issue more quickly than I did.
I also had the same problem,
when I cleaned the derived data
Remove all removed derived data from Trash as well.
Stop Xcode, restart it and clean build
It should be fixed now.
In my case this error because I use Class name for variable
var MYClass : MYClass {
get {
return.....
}
}
And this fixes my problem
var myClass : MYClass {
get {
return.....
}
}
My problem was that I tried to mimic static variables with the so-called module approach (the Module design pattern). So, I had something like that (just a simple static reference to an operation queue declared at the level of a swift file):
let globalQueue: NSOperationQueue = {
let queue = NSOperationQueue()
queue.suspended = false
queue.maxConcurrentOperationCount = NSOperationQueueDefaultMaxConcurrentOperationCount
return queue
}()
So, that worked fine in Xcode 6.x.x, but ceased to compile in Xcode 7beta. Just want you guys to be aware of it.
P.S. In general, I managed to find out what was wrong from the logs (see the screenshot attached). Hope this saves you some time.
I got Segmentation fault when I called a protocol function the same protocols extension.
I had a code something in the line with this:
protocol Rotatable {
func rotate() -> Self
}
extension Rotatable {
func rotate(steps: Int) {
for _ 0..<steps { self.rotate() }
}
}
When I later made an object and declared that it would follow the Rotatable protocol I got Segmentation fault 11 and the program crashed.
Ex: this would cause Segmentation fault and crash Xcode
struct SomeStruct : Rotatable {
}
If I however first implemented the function rotate() in SomeStruct and then afterwards declared that it conformed to Rotatable there where no problem.
I had a similar today and tried the steps described here including removing files I had recently modified. Nothing seemed to work. I tried something that had been suggested when SourceKit would crash in Xcode.
I when into the derived data directory and deleted everything. The location is listed under "Preferences -> Locations -> Derived Data" There is an arrow icon right next to the path which opens finder with that directory selected. Select all the directories inside and delete them. Close Xcode and Reopen it. That made the problem disappear for me.
I think that some intermediate file is getting corrupted and the compiler does not know how to handle it.
I get this error because a silly mistake!!
in a class I defined
var url: String!?
:)
So it seems that this description is a multiple & generic error for a lot of reasons!!
This can happen as well if you are porting Objective-C code to Swift and you move an objective C protocol to swift. If you leave off the #objc at the protocol definition and you still have Objective-C code that uses that protocol you can get this error.
The solution in that case is adding #objc to the protocol
protocol MyPortedProtocol {}
changes to
#obcj protocol MyPortedProtocol {}
Also make sure any classes that implement this protocol add #objc to the methods
I did answer in "Swift compiler segmentation fault when building"
I had this error too, and i fixed like this:
check your project and find out which files are using twice and remove one, or delete all and re-add them.
Errors in my xCode
:0: error: filename "AttributedString.swift" used twice: '/Users/.../CNJOB/CNJOB/AttributedString.swift' and '/Users/.../CNJOB/CNJOB/AttributedString.swift'
:0: note: filenames are used to distinguish private declarations with the same name
:0: error: filename "APIClient.swift" used twice: '/Users/.../CNJOB/CNJOB/APIClient.swift' and '/Users/.../CNJOB/CNJOB/APIClient.swift'
:0: note: filenames are used to distinguish private declarations with the same name
Command /Applications/Xcode 3.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swiftc failed with exit code 1
For me it's caused by adding the swift files to different targets (today extension in my case).
I forgot to add one #end after #implementation in a .m file that had multiple classes in it. Something like:
#implementation Adjust
#end
#implementation Data //#end For this class was missing
#implementation Create
#end
I got this bug because of line
self.textView.inputAccessoryView = self.toolbarItems;
If you delete it the error will gone.
My steps:
1)
Deleted Derived data
Cleared build folder Didn't help
Copied class files to another folder as backup and commented everything in this class. Error gone.
Commented code blocks one by one until
build was success.
For me the problem was mixing Generics, Extensions, and #objc.
It turns out Xcode doesn't like having #objc inside extensions of generic classes:
class FaultyClass<T: TypeValidator>: UIControl where T.ItemType == String {
}
extension FaultyClass: UITextFieldDelegate {
func textFieldDidEndEditing(_ textField: UITextField) {
}
}
The above code gives the error #objc is not supported within extensions of generic classes. So I moved the method to the class itself but didn't delete the empty extension. This got rid of the error but when I compiled the project I got the segmentation fault.
The solution was to move UITextFieldDelegate to the class declaration.
class GoodClass: <T: TypeValidator>: UIControl, UITextFieldDelegate where T.ItemType == String {
// MARK: - TextFieldDelegate
func textFieldDidEndEditing(_ textField: UITextField) {
}
}
My problem was in methods signatures:
func setCategory(categoryId: Int?, subcategoryId: Int?) -> FilterSettings {
func changeCategory(categoryId: Int?, subcategoryId: Int?, handler: #escaping (Int) -> ()) {
I don't get why compiler cannot handle such declarations.
In my case it was because of an inappropriate inout in the function parameters. So I suggest you to look for that as well.
For me it was something similar to what #LuisCien described in this answer https://stackoverflow.com/a/42803582/4075379
I didn't have any generics or #objc tags, but it was these lines of code that were causing the segmentation fault:
public extension CGFloat {
/// Whether this number is between `other - tolerance` and `other + tolerance`
func isEqual(to other: CGFloat, tolerance: CGFloat) -> Bool {
return (other - tolerance...other + tolerance).contains(self)
}
}
i.e. an extension on a primarily Objective-C primary type?
Very luckily, I was able to delete those lines because the project wasn't using anymore. That fixed the issue.
Dumb mistake. I referred to self in a Class method:
public class func FunctionName() -> UIImage {
let bundle = Bundle.init(for: type(of: self))
...
}
I run into this problem when building some legacy code whaich was not adapted for latest Swift versions.
Segmentation fault: 11
When you open Report navigator it contains some context like:
1. Apple Swift version 5.3.2 (swiftlang-1200.0.45 clang-1200.0.32.28)
2. While evaluating request IRGenSourceFileRequest(IR Generation for file "/Users/alex/Downloads/NSURLProtocolExample-Swift_complete/NSURLProtocolExample/AppDelegate.swift")
3. While emitting IR SIL function "#$s20NSURLProtocolExample11AppDelegateC11applicationAD29didFinishLaunchingWithOptionsSbSo13UIApplicationC_So12NSDictionaryCSgtF".
for 'application(application:didFinishLaunchingWithOptions:)' (at /Users/alex/Downloads/NSURLProtocolExample-Swift_complete/NSURLProtocolExample/AppDelegate.swift:17:3)
0 swift 0x000000010b2d3615 llvm::sys::PrintStackTrace(llvm::raw_ostream&) + 37
1 swift 0x000000010b2d2615 llvm::sys::RunSignalHandlers() + 85
2 swift 0x000000010b2d3bcf SignalHandler(int) + 111
3 libsystem_platform.dylib 0x00007fff2039bd7d _sigtramp + 29
...
To solve this issue:
comment the pointed line (line 17 in AppDelegate.swift)
Build and fix all others issues
uncomment line from step 1
Swift 5 Very Easy And Smooth Solution
1- Just check your last added Extension / Code / Folder File before then this issue occur
2- Just Commit the code or save that code
3- Clean and Build & DONE :-)
Happy Coding
I ran into a similar problem when switching from beta2 to beta4.
Clean
then
Build

iOS Swift unit test result in unresolved identifier

Simple function in swift for testing:
func testExample() {
var tagname = "someClass()"
var logger = Device("", "") //unresolved identifier
XCTAssert(true, "Pass")
}
Even after I import my module with "import ", I still cannot use classes from my module. Also though I might have messed something up in the project, but NONE of my sample projects will let me use module classes.
Seems like it should work but might have broken in beta 2.
EDIT: fixed it
The IDE didn't pick up the check for the param names. Seems Xcode is still a tad iffy
I hit the same issue today, not sure if this is only available recently - rather than using import TARGET_NAME in your test file and/or declaring your classes/methods as public, you can add your file to your Tests target via XCode's File Inspector.
Cmd + Opt + 1 to show it while in any file, and check the box under Target Membership for your Tests Target.
You may need to rebuild.... Cmd + b.
Should this be specific to my system.... I'm running Xcode 6.3 beta 1, and testing via Quick + Nimble, both installed with the latest cocoapods beta.
The problem for me was that I had non-alphanumerical characters in my main target name.
I had to import it the following way (Note the special #testable annotation)
#testable import my_tutorial_app
It seems that in Xcode 6 Beta 4 you need to declare public classes and methods as "public". Example:
public class Device {
public init(...) {
}
public func myMethod(...) {
}
}
Now they are accessible from the swift test class.
I had the same problem and discovered that it works if I call it like this:
SuperStructName.StructName

Resources