Linker error when implementing NSObject protocol while using enums? - ios

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

Related

Drag and Drop into a `UICollectionView` placeholder in iOS 11 Beta 4

The API for dragging and dropping into a UICollectionView changed in iOS 11 Beta 4. In beta 1-3, the code looked like:
let placeholderContext = coordinator.drop(
item.dragItem,
toPlaceholderInsertedAt: indexPath,
withReuseIdentifier: "reuseID",
cellUpdateHandler: { _ in }
)
In beta 4, the introduced UICollectionViewDropPlaceholder. My code is
let placeholder = UICollectionViewDropPlaceholder(
insertionIndexPath: indexPath,
reuseIdentifier: "reuseID"
)
let placeholderContext = coordinator.drop(item.dragItem, to: placeholder)
I am getting this compile error:
Undefined symbols for architecture arm64:
"_OBJC_CLASS_$_UICollectionViewDropPlaceholder", referenced from:
objc-class-ref in StickerLibraryViewController.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
note: symbol(s) not found for architecture arm64
error: linker command failed with exit code 1 (use -v to see invocation)
Other than not using a placeholder until beta 5, anyone have any ideas of how to get this working in beta 4?
Thanks!
Until this is fixed in Beta 5, I ended up solving this issue by dropping down into the Objective-C runtime.
In the Obj-C header…
NS_ASSUME_NONNULL_BEGIN
#interface RKNFactory : NSObject
- (UICollectionViewDropPlaceholder*)placeholderForIndexPath:(NSIndexPath*)indexPath resuseIdentifier:(NSString*)reuseIdentifier;
#end
NS_ASSUME_NONNULL_END
In the implementation…
#import ObjectiveC.runtime;
#implementation RKNFactory
- (UICollectionViewDropPlaceholder*)placeholderForIndexPath:(NSIndexPath*)indexPath resuseIdentifier:(NSString*)reuseIdentifier {
SEL initSelector = NSSelectorFromString(#"initWithInsertionIndexPath:reuseIdentifier:");
Class placeholderClass = NSClassFromString(#"UICollectionViewDropPlaceholder");
return [[placeholderClass alloc] performSelector:initSelector withObject:indexPath withObject:reuseIdentifier];
}
#end
And then from the Swift code…
return RKNFactory().placeholder(for: indexPath, resuseIdentifier: reuseIdentifier)
I had a similar problem with local authentication not compiling on on the simulator architecture when it was in beta.
Does it compile if you remove arm64 from valid architectures in build settings (or turn off “build all architectures”)?
If they compiled this symbol for simulator, but left it out for arm64, the only solution might be to prevent it from compiling on arm64 and test it only on the simulator for now.
You can also wrap the code temporarily in a “#if block” that prevents the compiler from looking at it when building arm64.
Finally, if you’re building for any versions of iOS under iOS 11, be sure to try turning those off for now, in case they forgot to mark API availability (which might have let the compiler provide a more helpful message).

Calling swift function from objective c gives linker error

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

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.

(Swift) Error: UIApplicationMain attribute cannot be used in a module

So, as part of my effort to learn Swift, I got my hands on the open source "Adventure" project (found HERE) made available by Apple.
Embarrassingly, I didn't go too far before I ran into my first predicament. When I tried to compile the project, I got the following error:
'UIApplicationMain' attribute cannot be used in a module that contains top-level code'
Specifically, the error is found in the AppDelegate.swift file and the attribute comes immediately after the import UIKit declaration as follows:
import UIKit
#UIApplicationMain
class AppDelegate: NSObject, UIApplicationDelegate {
var window: UIWindow?
....
// a number of functions that I won't list here...
....
}
I did some research on this but understandably(?) there doesn't seem to be much information regarding this issue. I wonder if anyone has run into the same issue.
(By the way, I am using Xcode6-beta5)
EDIT 1 --------------
Now with a fresh install of Beta6, I get the following errors after compile:
Undefined symbols for architecture x86_64:
"TFSs15_arrayForceCastU___FGSaQ__GSaQ0", referenced from:
__TFC9Adventure13HeroCharacter20animationDidCompletefS0_FOS_14AnimationStateT_ in HeroCharacter.o
__TFC9Adventure13HeroCharacter14fireProjectilefS0_FT_T_ in HeroCharacter.o
__TFC9Adventure4Cave15applyCaveDamagefS0_FTSd10projectileCSo6SKNode_T_ in Cave.o
__TFC9Adventure4Cave12performDeathfS0_FT_T_ in Cave.o
__TFFC9Adventure4Cave16loadSharedAssetsFMS0_FT_T_U_FT_T_ in Cave.o
__TFC9Adventure6Goblin20animationDidCompletefS0_FOS_14AnimationStateT_ in Goblin.o
__TFFC9Adventure6Goblin16loadSharedAssetsFMS0_FT_T_U_FT_T_ in Goblin.o
...
"__TFSsoi1aUSs17_RawOptionSetType_USs21BitwiseOperationsTypeSs9Equatable__FTQ_Q__Q_", referenced from:
__TFC9Adventure21LayeredCharacterScene14handleKeyEventfS0_FTCSo7NSEvent7keyDownSb_T_ in LayeredCharacterSceneOSXEvents.o
"__TFVSC6CGSizeCfMS_FT5widthSd6heightSd_S_", referenced from:
__TFFC9Adventure6Archer16loadSharedAssetsFMS0_FT_T_U_FT_T_ in Archer.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1
I'm not even going to try to guess what these errors mean.
Apparently the Adventure project doesn't compile correctly in Xcode6-Beta5. However, Xcode6-Beta6 compiles and runs it just fine.
As for the error encountered after upgrading to Beta6, the way to fix that is to delete the derived data for the project. To do that, open the Organizer ("Window" menu -> "Organizer"), select the "Adventure" project on the left side of the window, then click the "Delete" button associated with the project's derived data (should be the top one on the far right).
For me, It seems there was another file called main.swift which was conflicting with my AppDelegate. I deleted it and the issue went away.

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.

Resources