Search code examples
objective-cswiftlinker-errorsobjective-c-swift-bridge

calling swift file in seperate project from objective c project. Apple Mach-o Linker error


we have a legacy iOS objective C app. We want to add "swift" functionality. Created a separate "Cocoa touch framework" project to reference it from the "objective C" project. I am getting this error when I try to call/init any of the methods in swift from objective c

Ld /Users/teeboy/Library/Developer/Xcode/DerivedData/super-aybvkjtipygrszeyqsnbmtglaaqi/Build/Products/Debug-iphonesimulator/super.app/super normal x86_64 cd /Users/teeboy/iWorkbench/super export IPHONEOS_DEPLOYMENT_TARGET=10.0 export PATH="/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin:/Applications/Xcode.app/Contents/Developer/usr/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin" /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -arch x86_64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator10.3.sdk -L/Users/teeboy/Library/Developer/Xcode/DerivedData/super-aybvkjtipygrszeyqsnbmtglaaqi/Build/Products/Debug-iphonesimulator -F/Users/teeboy/Library/Developer/Xcode/DerivedData/super-aybvkjtipygrszeyqsnbmtglaaqi/Build/Products/Debug-iphonesimulator -F/Users/teeboy/iWorkbench/super -filelist /Users/teeboy/Library/Developer/Xcode/DerivedData/super-aybvkjtipygrszeyqsnbmtglaaqi/Build/Intermediates/super.build/Debug-iphonesimulator/super.build/Objects-normal/x86_64/super.LinkFileList -Xlinker -rpath -Xlinker @executable_path/Frameworks -mios-simulator-version-min=10.0 -dead_strip -Xlinker -object_path_lto -Xlinker /Users/teeboy/Library/Developer/Xcode/DerivedData/super-aybvkjtipygrszeyqsnbmtglaaqi/Build/Intermediates/super.build/Debug-iphonesimulator/super.build/Objects-normal/x86_64/super_lto.o -Xlinker -no_deduplicate -Xlinker -objc_abi_version -Xlinker 2 -fobjc-arc -fobjc-link-runtime -ObjC -all_load -Xlinker -sectcreate -Xlinker __TEXT -Xlinker __entitlements -Xlinker /Users/teeboy/Library/Developer/Xcode/DerivedData/super-aybvkjtipygrszeyqsnbmtglaaqi/Build/Intermediates/super.build/Debug-iphonesimulator/super.build/super.app.xcent -lz -lPatientSearch -framework MapKit -framework ZipArchive -framework QuartzCore -lMobuleMenuCell -framework OCMockitoIOS -framework Security -lModuleNavigation -lToDoList -framework CoreData -lPatientChart -framework CoreText -framework Crashlytics -framework CoreLocation -lVisitNotes -lDataAccess -lDashboard -framework MobileCoreServices -framework SystemConfiguration -lframework -lsuperCommon -framework UIKit -framework OCHamcrestIOS -framework Foundation -framework CoreGraphics -Xlinker -dependency_info -Xlinker /Users/teeboy/Library/Developer/Xcode/DerivedData/super-aybvkjtipygrszeyqsnbmtglaaqi/Build/Intermediates/super.build/Debug-iphonesimulator/super.build/Objects-normal/x86_64/super_dependency_info.dat -o /Users/teeboy/Library/Developer/Xcode/DerivedData/super-aybvkjtipygrszeyqsnbmtglaaqi/Build/Products/Debug-iphonesimulator/super.app/super

Undefined symbols for architecture x86_64: "_OBJC_CLASS_$__TtC5utils3zip", referenced from: objc-class-ref in libDashboard.a(ASLandingPageVC.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 name of swift library is "utils". The legacy objective c app uses some other project dependencies. sorry, newbie to xcode.


Solution

  • Without knowing exactly how you referenced the Swift framework in the Objective-C app, I can only guess that you referenced a framework binary that is built for a platform different from the one you are trying to build the app for.

    For instance, this would happen if you built the framework for a device, then included, in the Framework Search Paths under the app's Build Settings, the path to the directory containing the resulting .framework directory and then tried to build the app for a simulator. It would work if you used the correct framework binary (built for the simulator in this case).

    However, a more elegant way of doing this is to embed the Swift framework in your application. Assuming the framework and the app are in different projects, you might do the following:

    • Ensure that the framework project is not open in Xcode.
    • Open the app project in Xcode.
    • Drag the framework's .xcodeproj from Finder to the app project in Xcode to create a reference.
    • Under General -> Embedded Binaries add your Swift .framework.
    • When you build the app, Xcode will build the framework for the correct architecture and use and embed it in your app.

    See https://developer.apple.com/library/content/technotes/tn2435/_index.html for more info about embedding frameworks. BTW, when the linker failed, did you also see a warning from ld about a file missing a required architecture?