13

NB: This is related to this question on project structure, but I have decided to a vastly the use-case to better abstract the problem.

Problem

How do I include in my iOS App and an accompanying iOS Extension (, or ) via CocoaPods?

Issues

  • For use in Extensions, AFNetworking needs to be build with #define AF_APP_EXTENSIONS, does this mean I need 2 versions AFNetworking? One for the Extension and one for the App?

  • How do I set up the Podfile so frameworks are built and copied to the correct places? Documentation on use_frameworks! is a bit thin.

Community
  • 1
  • 1
Richard Stelling
  • 25,607
  • 27
  • 108
  • 188
  • 1
    For people coming across this in the future: as of time of writing, AFNetworking seems to have fixed this in their latest versions, so try updating the pod before attempting the solutions below. – ftvs Mar 30 '16 at 08:37

3 Answers3

13

Update:

As Rhythmic Fistman mentioned the original answer's method gets overwritten when doing a new pod install.

Aelam provided the following method in this Github issue:

Add this to your podfile. remember to replace the target name

post_install do |installer_representation|
    installer_representation.project.targets.each do |target|
        if target.name == "Pods-YOU_EXTENSION_TARGET-AFNetworking"
            target.build_configurations.each do |config|
                    config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= ['$(inherited)', 'AF_APP_EXTENSIONS=1']
            end
        end
    end
end

Obsolete answer:

1) Be sure that pod 'AFNetworking' is included for both targets (your container app and extension) in your podfile.

Example in my case:

target 'ContainerAppTarget', :exclusive => true do
  pod "SDKThatInternallyUsesAFNetworking"
end

target 'ExtensionTarget', :exclusive => true do
   pod 'AFNetworking'
end

2) In XCode, click on Pods on the hierarchy view to bring its build options. Then on the build options, select the target for which you are looking at the build options in the dropdown. There select Pods-{Extension Target Name}-AFNetworking (it should have been created automatically by pod install. Then select Build Settings. Then under Apple LLVM 6.0 - Language, verify that Prefix header has a filename. That filename on my case was Target Support Files/Pods-{Extension Target Name}-AFNetworking/Pods-{Extension Target Name}-AFNetworking-prefix.pch. If it doesn't have such a filename or similar then add it.

3) Go to that prefix header file that was named there or you added there. It'll be almost empty, then add the following line at the end:

#define AF_APP_EXTENSIONS

That should allow your container app to point to a version of AFNetworking built normally and your extension app to another built with the flag set. So only one version of the library but built in two different ways, each on one of the targets.

justinsAccount
  • 742
  • 1
  • 10
  • 10
  • 4
    That pch file is regenerated every time you do a pod install, which wipes out your modification. – Rhythmic Fistman Apr 01 '15 at 03:17
  • You're my god damn hero. – Mike May 29 '15 at 14:12
  • I received this issue while installing cocoapods [!] Unable to find a specification for `SDKThatInternallyUsesAFNetworking` am I supposed to replace SDKThatInternallyUsesAFNetworking with something else?? – Geet Aug 04 '15 at 06:29
  • @Geet `SDKThatInternallyUsesAFNetworking` is just an example name for a pod which internally uses AFNetworking. There is no pos by that name – ZeMoon Aug 14 '15 at 12:09
  • Its still giving error in my today's extension while importing AFNetworking. #import – kidsid49 Feb 24 '16 at 22:25
9

For newcomers to this post, things have changed a little.

I spent a fair amount of time hitting my head against a wall, hopefully this will spare some of you from that same fate.

Cocoapods changed so that it now only generates one library per pod, so in order to properly set the AF_APP_EXTENSIONS macro, it actually needs to be set in the AFNetworking target, not your extension's target.

For example (with some pretty log statements):

post_install do |installer_representation|
    installer_representation.pods_project.targets.each do |target|
        puts "=== #{target.name}"
        if target.name == "AFNetworking"
            puts "Setting AFNetworking Macro AF_APP_EXTENSIONS so that it doesn't use UIApplication in extension."
            target.build_configurations.each do |config|
                puts "Setting AF_APP_EXTENSIONS macro in config: #{config}"
                config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= ['$(inherited)', 'AF_APP_EXTENSIONS=1']
            end
        end
    end
end

Also worth noting the pods_project in installer_representation.pods_project.targets.each do |target|

Cocoapods has deprecated project and it has been changed to pods_project

The one somewhat downside to this is that AFNetworking won't use any UIApplication APIs in the container app either, but that was a non-issue in my project.

Hope this helps.

julianwyz
  • 3,104
  • 1
  • 29
  • 34
  • Newcomer indeed. Searched all around for the solution till I came by this post. Thanks for this update! – ZeMoon Aug 14 '15 at 12:54
  • No problem! Glad it helped! – julianwyz Aug 14 '15 at 13:07
  • I wouldn't have got this working even if I banged my head against the wall numerous times. It worked great, Thanks! – Anuj Rajput Aug 17 '15 at 10:26
  • 1
    `"The one somewhat downside to this is that AFNetworking won't use any UIApplication APIs in the container app either, but that was a non-issue in my project."` so then this doesn't answer the original question then. – thisiscrazy4 Oct 28 '15 at 15:21
  • 1
    The original question was "How do I include afnetworking in my iOS App and an accompanying iOS Extension (ios8-extention, ios8-today-widget or ios8-share-extension) via CocoaPods?" I believe my answer addresses that question. That being said, the only UIApplication API that AFNetworking uses is ```setNetworkActivityIndicatorVisible:``` so if you do want to include that, it is easy enough to add ```[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];``` when loading starts and ```[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];``` on completion. – julianwyz Oct 28 '15 at 18:18
  • Its still giving error in my today's extension while importing AFNetworking. #import – kidsid49 Feb 24 '16 at 22:33
  • @wyzkid207 I am running the same issue when using `DTCoreText` in the Container app and share extension. I tried your solution, but the error are still here. Should the target name in `if target.name ==" "` conform to some rules? My share extension target name is `LiAi-Share`, I have tried `if target.name == "LiAi-Share"`, `if target.name == "Pods-LiAi-Share"` and `if target.name == "Pods-LiAi-Share-DTCoreText"`, but none works. – Cokile Ceoi Oct 07 '16 at 08:57
0

Updating your pod to at least version 2.6 can solve this. See the requirements table at: https://github.com/AFNetworking/AFNetworking

David T
  • 2,724
  • 1
  • 17
  • 27