Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I distribute a mix of Objective-C and Swift code to be run on the iOS simulator?

I have a set of Swift and Objective-C files that extend some of the functionality in the XCTest framework.

I was easily able to create a Cocoa framework composed of these files. I added all the files to an OS X framework target and, since some of them import XCTest headers, I linked XCTest.framework to my framework. Users are able to add the framework to their unit test targets, provided they are building for OS X.

Question: How can I do the same (i.e.: distribute this code) for users building for the iOS simulator?

What I've Tried (1): Cocoa Touch framework

I can't make a Cocoa Touch framework that imports XCTest.framework--doing so results in the following linker error ("Quick" is the name of the framework):

Ld /Users/modocache/Library/Developer/Xcode/DerivedData/Quick-cajmiuprocunntdhiwsnsfzqydkc/Build/Products/Debug-iphonesimulator/Quick-iOS.framework/Quick-iOS normal x86_64
    cd /Users/modocache/GitHub/modocache/Quick
    export IPHONEOS_DEPLOYMENT_TARGET=8.0
    export PATH="/Applications/Xcode6-Beta.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin:/Applications/Xcode6-Beta.app/Contents/Developer/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin"
    /Applications/Xcode6-Beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -arch x86_64 -dynamiclib -isysroot /Applications/Xcode6-Beta.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator8.0.sdk -L/Users/modocache/Library/Developer/Xcode/DerivedData/Quick-cajmiuprocunntdhiwsnsfzqydkc/Build/Products/Debug-iphonesimulator -F/Users/modocache/Library/Developer/Xcode/DerivedData/Quick-cajmiuprocunntdhiwsnsfzqydkc/Build/Products/Debug-iphonesimulator -F/Applications/Xcode6-Beta.app/Contents/Developer/Library/Frameworks -filelist /Users/modocache/Library/Developer/Xcode/DerivedData/Quick-cajmiuprocunntdhiwsnsfzqydkc/Build/Intermediates/Quick.build/Debug-iphonesimulator/Quick-iOS.build/Objects-normal/x86_64/Quick-iOS.LinkFileList -install_name @rpath/Quick-iOS.framework/Quick-iOS -Xlinker -rpath -Xlinker @executable_path/Frameworks -Xlinker -rpath -Xlinker @loader_path/Frameworks -Xlinker -objc_abi_version -Xlinker 2 -Xlinker -no_implicit_dylibs -mios-simulator-version-min=8.0 -framework XCTest -single_module -compatibility_version 1 -current_version 1 -Xlinker -dependency_info -Xlinker /Users/modocache/Library/Developer/Xcode/DerivedData/Quick-cajmiuprocunntdhiwsnsfzqydkc/Build/Intermediates/Quick.build/Debug-iphonesimulator/Quick-iOS.build/Objects-normal/x86_64/Quick-iOS_dependency_info.dat -o /Users/modocache/Library/Developer/Xcode/DerivedData/Quick-cajmiuprocunntdhiwsnsfzqydkc/Build/Products/Debug-iphonesimulator/Quick-iOS.framework/Quick-iOS

ld: building for iOS Simulator, but linking against dylib built for MacOSX file '/Applications/Xcode6-Beta.app/Contents/Developer/Library/Frameworks/XCTest.framework/XCTest' for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

What I've Tried (2): Cocoa Touch static library

Other projects similar to mine that extend the XCTest framework use static libraries to distribute their code. However, attempting to build a static library that includes Swift code results in the following error:

