Calling swift function from objective c gives linker error - ios

I am trying to call swift function from objective c file.
Swift function implementation:
#objc class FXFormVariables : NSObject {
class func FXFontName() -> String { return fontName }
class func FXFontSize() -> CGFloat { return fontSizeLarge }
class func FXHiddenCell() -> NSArray { return hiddenElementFromFormIndex as NSArray }
}
Objective C:
NSArray *hideArray = [FXFormVariables FXHiddenCell];
if ([hideArray containsObject:#(cellIndexPath)]){
return 0.0;
}
Linker error in Buildtime:
Undefined symbols for architecture x86_64:
"_OBJC_CLASS_$__TtCC13Social_Engine11AppDelegate15FXFormVariables", referenced from:
objc-class-ref in FXForms.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
This code works fine in Xcode 7.3 but after upgrade to 8.3 it start throwing linker error.
Please help. Thanks in advance.

Import file named Project name appending by -Swift.h in your Objective-C file
Please check below example of import file
#import “ProjectName-Swift.h”
Xcode will generate this file when you build your project with .swift files.
Also, you can check from below question:
How to import Swift code to Objective-C

you can get this type of error check your class is listed under the "Compile Sources" step of the "Build Phases" tab of your target. Normally Xcode does this for you, but sometimes it loses the plot and you need to add the class file manually.
To do this:
TargetSettings -> Build Phases -> Compile Sources -> add your class -.swift >Build and Run

Related

Unit Tests for Swift & Objective C files

I’m having trouble setting up Unit tests (XCTestCase) for my Xcode Project.
The project contains Objective C and Swift files.
'Enable testability' and 'Defines Module' is set to 'YES'
I imported the main project with: #testable import Projectname
I created a separate (empty) Bridging header . And made sure that all te frameworks are imported in the Unit testing Target (through Project > Build Phases).
This works fine for all the Objective C classes/files. But not with the swift classes with have Objective C functions in it.
When i’m running the test it fails. And almost all the #import lines in the main bridging header get the same warning: “Pointer is missing a nullability type specifier (_Nonnull, _Nullable, or _Null_unspecified)”
I also get a warning for the class i try to import:
“Undefined symbols for architecture x86_64:
“Project.BaseController.__allocating_init () -> Project.BaseController", referenced from:
Main_App.ProjectTests.setUp () -> () in ProjectTests.o
"type metadata accessor for Flitsmeister.BaseController", referenced from:
Main_App.ProjectTests.setUp () -> () in ProjectTests.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)”
Is it possible to test Swift files with imported Objective C code?
Are there workarounds?

Admob Conversion Tracking in Swift

I tried to set conversion tracking in my iOS game, but I didn't be able to do that. The tutorial can be found here: https://developers.google.com/app-conversion-tracking/ios/?hl=it#usage_and_disclosure
I integrate the GoogleConversionTrackingSDK to my project, load AdSupport framework and type -ObjC in Other linker flags.
I tried to convert this snippet from Obj-C:
[ACTConversionReporter reportWithConversionID:#"MY_ID" label:#"MY_LABEL" value:#"MY_VALUE" isRepeatable:NO];
to Swift:
ACTConversionReporter.reportWithConversionID("MY_ID", label: "MY_LABEL", value: "MY_VALUE", isRepeatable: false)
and I put that in didFinishLaunchingWithOptions method of AppDelegate.swift, but I get the error:
Use of unresolved identifier 'ACTConversionReporter'
If I type in Obj-C bridging header in Swift Compiler - Code Generation in Build Settings "ACTReporter.h" (without qm), I put the header file in the folder of my game or if I type the whole path of "ACTReporter.h" ending with its name, I fail the build and I get 2 errors:
Undefined symbols for architecture armv7:
"_OBJC_CLASS_$_ACTConversionReporter", referenced from:
type metadata accessor for __ObjC.ACTConversionReporter in AppDelegate.o
ld: symbol(s) not found for architecture armv7 clang: error: linker
command failed with exit code 1 (use -v to see invocation)
I don't know what to do. I hope there is someone who can fix this.
You need to add to your project "YourProjectName-Bridging-Header.h" file
Here you can see how to add the file
in Bridging Header file add #import "ACTReporter.h"
Then it will work for you!

UITest: Undefined symbols for architecture armv7

I'm trying to call a swift singleton from my UITest target. I'm importing the main module: #testable import Ary but when I try to build it says:
Undefined symbols for architecture armv7:
"Ary.DataModelLayerOperation.getter : Ary.DataModelLayer", referenced from:
AryUITests.AryUITests.setUp (AryUITests.AryUITests)() -> () in AryUITests.o
d: symbol(s) not found for architecture armv7
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Syntax highlighting works though (the singleton doesn't have access modifiers, so it's marked as internal which should be perfectly fine for access from the test target)...
The function I'm calling is [in an XCTestCase]:
override func setUp() {
super.setUp()
if !DataModelLayerOperation.isUserLoggedIn() {
//do something
}
}
I'm afraid what you want to achieve is not possible at the moment. I have encountered similar problem and asked my question here. I will soon accept the answer that says:
The UI tests are a separate module from the app, therefore not run
inside your app as a logic test would.
I'm hoping this will be improved in the next Xcode versions.

Linker error when implementing NSObject protocol while using enums?

Here is a distilled version of the code I am having trouble with in Swift:
enum E {
case C
}
class Test: NSObject {
var v: E = .C
}
When I attempt to build, I get the following error:
Undefined symbols for architecture x86_64:
"__TWvdvC8TestTest4Test1vOS_1E", referenced from:
__TFC8TestTest4Testm1vOS_1E in AppDelegate.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
To reproduce this, simply make a new Swift project and paste the above code right into "AppDelegate.swift". Alternatively, make a new file and stick it in there instead!
Am I missing something obvious or is this yet another Swift bug? I did try deleting all derived data and other forms of voodoo magic.
Thanks for the help!
It seems like the compiler removes the enum if there is only one case?
I can reproduce your issue, it disappears when I add a second case :
enum E {
case C,D
}
class Test: NSObject {
var v : E = .C
}
I noticed a couple things when trying this:
In the current non-beta version of Xcode, I see the error you're referring to (almost certainly a Swift bug). However, if I add an extra value to the enum (case C,D), it compiles just fine
I couldn't reproduce the crash in the latest Xcode beta (Version 6.3 (6D520o)), which leads me to believe that the bug has been fixed in Swift 1.2

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

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.

Resources