Closed juliozatarain closed 7 years ago
Thanks for opening this issue. Continued support for projects transitioning from objc to swift has been an important feature for a while.
I'm a little surprised to see this exact error. I'll have to dig into how that class is linked to understand it better. It might be as simple as it missing from the umbrella header for the project it belongs to.
Sent From A Very Small Keyboard
On Sep 12, 2016, at 08:15, Julio zatarain notifications@github.com wrote:
We are trying to integrate swift into our project. When we try to use fakes such as PSHKFakeHTTPURLResponse in our tests we get an error while installing the bundle to the simulator:
"Failed to load test bundle from file: Symbol not found: OBJC_CLASS$_PSHKFakeHTTPURLResponse"
It seems to be looking for the symbols inside the App symbols, instead of the Spec symbols.
Here is our Podfile:
source 'https://github.com/CocoaPods/Specs.git' use_frameworks!
target 'app' do pod 'Blindside' pod 'Flurry-iOS-SDK' pod 'MBProgressHUD', :git => 'https://github.com/gudatcomputers/MBProgressHUD.git' pod 'KSDeferred' pod 'PivotalCoreKit', :git => 'https://github.com/pivotal/PivotalCoreKit.git' pod 'TrustKit' end
target 'Specs' do pod 'Blindside' pod 'MBProgressHUD', :git => 'https://github.com/gudatcomputers/MBProgressHUD.git' pod 'KSDeferred' pod 'Cedar' pod 'Nimble', '3.2.0' pod 'PivotalCoreKit/Foundation', :git => 'https://github.com/pivotal/PivotalCoreKit.git' pod 'PivotalCoreKit/UIKit', :git => 'https://github.com/pivotal/PivotalCoreKit.git' pod 'TrustKit' end
Does PivotalCoreKit support a project with objC & swift code and tests together?
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub, or mute the thread.
Thanks for the quick response, so the error says that the symbol is expected in the .app: Expected in : ".app/Frameworks/PivotalCoreKit.framework/PivotalCoreKit"
I tried it using cocoapods version 0.39.0 and 1.1.0.beta.1 and I am getting the same error.
if I add the PCK foundation directory to the app target in the Podfile, then the symbol is found. But it is actually included when running the app itself so it uses the Foundation fakes instead of the real objects.
Are the tests frameworks supposed to be copied to that location?
Any update on this issue?
Are the tests frameworks supposed to be copied to that location?
Absolutely not. It shouldn't be necessary to add your test dependencies to your app in order for your tests to run correctly.
It sounds like you're using a Test Bundle, @juliozatarain -- is that correct? Do you invoke your tests by striking cmd+u
in Xcode, or by selecting your test scheme and typing cmd+r
?
If you're using a test bundle, then I think some additional work is necessary to make sure the frameworks specifically for your tests load when running your tests (and I forget how to do that, so I'd need to look at xcode's project settings and reverse engineer how to do it again). This is pretty complicated when using Cocoapods, since it really, REALLY wants to overwrite your project settings on your behalf, although it's possible.
I'm going to investigate how this actually works by setting up a small reproducible project. It would be nice to have a project that demonstrates how to use PCK in a mixed objc-swift world.
You may be interested in looking at this relevant cocoapods issue -- it might point you in the right direction for xcode project settings to change to make your tests compile again.
We are using a test bundle, we tried was is suggested in the cocoapods issue link and it seems to be working with cmd + u.
UPDATE: False alarm it does not work using cmd + u and xcode 8.
How can we approach moving away from a test bundle? @tjarratt
The general approach for running without a test bundle is
SpecSuite
, perhaps)SpecSuite
app to Cedar, PCK, and all dependencies your all usesmain
implementation in SpecSuite
to call CedarApplicationDelegate
instead of your UIApplicationDelegate
subclass.SpecSuite
targetSpecSuite
targetSpecSuite
targetIn order to run your tests, you would select the SpecSuite
target in Xcode, then hit cmd+r. You won't see the nice bezel appear telling you that the tests passed or failed, but you will get console output.
I prefer this approach personally because of how complicated Test Bundles with resources and extra frameworks end up being. Few people that I have met actually know how test bundles work, and it's kind of scary and amazing that Apple has been able to keep them functional for so long.
The approach that I've laid out above, while complicated and with some downsides (like not being able to use cmd+u and needing to switch targets), comes with the upside of having a simpler model -- your tests are just a separate application target, not a magical test bundle. This is a lot closer to what other languages do (ruby, go, javascript, elm, scala, java, c, c++, etc). I've never seen another language actually use anything like Test Bundles before I started doing OS X and iOS development.
Thinking about this some more, it sounds suspiciously similar to some other cocoapods issues that I've seen in the past.
It may have something to do with adding multiple copies of frameworks to both your specs and app targets.
Your podfile, truncated for clarity...
target 'app' do
pod 'MBProgressHUD', :git => 'https://github.com/gudatcomputers/MBProgressHUD.git'
pod 'KSDeferred'
pod 'PivotalCoreKit', :git => 'https://github.com/pivotal/PivotalCoreKit.git'
end
target 'specs' do
pod 'MBProgressHUD', :git => 'https://github.com/gudatcomputers/MBProgressHUD.git'
pod 'KSDeferred'
pod 'PivotalCoreKit', :git => 'https://github.com/pivotal/PivotalCoreKit.git'
end
This ends up (probably) creating a duplicate version of each framework into your Specs
test bundle. When you run your tests, Xcode runs your real app, and then injects each test bundle that your scheme's test action specifies at runtime. At that point, each class in the test bundles will be loaded into your app's runtime, potentially creating copies of existing classes (e.g.: there will be two classes called KSDeferred
(for example), but they will be distinct class instances).
My guess is that having doubled pods in your targets, combined with use_frameworks!
(which you needed for swift support) may be causing this problem, although it's really hard to actually verify without a minimal reproducible test case.
The easy change you might want to try is not including ALL of PivotalCoreKit in your app target. If you can specify that you only want to restrict the app to, say, Foundation/Core, you might be able to get it to load PivotalCoreKit/Foundation/PivotalSpecHelper
for your test target.
#other pods omitted for brevity
target 'app' do
pod 'PivotalCoreKit/Foundation/Core', :git => 'https://github.com/pivotal/PivotalCoreKit.git'
end
target 'Specs' do
pod 'PivotalCoreKit/Foundation/SpecHelper', :git => 'https://github.com/pivotal/PivotalCoreKit.git'
end
So I followed the steps to move away from the TestBundle and we are getting the following error when running it:
ld: framework not found XCTest for architecture x86_64
I am going to try being more specific with the inclusions and see what happens.
thanks!
So we kept the bundle approach and just stopped using PCK in the app target. And its working now.
We are trying to integrate swift into our project. When we try to use fakes such as PSHKFakeHTTPURLResponse in our tests we get an error while installing the bundle to the simulator:
"Failed to load test bundle from file: Symbol not found: _OBJCCLASS$_PSHKFakeHTTPURLResponse"
It seems to be looking for the symbols inside the App symbols, instead of the Spec symbols.
Here is our Podfile:
source 'https://github.com/CocoaPods/Specs.git' use_frameworks!
target 'app' do pod 'Blindside' pod 'Flurry-iOS-SDK' pod 'MBProgressHUD', :git => 'https://github.com/gudatcomputers/MBProgressHUD.git' pod 'KSDeferred' pod 'PivotalCoreKit', :git => 'https://github.com/pivotal/PivotalCoreKit.git' pod 'TrustKit' end
target 'Specs' do pod 'Blindside' pod 'MBProgressHUD', :git => 'https://github.com/gudatcomputers/MBProgressHUD.git' pod 'KSDeferred' pod 'Cedar' pod 'Nimble', '3.2.0' pod 'PivotalCoreKit/Foundation', :git => 'https://github.com/pivotal/PivotalCoreKit.git' pod 'PivotalCoreKit/UIKit', :git => 'https://github.com/pivotal/PivotalCoreKit.git' pod 'TrustKit' end
Does PivotalCoreKit support a project with objC & swift code and tests together?