Libtool /Users/MBP-006FYGC/Library/Developer/Xcode/DerivedData/Quick-chbdhbmwzcgjlyfsbxuvmajagydy/Build/Products/Debug/libQuick-OSX.a normal x86_64
    cd /Users/MBP-006FYGC/GitHub/modocache/Quick
    export MACOSX_DEPLOYMENT_TARGET=10.7
    /Applications/Xcode6-Beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool -static -arch_only x86_64 -syslibroot /Applications/Xcode6-Beta.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk -L/Users/MBP-006FYGC/Library/Developer/Xcode/DerivedData/Quick-chbdhbmwzcgjlyfsbxuvmajagydy/Build/Products/Debug -filelist /Users/MBP-006FYGC/Library/Developer/Xcode/DerivedData/Quick-chbdhbmwzcgjlyfsbxuvmajagydy/Build/Intermediates/Quick.build/Debug/Quick-OSX.build/Objects-normal/x86_64/Quick-OSX.LinkFileList -ObjC -L/Applications/Xcode6-Beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx -Xlinker -rpath -Xlinker /Applications/Xcode6-Beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx -Xlinker -force_load -Xlinker /Applications/Xcode6-Beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/arc/libarclite_macosx.a -Xlinker -sectalign -Xlinker __SWIFT -Xlinker __ast -Xlinker 4 -Xlinker -sectcreate -Xlinker __SWIFT -Xlinker __ast -Xlinker /Users/MBP-006FYGC/Library/Developer/Xcode/DerivedData/Quick-chbdhbmwzcgjlyfsbxuvmajagydy/Build/Intermediates/Quick.build/Debug/Quick-OSX.build/Objects-normal/x86_64/Quick_OSX.swiftmodule -framework XCTest -framework Foundation -o /Users/MBP-006FYGC/Library/Developer/Xcode/DerivedData/Quick-chbdhbmwzcgjlyfsbxuvmajagydy/Build/Products/Debug/libQuick-OSX.a

error: /Applications/Xcode6-Beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: unknown option character `X' in: -Xlinker
Usage: /Applications/Xcode6-Beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool -static [-] file [...] [-filelist listfile[,dirname]] [-arch_only arch] [-sacLT] [-no_warning_for_no_symbols]
Usage: /Applications/Xcode6-Beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool -dynamic [-] file [...] [-filelist listfile[,dirname]] [-arch_only arch] [-o output] [-install_name name] [-compatibility_version #] [-current_version #] [-seg1addr 0x#] [-segs_read_only_addr 0x#] [-segs_read_write_addr 0x#] [-seg_addr_table <filename>] [-seg_addr_table_filename <file_system_path>] [-all_load] [-noall_load]

More Information

For those that are interested, or if you need more details, the project in question is on GitHub. I'm keeping track of what I've tried so far using this issue.

How can I distribute this Swift/Objective-C code (which uses XCTest code) to users who wish to use it in their iOS unit tests?

like image 402
modocache Avatar asked Jun 09 '14 18:06

modocache


People also ask

Can you mix Objective-C and Swift?

Overview. You can use Objective-C and Swift files together in a single project, no matter which language the project used originally. This makes creating mixed-language app and framework targets as straightforward as creating an app or framework target written in a single language.

Can you call Swift from Objective-C?

Call Swift from Objective-CThe Swift library cannot be directly called from Objective-C, since it is missing the required annotations in the code, and in many cases, modules do not inherit from NSObject, rather they use the native Swift data types.

Does Swift work with C?

Either way, Swift language is perfectly compatible with Objective-C and can be used interchangeably within the same project. This is especially useful for large projects that are being extended or updated: You can still add more features with Swift, taking advantage of the existing Objective-C codebase.

What is Objective-C in iOS?

Objective-C is the primary programming language you use when writing software for OS X and iOS. It's a superset of the C programming language and provides object-oriented capabilities and a dynamic runtime.

Which is better Swift or Objective-C?

For starters, Swift is easier to read and write than Objective-C. Swift also has a more concise syntax that makes it easier to understand code at a glance. In addition, Swift is more type-safe than Objective-C, meaning that it is less likely to produce unexpected results due to type mismatches.


1 Answers

What is the value of FRAMEWORK_SEARCH_PATHS in your project? I just created a fresh iOS framework and this was the default:

$(inherited) $(DEVELOPER_FRAMEWORKS_DIR)

Try this instead:

$(SDKROOT)/Developer/Library/Frameworks $(inherited) $(DEVELOPER_FRAMEWORKS_DIR)

This should cause Xcode to find the iOS framework bundle before the Mac version.

like image 181
Adam Sharp Avatar answered Oct 06 '22 16:10

Adam Sharp