Kiwi and CocoaPods with a static shared library
Asked Answered
M

4

3

I have a workspace with 3 projects:

  • MyApp
  • Common
  • Pods

Common is a common library that MyApp depends on. I'd like to setup CocoaPods and Kiwi to work correctly in this project. How do I go about this?

I found https://mcmap.net/q/522202/-configuring-cocoapods-with-an-existing-static-library-and-ios-application, but when I try to follow this approach, I get an error when building MyApp before I even try adding Kiwi:

ld: library not found for -lPods

Here's the repo on GitHub: https://github.com/lyahdav/cocoapods_kiwi_shared_library

My Podfile is:

workspace 'MyApp.xcworkspace'
platform :ios, '7.0'

target 'Common' do
  xcodeproj 'Common/Common.xcodeproj'

  pod 'AFNetworking'
  pod 'Reachability'

  target 'MyApp', :exclusive => true do
    xcodeproj 'MyApp.xcodeproj'
  end
end
Motto answered 28/3, 2014 at 0:4 Comment(0)
M
2

I finally found a working solution for this. Here's the Podfile:

platform :ios, '7.0'

workspace 'MyApp.xcworkspace'

xcodeproj 'MyApp'

pod 'CupertinoYankee', '~> 1.0'

target :MyAppTests, :exclusive => true do
    pod 'Kiwi/XCTest'
end

target :Common, :exclusive => true do
    xcodeproj 'Common/Common'
    pod 'CupertinoYankee', '~> 1.0'
end

target :CommonTests, :exclusive => true do
    xcodeproj 'Common/Common'
    pod 'Kiwi/XCTest'
end

This example Podfile shows both MyApp and Common configured to use Kiwi for tests and they can both use pods (CupertinoYankee in this example).

I did manually have to configure in Xcode that MyApp links with Common with these steps:

  1. In MyApp project settings > MyApp target > Build Phases > Link Binary With Libraries > add libCommon.a
  2. In MyApp project settings > Build Settings > User Header Search Paths > add ${SRCROOT}/Common/Common/**

This repo has a working example: https://github.com/lyahdav/cocoapods_kiwi_shared_library

The only slightly annoying thing I didn't manage to figure out was if there's a way to not duplicate each pod that I want to use both in MyApp and Common. If anyone has a solution that does all of what my solution does and solves that, I'll gladly mark it the accepted answer.

Motto answered 19/5, 2014 at 0:47 Comment(0)
C
1

Posted as an edit by anonymous user. Here's his answer:


I have forked the repository and made few changes for new cocoapods versions to make it still working.

platform :ios, '8.0'

workspace 'MyApp.xcworkspace'

project 'MyApp'

target :MyApp do
    pod 'CupertinoYankee', '~> 1.0'
end

target :MyAppTests do
    pod 'Kiwi/XCTest'
end

target :Common do
    project 'Common/Common'
    pod 'CupertinoYankee', '~> 1.0'
end

target :CommonTests do
    project 'Common/Common'
    pod 'Kiwi/XCTest'
end

https://github.com/chrishunterkiller/cocoapods_kiwi_shared_library

Cistercian answered 28/3, 2014 at 0:5 Comment(0)
W
0

I'm not sure how to fix the setup you have, but if I were you I would make Common into its own Pod. Pods can be private and just stored in GitHub as a repo. Of course, you need a podspec for Common but I built a sample to test that setup for our build service and it took me less than 30 mins to get it right.

Then in your Podfile for MyApp, you do something like this:

pod 'Common', :git => '[email protected]:lyahdav/Common.git', :commit => 'a1b2c3d'

And AFNetworking and Reachability can be referenced in the podspec of Common (assuming that's the right dependency).

This setup also allows you to include Common in whatever other apps you're building without having to embed the code. Again, making assumptions about what you're trying to achieve, so add more detail to the question if that's not right.

Welcher answered 1/4, 2014 at 6:21 Comment(5)
The issue I have with this approach is it would mean the Common Pod would be in its own repo. This would mean I'd have two repos to maintain which seems like unnecessary overhead in my situation. Or is there a way to alleviate that? I want to be able to split apart the Common code mainly for separation of concerns and so I can TDD quicker on the Common library. Right now when I want to run a test related to the Common code, it has to build the entire project, which takes about 20 seconds each time because of its size. The Common code alone would build much quicker.Motto
You could make Common and MyApp both into child directories in a top-level directory for your repo and use the :path approach to referencing the Common pod, instead of :git (see @Rivera 's answer). That approach doesn't give you the benefit of isolating the Common codebase for use in other apps, but if that's not your objective, might be simpler. I lean towards smaller single-purpose repos, but it's just personal preference.Welcher
I'm trying the :path approach, but I'm stuck on how to create a Kiwi test suite for the Common project that I can run from the same Xcode workspace as MyApp. I tried creating a new project as part of the workspace that has a dependency on the Pods project and I tried writing tests there (using XTest for now) that exercise code in the Common project, but I get a linker error saying undefined symbols for the class I'm trying to use in my tests. Any idea how this bit should be set up?Motto
I would expect that the tests for Common would be in the Common project. Is there a reason not to do it that way? Any manipulation of the MyApp workspace to tell it about Common is breaking the isolation that you created by moving the Common stuff into a Pod and will likely result in a fragile config. I'm happy to jump on a chat if that will help instead of creating a huge comment thread.Welcher
Sorry for neglecting this for a while, I just posted an answer that solved my specific problem. I wanted the Common tests to be part of the Common project, but I wanted to be able to run them from the same Xcode workspace as MyApp. I achieved that in my solution (by switching to the Common scheme and running tests).Motto
S
0

You could hack a solution that may get broken again, or better yet as Common is your library, start using CocoaPods for your Common library as well.

It will show up as a local "Dvelopment Pod", which means that you can directly edit the library code as well.

To begin easily just create a Common.podspec at the root folder:

$ pod lib create Common

Then just edit the minimum required parameters, such as platform, source_files, requires_arc and dependency if any.

You can take a look at how your library looks as you change it (and compare it to what you had with your manually created Common library):

$ pod lib lint --no-clean Common.podspec

Finally remove the no-longer needed Common from your workspace and add this to your Podfile:

pod 'Common', :path => '../Relative/Path/To/CommonSources/'

It will take you no more than 30 minutes and you'll learn many things in the process.

Next you could take a look at making private pod repositories.

Sickness answered 4/4, 2014 at 1:5 Comment(2)
I'm liking this approach, except I'm not seeing how I'd create a separate Kiwi test suite for the Common library that I can run in the same Xcode workspace. I'm going to experiment with different solutions now, but do you have any ideas? Should there be a new test target in the Pods project? A new test project in my workspace?Motto
Most likely you'll need two projects and two Podfiles (and thus two accompanying Pods directories and two CocoaPods-generated Workplaces), one for your App, and one to test your Common library. If both projects had very close requirements then you could try to have a single project with two targets and juggle requirements in the Podfile like here: guides.cocoapods.org/syntax/podfile.html#target.Sickness

© 2022 - 2024 — McMap. All rights reserved.