iOS error: cannot find the symbol when linking in Swift - ios

I have following code in Swift in A.swift file:
/// **A.swift**
protocol Johnkui: class {
var name: TruncatedView? { get set }
}
/// typealias TruncatedView = String
class TruncatedView: UIView {
}
extension UIView {
private struct TruncatedViewKey {
static var navigationViewKey = "navigationViewKey"
}
var name: TruncatedView? {
set {
objc_setAssociatedObject(self, &TruncatedViewKey.navigationViewKey, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_ASSIGN)
}
get {
return objc_getAssociatedObject(self, &TruncatedViewKey.navigationViewKey) as? TruncatedView
}
}
}
and B.swift file has following code:
/// B.swift
class JJ: UIView, Johnkui {
}
When compiling these two files, a linking error was reported:
Undefined symbols for architecture x86_64:
"__TFE9SwiftTestCSo6UIViewm4nameGSqCS_13TruncatedView_", referenced from:
__TTWC9SwiftTest2JJS_7JohnkuiS_FS1_m4nameGSqCS_13TruncatedView_ in ViewController.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
However, when combining these two files into one, the error is gone, and I cannot find out the reason for this result, what's your explanation?

Related

Swift Compile Error - Undefined symbols for architecture arm64

I'm getting this error on my Swift iOs app when I try to compile:
Undefined symbols for architecture arm64:
"checkForiOS14 #1 () -> Swift.Bool in App_Clip.NoteView.(reminderSymbolName in _82CBB329F1D225F83535F59E6FD7F4C3).getter : Swift.String", referenced from:
App_Clip.NoteView.(reminderSymbolName in _82CBB329F1D225F83535F59E6FD7F4C3).getter : Swift.String in NoteView.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
The property it is referring to is a computed property/private var in a view to check the version of iOS:
private var iosVersion = UIDevice.current.systemVersion
private var reminderSymbolName: String {
if checkForiOS14() {
return "checkmark.circle"
} else {
return "checklist"
}
func checkForiOS14() -> Bool {
if let version = Double(iosVersion) {
if version <= 14.9 {
return true
} else {
return false
}
}
return false
}
}
I have done all the basic stuff, deleting derived data, cleaning my build folder, restarted my mac, I even went back to a commit that builds and copied the changed files to the new commit, but this error will not go away. I am not using any pods, but I am using some SPM packages. Any idea what is going wrong?
There's built-in availability checks you can use for this purpose:
private var reminderSymbolName: String {
if #available(iOS 14.9, *) {
return "checkmark.circle"
} else {
return "checklist"
}
}
See https://nshipster.com/available/
Well, isn't that always how it goes? You try everything, post on Stack, and then literally minutes later you fix it? Apparently the answer was taking my method out of the computed property and making it private, like so:
private func checkForiOS14() -> Bool {
if let version = Double(iosVersion) {
if version <= 14.9 {
return true
} else {
return false
}
}
return false
}
private var reminderSymbolName: String {
if checkForiOS14() {
return "checkmark.circle"
} else {
return "checklist"
}
}
Hope this helps you if you are stuck like I was...

RxTest: Undefined symbols for architecture x86_64 and arm64

