I use CocoaPods in a project where we separate core material from app material.
Inside our workspace there are 3 projects (not counting Pods project), one for the core, and 2 others, one for the iOS version and another macOS version of the app.
The core project builds a framework which as dependencies. Those dependencies should be copied into a folder named Frameworks
, but are not.
Indeed, there is no 'Embed Pods Frameworks' build phase for the core framework target.
(There is one however for the core framework test target).
Everything builds fine, but when I launch the app, the loader complains it can't load frameworks :
dyld: Library not loaded: @rpath/Alamofire.framework/Versions/A/Alamofire
Referenced from: /Users/vince/Library/Developer/Xcode/DerivedData/App-ggigklukffxidydygewgkvwmfwbl/Build/Products/Debug/AppCore.framework/Versions/A/AppCore
Reason: image not found
I'm looking for a way to copy those dependencies inside the framework bundle.
Run pod install
inside the directory where the Podfile
file is.
Open the workspace, build and run the macOS target (same crash for iOS)
If I copy the script inside the 'Embed Pods Frameworks' build phase for the tests target, into a new script build phase for the core framework, it does work (dependencies are copied, no loading error).
I expected the app to run, without error.
The loader cannot locate and load a framework dependency inside my core framework.
CocoaPods : 1.1.1
Ruby : ruby 2.2.2p95 (2015-04-13 revision 50295) [x86_64-darwin14]
RubyGems : 2.4.8
Host : Mac OS X 10.12.1 (16B2555)
Xcode : 8.1 (8B62)
Git : git version 2.9.3 (Apple Git-75)
Ruby lib dir : /Users/vince/.rvm/rubies/ruby-2.2.2/lib
Repositories : master - https://github.com/CocoaPods/Specs.git @ d006285cac32ca0ec77dafe98114de840ace76a3
Executable Path: /Users/vince/.rvm/gems/ruby-2.2.2/bin/pod
cocoapods-deintegrate : 1.0.1
cocoapods-plugins : 1.0.0
cocoapods-search : 1.0.0
cocoapods-stats : 1.0.0
cocoapods-trunk : 1.1.1
cocoapods-try : 1.1.0
source 'https://github.com/CocoaPods/Specs.git'
workspace './App.xcworkspace'
use_frameworks!
inhibit_all_warnings!
abstract_target 'App Core' do
pod 'LzmaSDK-ObjC'
pod 'Moya', '~> 8.0.0-beta.3'
target :'App Core macOS' do
project './App Core/App Core.xcodeproj'
platform :osx, '10.11'
target 'App Core macOSTests' do
inherit! :search_paths
end
end
target :'App Core iOS' do
project './App Core/App Core.xcodeproj'
platform :ios, '9.0'
target 'AppCore Core iOSTests' do
inherit! :search_paths
end
end
end
abstract_target 'App Apps' do
pod 'Fabric'
pod 'Crashlytics'
target :'App macOS' do
project './App macOS/App macOS.xcodeproj'
platform :osx, '10.11'
target 'App macOSTests' do
inherit! :search_paths
end
end
target :'App iOS' do
project './App iOS/App iOS.xcodeproj'
platform :ios, '9.0'
target 'App iOSTests' do
inherit! :search_paths
end
end
end
@vincedev can you provide a project that reproduces the issue? I have a general/vague idea of what's going on from your description but having a repro case would be super helpful for debugging and fixing. Thanks!
@benasher44 : Sure, please check out the zip file, which contains a minimal project to reproduce the issue.
CocoaPodsSample.zip
I have a general idea of what's going on here. There are a few frameworks issues that are related to this one. I'm going to try to fix them all at once, but it's going to take some time. In the meantime, you can work around this by making your core project a sub-project in your app project and then adding your core.framework as a dependency in your target dependency build phase. Does that make sense? This is a bit of a heavy work around (in terms of big changes you might not want to make to your project), but I believe it'll work.
@benasher44 : Thanks for the quick reply.
I gave a try to the workaround, but unfortunately it didn't fix the issue. Dependant frameworks still aren't copied into my core framework structure, and dynamic loader fails to load them at runtime.
What I did to work around this is add a build phase to the core framework build process, by copying the 'Embed Pods Frameworks' from the corresponding test target.
Did you pod install
again after you did my suggested workaround? That's important, but I forgot to mention it initially sorry
@benasher44 : Yes I did.
Confirming that @vincedev's workaround works, but it's only temporary, because you end up with nested frameworks so this shouldn't be a valid binary to submit to the AppStore.
On the Cocoapods 1.1.0 Release Notes it specifies that framework targets are supported, but no sample Podfile or xcodeproj
are posted to help us out.
How does this feature work?
Thanks a lot for your help!
@piercifani most cases that I was presented with during the 1.1.0 betas worked by having a project with an app target, and that project had a sub-project with a framework target. The framework target in the sub-project was then added as a target dependency in the Target Dependencies build phase of the app target. This scenario has been well-tested, but the scenario here shouldn't be difficult to support. I'm working on it, but it's slow going mostly because CocoaPods isn't my day job :)
@piercifani @vincedev is there a reason why the framework project can't be a sub-project of the app project in either of your cases? I've been working on trying to implement matching up a framework dependency across projects, but it's proving to be impossible. The UUID of the framework in the app project doesn't match the UUID of the framework target in the framework project. Because of this, it's not possible for CocoaPods to know where the framework target in the framework project is going to be embedded.
Hi @benasher44,
First of all, thanks for your time, really appreciate it!
Second of all: I have no issue doing just that; I guess what I need here is a way of _knowing what to do_ to make it work, since the release notes seem to include no examples on this feature.
What I think would be valuable for the CP community is a sample workspace setup of an App + Framework and a Podfile that links Pods to both the app and the framework, since this is the most common scenario.
Do you think that this would be useful?
@benasher44 what about if the framework is also dependant of another framework project ? Do you think it would work in that scenario ?
In our case we have workspace setup like that :
Cheers
@benasher44 : Retried the suggested workaround today to no avail.
I then tried it also on the sample project I gave you, with the same result.
Did you try it with the sample ? Did it work for you ?
It has worked for me and others. I'll put up a sample project to better illustrate in the next week.
Yeah, I don't think it's working correctly either.
I have followed your steps (I deintegrated Cocoapods from all xcodeproj
first), and now the project looks like this .
But still, the *-frameworks-.sh
script doesn't install any framework on the main target, making the app crash on launch.
Any ETAs on the sample project?
Thanks!
@piercifani @vincedev I finally got some time to put together a frameworks sample project. In doing this, I discovered that I definitely broke framework support when the framework target exists in another project (still needs to be a sub-project of the app project though). I have a fix in the works, and I plan on having a PR聽up today. I'm also going to try to get the sample project up today as well.
PR was posted yesterday. I've finished work on the sample project for dynamic frameworks this morning, and it's now posted here: https://github.com/benasher44/CocoaPodsLibExample
Thanks everyone for being patient here! I've been quite busy lately :)
@benasher44 , I forket your example to reproduce a case when a local framework project is dependant on another local framework project
Demo : https://github.com/dagio/CocoaPodsLibExample
In that case, SampleFramework is dependant of SampleFramework2. SampleFramework2 itself is dependant of an external framework : MDWamp
It looks like this :
And the Podfile looks like that :
platform :ios, '9.0'
use_frameworks!
workspace 'SampleApp.xcworkspace'
target 'SampleApp' do
project 'SampleApp.xcodeproj'
pod 'AFNetworking'
end
target 'SampleFramework' do
project 'SampleFramework/SampleFramework.xcodeproj'
pod 'CocoaLumberjack'
end
target 'SampleFramework2' do
project 'SampleFramework2/SampleFramework2.xcodeproj'
pod 'MDWamp'
end
When the app start, the dynamic loader can not find "CocoaAsyncSocket" (one of the dependencies of SampleFramework2) :
dyld: Library not loaded: @rpath/CocoaAsyncSocket.framework/CocoaAsyncSocket
Referenced from: /Users/damiengavard/Library/Developer/Xcode/DerivedData/SampleApp-dalejtiajrnfbyfeuyaqvunmoptd/Build/Products/Debug-iphonesimulator/SampleFramework2.framework/SampleFramework2
Reason: image not found
(lldb)
The copy framework step file (Pods-SampleApp-frameworks.sh) does not include these frameworks :
if [[ "$CONFIGURATION" == "Debug" ]]; then
install_framework "$BUILT_PRODUCTS_DIR/AFNetworking/AFNetworking.framework"
install_framework "$BUILT_PRODUCTS_DIR/CocoaLumberjack/CocoaLumberjack.framework"
fi
if [[ "$CONFIGURATION" == "Release" ]]; then
install_framework "$BUILT_PRODUCTS_DIR/AFNetworking/AFNetworking.framework"
install_framework "$BUILT_PRODUCTS_DIR/CocoaLumberjack/CocoaLumberjack.framework"
fi
@dagio thanks for bringing up this interesting scenario! Do you mind filing a new issue? I'll likely need to work on this scenario separately (handling frameworks from a sub-projoect that depend on a framework from another sub-project), since the fix for this issue is ready to go in soon.
@benasher44, I opened a new issues as you asked with all the details : #6245
Thanks @benasher44. Adding MyFramework.framework
as a Target Dependency of MyApp
was the key part for me that resolved the dyld: Library not loaded
error. To do this, I had to add MyFramework.project
as a sub-project of MyApp.project
like you suggested.
It's odd that this is required, to cause the Target Dependency picker to see the framework dependency; I would expect this to still work with both projects living at the top-level in the workspace. I wonder if there is a way to manually edit the App's project file's Target Dependencies section to point to a sibling project's framework target.
@JakeSc we (CocoaPods) can't otherwise know for sure that the framework in your project needs to be integrated into that specific target. In a more extreme case, if you had lots of targets and frameworks, this linkage is important so that CocoaPods doesn't make assumptions about how targets in your project depends on frameworks in your project.
Sorry for bringing up an older post, however I'm having a problem which is easily replicated with the CocoaPodsLibExample that you created @benasher44 . When adding certain pods to the podspec (such as pod 'GoogleSignIn'), I get:
Class GIDTokenFetchDelegate is implemented in both .../SampleFramework.framework/SampleFramework and ...SampleApp.app/SampleApp. One of the two will be used. Which one is undefined.
Note that this happens with other pods, I'm just using 'GoogleSignIn' as an example. I've posted a sample here:
CocoaPodsLibExample-master 2.zip
This is Cocoapods version 1.3.1. Could you help?
Most helpful comment
@piercifani @vincedev I finally got some time to put together a frameworks sample project. In doing this, I discovered that I definitely broke framework support when the framework target exists in another project (still needs to be a sub-project of the app project though). I have a fix in the works, and I plan on having a PR聽up today. I'm also going to try to get the sample project up today as well.