Assume I have a project, which includes a playground. I run pod install
on a Podfile like that:
use_frameworks!
pod "Alamofire"
target "MyApp"
I'd expect that I could successfully import Alamofire into my playground. This would have worked with the old scoping until 0.39, but broke with the 1.0 prereleases.
The framework isn't found, because pod targets are now scoped by default and playgrounds don't support to extend their framework search paths.
I see two actual possible solutions for this issue and not solving the issue as a possible alternative decision.
Only scope pod targets, if there are different conflicting pod variants, which would require that. (Note: Different pod variants per platform are not conflicting as the default configuration build dir is already scoped by platform.) But this might be easily overseen and doesn't really behave predictable for users. This will cause unnecessary confusion.
But having conflicting pod variants is in general fine, so warning on the installation, that there are dependencies, which can't be used in playgrounds doesn't seem to be appropriate. Informing isn't enough, because it wouldn't appear without verbose mode. Scanning the project directory for playgrounds and scanning all contained Swift files for their imports would happen to early and miss imports, which would be added after running pod install
.
Allow to declare the playground explicitly in the Podfile:
use_frameworks!
pod "Alamofire"
playground "MyApp.playground"
target "MyApp"
This would tell the analyzer to generate the Pod dependencies at least once unscoped. If necessary, pod targets can be duplicated.
This would make the behavior of pods in playgrounds explicit and predictable.
Using different pod variants for different playgrounds would lead to conflicts, which would have to fail the installation. e.g.
use_frameworks!
playground "Foo.playground" do
pod "BananaKit/PalmTree"
end
playground "Bar.playground" do
pod "BananaKit/Fruit"
end
This would require the following subtasks to be solved:
playground
declaration. This should work similar to target
, but wouldn't support any of the installer directives as inherit!
, use_frameworks!
etc.use_frameworks!(false)
for declared playgrounds.PlaygroundDefinition
(subclass of TargetDefinition
)We can build plugins, which helps to workaround this issue as https://github.com/neonichu/ThisCouldBeUsButYouPlaying. If the Xcode team should ever decide to support adding additional framework search paths or even xcconfigs for playgrounds, we could re-evaluate this discussion and utilize these new functionalities to treat playgrounds mostly like usual targets.
/c @neonichu
I like solution B a lot, but am wondering if there is ever a situation where the unscoped framework would take precedence over the scoped ones for the other targets. I'm assuming we can't really remove the unscoped directory from the search path. Have we investigated that scenario, yet?
Oh, that's an interesting thought you bring up there. That would definitely require further investigation.
One more theoretic idea to mitigate that would be to build umbrella frameworks for playgrounds, which contain all the other frameworks. But this would require submodule support in the Swift compiler and some advanced linker reexport wizardry.
After we found out that this is relevant to support IBDesignables for the Interface Builder as well, it might make sense to generalize this to an option, which can be specified via the install!
directive. e.g.
install! :unscoped => true
That could work independent from the existing option :deduplicate_targets
.
I'm a bit concerned with the UX of that. It's quite a way from seeing IBDesignable
not work to realizing the unscoped
option is the solution. I don't have a better solution, though :disappointed:
Yeah, I share your concerns here, but I don't see any better option, which would unify playgrounds and IBDesignable
. A blog post plus documentation in the guides around that topic could help a lot.
Yeah, I'm not really sure I even get what unscoped
means after reading this thread, explaining it to people without the context could be tough. Feels like:
abstract_target do
# using this
playground "path/To/Example.playground"
# or
support_iboutlets!
pod "Thingy"
end
feels more DSL-like / recognizable
At first look I thought that syntax proposed by @orta would be super inconsistent. But it still makes sense with my initial proposal B as we can use it to determine the platform.
I would though prefer to name it after the thing which should be supported: support_ibdesignable!
.
sure, makes sense
hello,
we recently upgraded to 1.0.0 and immediately started to experience the IBDeisgnable problem stated by many threads mentioned above. This issue has made IB unusable for us, a serious problem... is there a temporary workaround while the community searching for long term solution?
@connectdotz you should be able to use a similar approach to what is used inside https://github.com/neonichu/ThisCouldBeUsButYouPlaying as a workaround:
use_frameworks!
target 'DateToolsPlayground' do
pod 'DateTools'
end
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['CONFIGURATION_BUILD_DIR'] = '$PODS_CONFIGURATION_BUILD_DIR'
end
end
end
But keep in mind this can break integration if your project is in a non-trivial situation where you have multiple pod targets producing build products with the same name. Be careful in applying this workaround!
that worked. Thanks!
Confirming that workaround proposed by @neonichu works with IBDesignables, CP 1.0.1 and XCode 7.3. Thanks.
https://github.com/CocoaPods/CocoaPods/issues/5334#issuecomment-223444937 workaround fixes playground execution errors:
Playground execution failed: error: Couldn't lookup symbols:
__TMaC10MyFramework18MyClass
but cause many build warnings like:
ld: warning: directory not found for option '-F.../Build/Products/Debug-iphonesimulator/Bolts'
Any update on this issue? We encountered this error in our UI framework and were able to bypass it thanks to @neonichu workaround, but not having support for IBDesignables out of the box is worrying. Can we do anything to help?
Nothing from our side, you're welcome to take a stab at adding the DSL attributes mentioned above - feels pretty spec'd out
Hi,
Just a comment about the proposed workaround:
If you have pure 'resource bundle' targets, then these targets will not have a $PODS_CONFIGURATION_BUILD_DIR (because nothing it being built).
This means that the target installation will install to wrong directory - and the "_-resources.sh" script in Pods/Target Support/Pods-All-_/ will fail.
You can solve this by skipping the proposed workaround if the target is of type 'com.apple.product-type.bundle'.
So @neonichu 's workaround from above becomes:
post_install do |installer|
installer.pods_project.targets.each do |target|
next if target.product_type == "com.apple.product-type.bundle"
target.build_configurations.each do |config|
config.build_settings['CONFIGURATION_BUILD_DIR'] = '$PODS_CONFIGURATION_BUILD_DIR'
end
end
end
At work we use HockeySDK which adds bundle targets and cause the original workaround to fail.
We recently ran into a similar issue with IBDesignables "image not found" issues, and were able to work around the problem by adding FRAMEWORK_SEARCH_PATHS to the runpath search paths.
post_install do |installer|
installer.pods_project.build_configurations.each do |config|
config.build_settings['LD_RUNPATH_SEARCH_PATHS'] = [
'$(FRAMEWORK_SEARCH_PATHS)'
]
end
end
None of these workarounds work for me. 馃槥
Still getting Image not found
errors when trying to render IBDesignables that imports a module that uses a pod.
Update: I was able to work around this by explicitly adding '$BUILT_PRODUCTS_DIR/[Scoped Dependency Directory]'
for the dependency that couldn't be found. I hate this solution, but at least I can render designables again.
Example Podfile:
source 'https://github.com/CocoaPods/Specs.git'
use_frameworks!
pod 'XCGLogger', '~> 4.0.0'
abstract_target 'iOS' do
platform :ios, '10.0'
target 'MyiOSTarget' do
end
target 'Designables Target' do
end
end
abstract_target 'macOS' do
platform :osx, '10.10'
target 'MyMacTarget' do
end
end
...and my "Runpath Search Paths" setting for the "Designables Target" looks like this:
Is there a better way to fix this?
Guys please. We need a fix for this issue! Not a workaround!
It's been almost 6 months from the original report by @mrackwitz !!
Hi @gask - there's enough information here for you to take a stab at an implementation if it's a blocking issue for you. Remember this is a community project, no-one gets paid for working on it.
@paulz Warnings could be eliminated by modifying @neonichu snippet a bit:
post_install do |installer|
installer.pods_project.targets.each do |target|
# add this line
target.new_shell_script_build_phase.shell_script = "mkdir -p $PODS_CONFIGURATION_BUILD_DIR/#{target.name}"
target.build_configurations.each do |config|
config.build_settings['CONFIGURATION_BUILD_DIR'] = '$PODS_CONFIGURATION_BUILD_DIR'
end
end
end
Is there any update on this issue a year later? Any fix planned?
Hi @gask - there's enough information here for you to take a stab at an implementation if it's a blocking issue for you. Remember this is a community project, no-one gets paid for working on it.
Nothing's changed, you're welcome to take a look though
The problem has seemed to reappear with a vengeance in Xcode 8.3.2 using Cocoapods 1.2.1. None of the workarounds seems to work anymore, short of removing "@IBDesignable" from any custom UI components.
I get that this is a group of volunteers, but this issue really needs to be addressed. It's making it very difficult to keep using Cocoapods for any serious work. Thanks for your dedication and effort on this project, but this issue should be prioritized.
Respectfully @picciano, people work on problems that they are having at this point in the lifecycle of this project. CocoaPods is mature, stable and is used in millions of apps. If you're having problems with this issue, then it might be time to try contributing back to the project and help fix it for everyone?
I know I'm repeating myself on this thread, but this is how people start contributing.
I added what I think is a related issue on StackOverflow here, with a sample project. Not sure if it's exactly the same issue, or if this is an appropriate place to post this comment, but I tried some work-arounds mentioned in this thread with no luck.
@arifken 's solution worked for us, on cocoapods 1.2.1
Xcode 8.3.3
I have tried the workaround with LD_RUNPATH_SEARCH_PATHS and it worked really well.
Thank you @arifken
Link to comment with workaround:
https://github.com/CocoaPods/CocoaPods/issues/5334#issuecomment-255831772
Cocoapods 1.3.1, Xcode 8.3.3
IMO this workaround looks like a good fix to be implemented permanently.
P.S.
I have added next unless config.name == 'Debug'
to make sure that I don't ship binaries to users with patched LD_RUNPATH_SEARCH_PATHS
@neonichu 's fix worked for me. Fantastic - thank you :).
I'm writing a pod containing ibdesignables as well as pod dependencies and I'm running into the interface builder issue in this discussion when using the pod in apps. I would like to contribute towards fixing the problem, but don't really understand enough about the XCode build process (yet). Probably don't understand enough about how CocoaPods work either.
But I found that when I add this to my podspec the problem goes away:
s.pod_target_xcconfig = { 'LD_RUNPATH_SEARCH_PATHS' => '$(FRAMEWORK_SEARCH_PATHS)' }
The comments from @adc-amatosov here https://github.com/CocoaPods/CocoaPods/issues/5334#issuecomment-332990608 makes me wonder if this has some side-effects for production apps that I'm not aware of. I would be really happy if anyone could point me in the right direction to understanding this better.
We have enjoyed brief period of playground happiness while using CocoaPods 1.3.1.
All our frameworks built either in Swift or Objective-C or both worked nicely with playgrounds (we don't use IBDesignables).
Then we moved on to CocoaPods 1.5.0 and Xcode 9.2 and most of playgrounds no longer work.
We're often getting errors like this:
Playground execution failed:
error: Couldn't lookup symbols:
_OBJC_CLASS_$_ObcClassName
Where ObjCClassName
is Objective-c class implemented in the dependency framework, i.e. playground is in the same project as framework A
, and A
depends on B
, and ObjcClassName
is in B
, so it's a transient dependency.
I've tried all the workarounds mentioned in this thread, as well as sticking -ObjC
for LDFLAGS
everywhere it would make sense, but no luck.
I wonder what I'm missing. My issue is not about designables, but about CocoaPods and Playgrounds.
Maybe someone faced this issue with 1.5.0?
I'd appreciate any help, thanks.
@mgrebenets There's a regression in 1.5.0. I've opened an issue here, feel free to +1 it: https://github.com/CocoaPods/CocoaPods/issues/7689
I have added next unless config.name == 'Debug' to make sure that I don't ship binaries to users with patched LD_RUNPATH_SEARCH_PATHS
@adc-amatosov what exactly does this do. Should I add it?
@keronsen 's solution in conjuction with
post_install do |installer|
installer.pods_project.build_configurations.each do |config|
config.build_settings.delete('CODE_SIGNING_ALLOWED')
config.build_settings.delete('CODE_SIGNING_REQUIRED')
end
end
in our Podfile fixed the issue for us. But why?
Can anyone explain, what exactly is happening there?
@appleitung The post_install step is the only thing needed. Doesn't seem like LD_RUNPATH_SEARCH_PATHS adds any effect. See here:
https://github.com/CocoaPods/CocoaPods/issues/7689#issuecomment-384951495
@appleitung I've tried both post install fixes, individually and together, still getting the same error.
good
@appleitung Just that post_install was enought for me to get rid of the errors. Probably it just bypass code signing for each pod.
This was causing me huge issues, breaking my whole storyboard in the latest version of Xcode. Pod in question was MultiSlider. Adding the post_install from @appleitung fixed it for me. Can someone from the Cocoapods team explain what is going on here?
Interface Builder seems to require code signing when it builds frameworks to render their designable views, CocoaPods was force disabling code signing for Pod frameworks.
The 1.6.0.beta.2
release includes the change that matches the workaround, so if this is a blocker for you please try out the beta.
Seem like not only Cocoapods issue, but in general Xcode IB Designable issue.
I have my own dynamic framework target in the project that defines IBDesignable.
What fixed the issue for me was adding $FRAMEWORK_SEARCH_PATHS to LD_RUNPATH_SEARCH_PATHS
To make it safe for production I customize for Simulator only:
"LD_RUNPATH_SEARCH_PATHS[sdk=iphonesimulator*]" = "$(inherited) $FRAMEWORK_SEARCH_PATHS";
Git diff with come context:
DYLIB_INSTALL_NAME_BASE = "@rpath";
INFOPLIST_FILE = MyDynamicFrameworkTarget/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
+"LD_RUNPATH_SEARCH_PATHS[sdk=iphonesimulator*]" = "$(inherited) $FRAMEWORK_SEARCH_PATHS";
MODULEMAP_FILE = "$(PRODUCT_NAME:c99extidentifier)/$(PRODUCT_NAME:c99extidentifier).modulemap";
PRODUCT_BUNDLE_IDENTIFIER = "${MAIN_BUNDLE_ID}.$(PRODUCT_NAME:rfc1034identifier)";
Post install step (https://github.com/CocoaPods/CocoaPods/issues/5334#issuecomment-255831772) also did not work, as it only changes search paths for pods target.
I've tried using 1.6.0.rc1
and it did not fix the issue for me.
@mortenbekditlevsen answers solves for me, i create dummy single app, then add target, develop a framework. The framework itself use CocoaPods.
I didn't have this issue until i create new IBDesignables class and the storyboard in my framework starts to crash
@paulz is your modification to the Build Setting of the app that uses the pod that has the IBDesignable OR is your modification to the Build Setting of the Framework? I've been confused by where the paths need to be modified, in some solutions it appears it is needed In both :-/
I think I've run into this issue too, but worked around it in my case by moving the IBDesignable
classes into their own framework target which does not have any cocoapods-managed dependencies.
As @paulz mentioned,
Adding
s.pod_target_xcconfig = { 'LD_RUNPATH_SEARCH_PATHS[sdk=iphonesimulator*]' => '$(inherited) $FRAMEWORK_SEARCH_PATHS' }
to the .podspec
file did it for me and it shouldn't have any secondary effects when building for production.
Most helpful comment
@connectdotz you should be able to use a similar approach to what is used inside https://github.com/neonichu/ThisCouldBeUsButYouPlaying as a workaround:
But keep in mind this can break integration if your project is in a non-trivial situation where you have multiple pod targets producing build products with the same name. Be careful in applying this workaround!