I am trying to run the following test from Chapter 16: Testing with RxTest of Raywenderlich RxSwift book:
import XCTest
import RxSwift
import RxTest
#testable import Testing
class TestingViewModel : XCTestCase {
var viewModel: ViewModel!
var scheduler: ConcurrentDispatchQueueScheduler!
override func setUp() {
super.setUp()
viewModel = ViewModel()
scheduler = ConcurrentDispatchQueueScheduler(qos: .default)
}
func testColorNameIsRayWenderlichGreenWhenHexStringIs006636() {
// 1
let colorNameObservable = viewModel.colorName.asObservable().subscribeOn(scheduler)
// 2
viewModel.hexString.value = "#006636"
// 3
XCTAssertEqual("rayWenderlichGreen", try! colorNameObservable.toBlocking().first()!)
}
}
But I get this error on the simulator:
Undefined symbols for architecture x86_64:
"type metadata for RxCocoa.DriverSharingStrategy", referenced from:
TestingTests.TestingViewModel.testColorNameIsRayWenderlichGreenWhenHexStringIs006636() -> () in TestingViewModel.o
"protocol witness table for RxCocoa.DriverSharingStrategy : RxCocoa.SharingStrategyProtocol in RxCocoa", referenced from:
TestingTests.TestingViewModel.testColorNameIsRayWenderlichGreenWhenHexStringIs006636() -> () in TestingViewModel.o
"RxCocoa.SharedSequence.asObservable() -> RxSwift.Observable", referenced from:
TestingTests.TestingViewModel.testColorNameIsRayWenderlichGreenWhenHexStringIs006636() -> () in TestingViewModel.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
And This one on iPhone 6s:
Undefined symbols for architecture arm64:
"type metadata for RxCocoa.DriverSharingStrategy", referenced from:
TestingTests.TestingViewModel.testColorNameIsRayWenderlichGreenWhenHexStringIs006636() -> () in TestingViewModel.o
"protocol witness table for RxCocoa.DriverSharingStrategy : RxCocoa.SharingStrategyProtocol in RxCocoa", referenced from:
TestingTests.TestingViewModel.testColorNameIsRayWenderlichGreenWhenHexStringIs006636() -> () in TestingViewModel.o
"RxCocoa.SharedSequence.asObservable() -> RxSwift.Observable", referenced from:
TestingTests.TestingViewModel.testColorNameIsRayWenderlichGreenWhenHexStringIs006636() -> () in TestingViewModel.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Unfortunately, there is no support for this issue in Raywenderlich's forums.
After a lot of searches, As somebody suggests here for another similar issue I found that this error will be solved by importing RxCocoa.

Undefined symbols Swift.UnsafeMutableBufferPointer

After downloading Xcode 8 and migrating to Swift 3 I'm not longer able to archive the project. At the same time the project builds without any issues.
Error that I get:
Undefined symbols for architecture armv7:
"Swift.UnsafeMutableBufferPointer.(subscript.materializeForSet :
(Swift.Int) -> A).(closure #1)", referenced from:
function signature specialization of generic specialization
with
Swift.UnsafeMutableBufferPointer :
Swift.MutableCollection in Swift and
Swift.UnsafeMutableBufferPointer :
Swift.RandomAccessCollection in Swift> of Swift._siftDown (inout A,
index : A.Index, subRange : Swift.Range, by : inout
(A.Iterator.Element, A.Iterator.Element) -> Swift.Bool) -> () in
OrderCoordinator.o
function signature specialization of generic specialization
with
Swift.UnsafeMutableBufferPointer :
Swift.MutableCollection in Swift and
Swift.UnsafeMutableBufferPointer :
Swift.RandomAccessCollection in Swift> of Swift._heapSort (inout A,
subRange : Swift.Range, by : inout (A.Iterator.Element,
A.Iterator.Element) -> Swift.Bool) -> () in OrderCoordinator.o
function signature specialization of generic specialization
with
Swift.UnsafeMutableBufferPointer :
Swift.MutableCollection in Swift and
Swift.UnsafeMutableBufferPointer :
Swift.RandomAccessCollection in Swift> of Swift._partition (inout A,
subRange : Swift.Range, by : inout (A.Iterator.Element,
A.Iterator.Element) -> Swift.Bool) -> A.Index in OrderCoordinator.o
ld: symbol(s) not found for architecture armv7 clang: error: linker
command failed with exit code 1 (use -v to see invocation)
I was able to get rid of error by commenting array sorting code in following function:
func didFinishWithResults(_ results: [PhotoProcessorResult]) {
guard let album = albumService.currentAlbum else { return }
//let sortedResults = results.sorted(by: { $0.fileIndex < $1.fileIndex })
let updateItems = zip(sortedResults, album.assetItems).map { (photoProcessorResult, assetItem) -> UpdateItem in
UpdateItem(path: photoProcessorResult.filePath, position: photoProcessorResult.fileIndex, isCover: assetItem.isCover)
}
albumService.updateAlbumWithItems(updateItems) { (success, errorDescription) in
if success {
self.handleAlbumUpdate()
} else {
self.showFailureAlert(errorDescription) {
self.startProcessingAlbum(self.albumService.currentAlbum)
}
}
}
}
While I resolved issue by sorting data using NSArray, I don't like this solution.
Will be grateful for any suggestions.
Since it compiles i don't think there is anything wrong with your code. The fact that it says "Undefined symbols for architecture armv7" and is failing to archive tells me that something is going on with your project, but unfortunately there are many ways to cause this problem. arm7 is iphone 5 so your project is probably setup correctly only for arm64. Try the solutions mentioned here: Undefined symbols for architecture armv7
If here is problem only for the this line:
let sortedResults = results.sorted(by: { $0.fileIndex < $1.fileIndex })
You can change to it:
let sortedResults = results.sorted { (first, second) -> Bool in
return first.fileIndex < second.fileIndex
}
Did it solve your problem?
Issue disappeared after updating to XCode 8.1.
Thanks everyone :)

