-
Notifications
You must be signed in to change notification settings - Fork 2.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow target-type specific podspec definitions #5373
Comments
I think we need a proposal on how this would work in practice to be able to evaluate it (but I'm leaning towards this is a massive undertaking for practically no benefit) |
IMO, we already have a solution to this problem with subspecs. A pod which has a subset of functionality that works within an app extension should separate that out into one. |
I disagree, @neonichu. I don't think subspecs are suitable for this particular issue. I can already give you two real world examples: https://github.com/SVProgressHUD/SVProgressHUD Two things have to happen in order to use these pods in a project with app extensions:
You can't just "outsource" functionality to subspecs, because they're part of the main functionality. I don't think that this is a "design flaw" by the creators of these pods. It's just the way to develop more complex applications that are using app extensions. I think @mrackwitz's solution is clever and it would help tremendously for these kinds of projects. |
@MuscleRumble This can also be solved by providing a subspec, though. If we take the s.subspec 'AppExtension' do |ap|
ap.source_files = …
ap.pod_target_xcconfig = { 'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GTM_BACKGROUND_TASK_FETCHING=0' }
end and in your Podfile you'd do: target 'App' do
pod 'GTMSessionFetcher'
end
target 'Extension' do
pod 'GTMSessionFetcher/AppExtension'
end Two distinct Pod targets would be generated and the files which are part of the |
Then you would have to duplicate code for In this example, you would have to copy If you wouldn't do that, you'll get compile-time errors. The easiest way is to deactive target deduplication for this pod. |
I don't think I understand what you're saying. There's nothing to copy, except for the definition of the list of files in the podspec, if it happens to be exactly the same as for another subspec. If that happens, it can be extracted out, since the podspec is just Ruby code. No actual source code has to be duplicated and targets will be |
What @neonichu proposes here makes sense. It might be not obvious though, but subspecs allow already to apply these sorts of variations to a podspec. They are way more powerful than just adding additional files, which made it already a massive undertaking to support them correctly with target deduplication. Given that we already have a way to express that, I'd be in favor of avoiding further complexity as @segiddins already suggested. Instead a tutorial or guide around that topic would be likely very helpful. |
Aye, I'm also on the side of "this is what subspecs are for."
Would be nice to have a blog post that just explores subspecs, and some interesting uses cases ( e.g. AFNetworking, ARAnalytics, RestKit ) ( we use them for code / dependency organization in Artsy for example ) |
I think I understand now how subspecs can be utilized for my use case. The thing is: There aren't a lot of frameworks/libraries that deal with app extensions properly. That's why I'm so frustrated and I have to fork/patch everything. I'll give subspecs a try, but I have two questions:
|
That's true, I don't think many podspec authors have realised that they could support application extensions quite nicely using this approach. If we do a blog post / guide and you have implemented the approach in some Pod(s), we could add that as an example and spread that knowledge this way. To the questions:
s.subspec "AppExtension" do |oda|
oda.dependency 'ADALiOS/AppExtension', '~> 1.2'
end |
The real answer is to use |
@segiddins that only works for marking symbols, though, doesn't it? Many Pods seem to have conditional code depending on their use within an application extension. |
Alright, thanks @neonichu! I'll give it a try in the near future. Subspecs seem to be the way to go! 👍 |
Hi Folks - any chance of that blog post explaining how this would work? |
Hey @ConfusedVorlon, might be a little late, but I recently encountered the issue and had to fix it by using @neonichu 's suggestion. I've written the reasoning and example in my blog (here) if you're interested. |
Just wanted to follow-up that I can confirm it's all working out with subspecs. Yes, I waited over half a year to do the change, because I couldn't use 1.0.0.beta.3 anymore. 😂 It wasn't pretty, I had to fork 7 projects and customize the podspecs, which will probably break my neck in the future, because of poor maintainability. But it wasn't pretty to begin with, so I guess it's just the way it is with App Extensions. Nevertheless, I think this issue can be closed, because we found a solution. 😄 Thanks again! |
I just can't make the proposed subspec approach work (share a subset of functionality through a subspec for an extension). I always get the famous "target has frameworks with conflicting names" error. I reproduced the proposed approach with a simple demo. I have a private framework with two subspecs:
Here's the podspec: Pod::Spec.new do |s|
s.name = 'MyFramework'
s.version = '0.1.0'
s.summary = 'Dummy Framework'
s.homepage = 'https://github.com/zierka'
s.license = 'MIT'
s.author = {'Zier Erik' => 'erik.interwebz@gmail.com'}
s.source = {:git => 'git@github.com:zierka/subspec-error-example.git', :tag => s.version.to_s}
s.requires_arc = true
s.platform = :ios
s.ios.deployment_target = '10.0'
s.default_subspecs = 'App'
s.subspec 'App' do |app|
app.source_files = [
'App/**/*.{swift}'
]
end
s.subspec 'Extension' do |ext|
ext.source_files = [
'App/CoreClass.swift',
'Extension/**/*.{swift}'
]
ext.exclude_files = [
'App/AppClass.swift'
]
end
end I have a simple xcode project, with 2 targets:
Here's the platform :ios, '10.0'
use_frameworks!
target 'SubspecProblemExample' do
pod 'MyFramework', :path => "../MyFramework" . # equal to MyFramework/App as that's declared for default_subspecs
end
target 'todayWidget' do
pod 'MyFramework/Extension', :path => "../MyFramework"
end Running Eriks-Machine:SubspecProblemExample erik$ pod install
Analyzing dependencies
Fetching podspec for `MyFramework` from `../MyFramework`
Downloading dependencies
Installing MyFramework (0.1.0)
[!] The 'Pods-SubspecProblemExample' target has frameworks with conflicting names: myframework. I read through all the issues about this error, and it's still not clear to me what the real problem is, because this is the same setup as previously described, and it's presented as a working solution and further confirmed. Am I missing something here? I uploaded the full demo project here: https://github.com/zierka/subspec-error-example Any help is greatly appreciated! |
There hasn't been any activity on this issue recently. Due to the high number of incoming GitHub notifications, we have to clean some of the old issues, as many of them have already been resolved with the latest updates. |
This issue will be auto-closed because there hasn't been any activity for a few months. Feel free to open a new one if you still experience this problem 👍 |
That is what need, thank you @neonichu neonichu |
CocoaPods target deduplication can be undesirable in some cases, when pods are used, which offer an extended API for targets, which are not limited to the extension API. In these cases, it would be desirable to use the full podspec in the app and only the limited features in the extension. This can be achieved in podspec with preprocessor conditionals, which require the presence of macros. A post_install hook would be required to define these macros for the pod targets.
The following could be a better solution to that: We could allow to specify attributes specific to iOS extensions in podspecs. This could look like that:
The analyzer could use that relatively easy as indication, that a pod can't be deduplicated across iOS apps and extensions. This could be used as well on tvOS.
This was created based on what I proposed in #5343 (comment).
/c @segiddins @neonichu @MuscleRumble
The text was updated successfully, but these errors were encountered: