Can't allocate anything from my project - static library (using XCTests) - ios

When i try tests like
#interface My_Tests : XCTestCase
- (void)testExample {
XCTAssertTrue(#YES, #"has to be passed");
}
Everything is working fine. However when i try such pattern:
#import "NSString+Additions.h"
//...
- (void)testNameValidation {
NSString *string = #"Harry";
XCTAssertTrue([string stringIsValid], #"Name validation error");
}
I get:
file:///Users/username/project/ProjectTests/ProjectTest.m: test failure:
-[Project_test testNameValidation] failed: (([string stringIsValid]) is true)
failed: throwing "-[__NSCFConstantString stringIsValid]: unrecognized selector
sent to instance 0x2f58ae8" - Name validation error
I can also just do something like this:
#import "MyViewController.h"
//...
- (void)testSomething {
MyViewController *a = [[MyViewController alloc] init];
XCTAssertTrue(#YES, #"Impossible!");
}
I get 2 errors (first and last line):
Undefined symbols for architecture i386:
"_OBJC_CLASS_$_MyViewController", referenced from:
objc-class-ref in MyTest.o
ld: symbol(s) not found for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Can someone explain me what am I doing wrong..? I can't do anything with my classes. It may be worth adding that i'm trying to test my custom static library and files included in it. I'm using CocoaPods and I've set environment basing on Kiwi description (only to be able to use CocoaPods files in my tests, I was also wondering whether to use Kiwi or XCTests).
PS. This is my first try with unit tests of any type, so please forgive eventual noobish question ;)

The unit tests aren't linked against the static library.
Add the library to the "Link Binary with Libraries" section of the build phases for the test target.

Related

kRNCryptorAES256Settings referenced error

I am trying to use RNCryptor in my app to do some data encryption.
Look at the code below:
var encryptedData: NSData = RNEncryptor.encryptData(data, withSettings:kRNCryptorAES256Settings, password: aPassword, error: nil)
Undefined symbols for architecture i386:
"_kRNCryptorAES256Settings", referenced from:
__TFC8UtraceUI24ChatBubbleViewController21textFieldShouldReturnfS0_FCSo11UITextFieldSb
in ChatBubbleViewController.o ld: symbol(s) not found for architecture
i386 clang: error: linker command failed with exit code 1 (use -v to
see invocation)
I am not sure why does it try to look for the constant name with an underscore; ideally it should have tried to look for kRNCryptorAES256Settings which is their in the bridgesupport and other header files.
Any clue what might be going wrong ?
Thanks !
You probably forgot to include the .m files as part of your build. Check the "Build Sources" step in your Build Phases.
If you're working in Swift, you may want to look at the new Swift version. That'll merge to master next week.
Swift cannot deal with C Structs, which is what kRNCryptorAES256Settings is. This issue has nothing to do with the architecture of the devices.
So to go around that, I created my own method in RNEcryptor with the sole reason to abstract the need of the C struct.
+ (NSData *)EncryptDataForSwift:(NSData *)data password:(NSString *)password error:(NSError **)error
{
return [RNEncryptor encryptData:data withSettings:kRNCryptorAES256Settings password:password error:error];
}
I am not sure whether it good idea or not, but this makes my project compilable, as I can call my method via Swift without needing to reference any C-only code:
var encryptedData:NSData = RNEncryptor.EncryptDataForSwift(data, password: Password, error: nil)
Hope this will help someone.

Defining a new interface causes "Undefined symbols for architecture x86_64:". Existing interfaces work fine

I have an iOS app and am using XCode Version 6.3.1 (6D1002).
I have a m file in which I define
#interface CustomObject:NSObject {} #end
and I try to use in viewDidLoad as
CustomObject* obj = [[CustomObject alloc]init];
When I run this, I get linkage errors saying
Undefined symbols for architecture x86_64:
"_OBJC_CLASS_$_CustomObject", referenced from:
objc-class-ref in ChooseAlbumViewController.o
ld: symbol(s) not found for architecture x86_64
I have similar interfaces defined for other objects and those continue to build, link and run fine. Any new interfaces I'm defining are failing with these linkage errors. I could use some help to figure out what's causing this. I'm new to iOS development so if I'm missing information crucial to figure this out please let me know and I'll add it.
Few flags from my Build Settings that might help -
Build Active Architecture Only = YES
Architectures = Standard Architecture armv7 armv64
Valid Architectures = arm64 armv7 armv7s
Here is the code in which I define the interface and try to use it
#interface CustomAlbum : NSObject {
}
#end
#implementation ChooseAlbumViewController
{
}
- (void)viewDidLoad {
[super viewDidLoad];
CustomAlbum* a = [[CustomAlbum alloc] init];
}
Figured it out, the problem was that I had only defined an interface but had not defined an implementation. Adding
#implementation User
#end
to the .m file solved the linkage issues.
Thanks for the help guys
Most of the time, this happens when your class isn't being compiled into the target you want. Select the .m file that CustomObject is in and check the right sidebar. In the first tab, there should be a list of targets. Check ✔️ your current target so that Xcode compiles it.
while compiling the source file ChooseAlbumViewController looks for a corresponding header. The header named CustomAlbum doesn't match. This causes the error message.

OCMVerify and Undefined symbols for architecture i386/armv7/armv7s

I am using OCMock (version 3.1.1) in my project and I am trying to use the OCMVerify macro to check if some method is called inside my object.
The problem is when I put this line:
OCMVerify([mockEngine notify]);
XCode show me the following link error (I've tried all platforms though):
Undefined symbols for architecture i386:
"OCMMakeLocation(objc_object*, char const*, int)", referenced from:
-[T009_EngineTest testPostEvent] in T009_EngineTest.o
ld: symbol(s) not found for architecture i386
I took the last version of the library from the website and I've also tried to compile it by myself.
Here is the unit test code:
Engine *mockEngine = OCMClassMock([Engine class]);
Object *obj = [[Object alloc] init];
[mockEngine startUp];
[mockEngine run];
[mockEngine postEvent:obj];
[NSThread sleepForTimeInterval:0.5];
OCMVerify([mockEngine notify]); // << THIS LINE CREATES THE LINK PROBLEM..
[mockEngine shutDown];
If I comment that line, the compiler links successfully..
It seems that that symbol is not in the library binary but I checked it was in the Xcode Compile Sources list.
Then I did a workaround... I hardcoded this line (the original code from the OCMock) into my unit test file:
OCMLocation *OCMMakeLocation(id testCase, const char *fileCString, int line){
return [OCMLocation locationWithTestCase:testCase file:[NSString stringWithUTF8String:fileCString] line:line];
}
And it works!
Now I want to know if there is some bug in OCMock or am I doing something wrong!
Here is the original header file declaring the external OCMakeLocation function:
https://github.com/erikdoe/ocmock/blob/master/Source/OCMock/OCMLocation.h
and here its implementation:
https://github.com/erikdoe/ocmock/blob/master/Source/OCMock/OCMLocation.m
Thanks.

UIColor Category Linker Errors

Earlier today I tried to add Unit tests to my xcode project for a static framework that I am creating. After adding the Unit Tests target to my project, I was able to successfully run the unit tests template and have the tests catch the default assertion. Then, after importing the file that I wanted to test into my new SenTestCase subclass, I tried to run the test but my UIColor category failed building with the test due to linker errors. The text of the linker errors is as follows:
Undefined symbols for architecture i386:
"_CGColorGetComponents", referenced from:
-[UIColor(ColorExtension) hexValue] in StaticFramework(StaticFramework)
"_CGColorGetNumberOfComponents", referenced from:
-[UIColor(ColorExtension) hexValue] in StaticFramework(StaticFramework)
ld: symbol(s) not found for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Next, I found where these two references were in my project. Both live in my category under the following function:
- (NSString *)hexValue
{
UIColor *color = self;
const size_t totalComponents = CGColorGetNumberOfComponents(color.CGColor);
const CGFloat * components = CGColorGetComponents(color.CGColor);
return [NSString stringWithFormat:#"#%02X%02X%02X",
(int)(255 * components[MIN(0,totalComponents-2)]),
(int)(255 * components[MIN(1,totalComponents-2)]),
(int)(255 * components[MIN(2,totalComponents-2)])];
}
If I remember correctly, both of these are part of the NSColor class. With a little more inspection, I also noticed that in my Unit Test's framework's folder, both UIKit.framework & Foundation.framework are red. I have tried reimporting them and building but this does not fix that issue either.
Interestingly enough, my static framework will still build and run fine as long as the associated Test is not also run. And when I comment this function out (and every time I use it), the Unit Test builds without issues. Would I be correct in my assumption that the missing UIKit.framework & Foundation.framework could be causing the linker not finding the NSColor properties? Does anyone have any additional suggestions that could explain why these properties are causing these issues or what I could do to fix them?
Any help would be greatly appreciated. Thanks for the assistance.
The linker error indicates that you are using CoreGraphics functions but you are not linking the CoreGraphics framework.
Update your project/target so you link the CoreGraphics.framework and the linker issues will be resolved.

"symbol(s) not found for architecture i386" problem using ShareKit

I want to use the http://getsharekit.com framework for future iOS projects. Hence I started testing out the framework.
But I already get the following error:
Undefined symbols for architecture i386:
"_OBJC_CLASS_$_SHKItem", referenced from:
objc-class-ref in ShareKitTestAppDelegate.o
"_OBJC_CLASS_$_SHKActionSheet", referenced from:
objc-class-ref in ShareKitTestAppDelegate.o
ld: symbol(s) not found for architecture i386
collect2: ld returned 1 exit status
Often, as far as I know, these problems arise if header files are wrongly imported. But I don't see any error here in the following code where the problem above occurs:
#import "ShareKitTestAppDelegate.h"
#import "SHK.h"
#import "SHKItem.h"
#import "SHKActionSheet.h"
- (IBAction) letshare:(id)sender
{
// Create the item to share (in this example, a url)
NSURL *url = [NSURL URLWithString:#"http://getsharekit.com"];
SHKItem *item = [SHKItem URL:url title:#"ShareKit is Awesome!"];
// Get the ShareKit action sheet
SHKActionSheet *actionSheet = [SHKActionSheet actionSheetForItem:item];
// Display the action sheet
[self.window addSubview:actionSheet];
}
I also included the ShareKit Headers Folder into HeaderSearchPath Build-Options, because of searching for all the headers.
But I don't see any error here or anything missed.
Can somebody help me?
With best regards,
Andreas
I had a similar problem with the following linker error:
Undefined symbols for architecture i386: "_OBJC_CLASS_$_SHK"
I resolved it by adding SHK.m to compiled sources under Project settings->Target->Build Phases. Not sure why SHK.m was not in the compiled sources list, and it was working previous to duplicating the Target. After the duplication I couldn't link any of the targets.
Adding SHKItem.m or SHK.m to compiled sources might help you if they aren't there already.
Read this http://getsharekit.com/install/.
Have you added the frameworks?

Resources