Linking error in unit test using URLRequestConvertible

I have a weird problem writing a simple unit test (Xcode 7.2) for a very simple function which makes sure a parameter is added to a URL:
func appendToken(token: String, toRequest request: URLRequestConvertible) throws -> URLRequestConvertible {
var error: NSError?
let modifiedRequest: NSMutableURLRequest
(modifiedRequest, error) = Alamofire.ParameterEncoding.URL.encode(request, parameters: ["token": self.token])
guard error == nil else {
// TODO: handle error
throw error!
}
return modifiedRequest
}
The unit test is like this:
func testTokenAddition() {
let token = "ABCD12345"
let client = MyClass(token: token)
let originalRequest = NSURLRequest(URL: NSURL(string:"http://localhost")!)
do {
let modifiedRequest = try client.appendToken(token, toRequest: originalRequest).URLRequest
XCTAssertTrue(modifiedRequest.URLRequest.URLString.hasSuffix("token=\(token)"))
} catch {
XCTFail()
print(error)
}
}
Obviously this is a very simple test on which I want to build upon (so please don't focus on the actual assertion). But when I try to run the test, I get this linking error:
Undefined symbols for architecture x86_64:
"protocol witness table for __ObjC.NSURLRequest : Alamofire.URLRequestConvertible in Alamofire", referenced from:
SDKitTests.SDKitTests.testTokenAddition (SDKitTests.SDKitTests)() -> () in SDKitTests.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
The function works when I run it from a normal target, so the problem is in the test function, but I'm not clear on how I should be calling it, I run the same code in a non-test class and there was no problem, so I'm a bit puzzled by this. Also the error message is a bit cryptic, from what I've Googled, a witness table is kind of like a vtable for protocols. But I haven't messed with that, the extension to NSMutableURLRequest is implemented in Alamofire, and I'm just using it.
What am I doing wrong? What do I need to do to fix it?
Ensure the Alamofire library is linked with your test target.
You may also need to remove inherit! :search_paths from the test target.

XCTest Array extension in swift

I wish to unit test my Array extension.
extension Array {
func itemPassingTest(test: (T) -> Bool) -> T? {
for item in self {
if test(item) {
return item
}
}
return nil
}
}
In my unit test target, I have
import XCTest
import JLTExample
class JLTExampleTests: XCTestCase {
func testExtensionArray() {
let target = [ ["a" : 1], ["a" : 2], ["a" : 3] ]
let actual = target.itemPassingTest { $0["a"] == 2 }
XCTAssertNotNil(actual)
}
}
When building I get the error
Undefined symbols for architecture i386:
"__TFSa15itemPassingTestU__fGSaQ__FFQSbGSqQ_", referenced from:
__TFC17JLTExampleTests17JLTExampleTests18testExtensionArrayfS0_FT_T_ in JLTExampleTests.o
ld: symbol(s) not found for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)
My guess is I'm importing my extension, but I don't know how to import an extension. I was hoping that my extension would have been imported with the rest of my code in import JLTExample.

Resources