Kiwi and CocoaPods with a static shared library - xcode

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://stackoverflow.com/a/16472563/62, 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

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:
In MyApp project settings > MyApp target > Build Phases > Link
Binary With Libraries > add libCommon.a
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.

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

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 => 'git#github.com: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.

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.

Related

React-native/iOS app: Module 'SquareInAppPaymentsSDK' not found, although it has been added to the project

For further information
I have posted this also in https://github.com/square/in-app-payments-react-native-plugin/issues/66#issuecomment-623619907 - you can find more details there.
The installation instructions of the package I am having problems with are in https://github.com/square/in-app-payments-react-native-plugin/blob/master/docs/get-started.md
Summarizing the problem
The problem I am having is that I have configured a react-native package (react-native-square-in-app-payments) in Xcode, but I am getting an error saying that 'module xxx not found'.
The question, is:
Why doesn't Xcode find the 'missing' module? What is not configured properly? Where should I look to check?
The error is the following
Module 'SquareInAppPaymentsSDK' not found
My podfile:
platform :ios, '11.0'
target 'myproject' do
use_frameworks!
pod 'React', :path => '../node_modules/react-native'
pod 'yoga', :path => '../node_modules/react-native/ReactCommon/yoga'
pod 'DoubleConversion', :podspec => '../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec'
pod 'glog', :podspec => '../node_modules/react-native/third-party-podspecs/glog.podspec'
pod 'Folly', :podspec => '../node_modules/react-native/third-party-podspecs/Folly.podspec'
pod 'RNSquareInAppPayments', :path => '../node_modules/react-native-square-in-app-payments'
post_install do |installer|
installer.pods_project.targets.each do |target|
if target.name == 'React'
target.remove_from_project
end
end
end
end
My project.pbxproj file (couldn't attach it here, but you can access it in github):
https://github.com/square/in-app-payments-react-native-plugin/issues/66#issuecomment-625333601
Update: Linking (following the 1st comment and #DenisTsoi answer) below
I tried automatic linking (as noted, I need it since I am using RN 0.59.9), and then I started again and tried manual linking, for both I have the same error. You can see my comments about this in https://github.com/square/in-app-payments-react-native-plugin/issues/66#issuecomment-625330210
BTW, under 'link binary with libraries' I have two entries of the package:
SquareInAppPaymentsSDK.framework (as requested in https://developer.squareup.com/docs/in-app-payments-sdk/installation#option-3-install-the-in-app-payments-sdk-manually)
libRNSquareInApppayments.a (part of linking)
Comment to #MuhammadNuman answer below:
I tried your podfile in a new react-native project (created by react-init). When I add
import { SQIPCore } from 'react-native-square-in-app-payments';
I get the error described in https://github.com/square/in-app-payments-react-native-plugin/issues/66#issuecomment-629762613
You may find my repo in https://github.com/rahamin1/square_with-podfile
I have faced this type of error in the past. Because some configuration things were missing or broken which leads these type of issues. So my suggestion for you is to create a new react-native project install all the library in the package.json one by one from the NPM or GitHub document of there library. and then copy the code from src (React Code) into the new project. If you have any changes inside the ios and android folder then only copy the changes from the file and paste to the file of the new project android/ios folder. (If nothing works then apply this solution. it always works for me)
According to your github issue link,
You’re running react 0.59.x. This means you’ll be required to run
react-native link
For native libraries to be linked in iOS XCode.
An alternative method is linking the dependency in XCode, which can be found on the react native docs
Excerpt
Step 1 If the library has native code, there must be an .xcodeproj
file inside its folder. Drag this file to your project on Xcode
(usually under the Libraries group on Xcode);

Step 2 Click on your main project file (the one that represents the
.xcodeproj) select Build Phases and drag the static library from the
Products folder inside the Library you are importing to Link Binary
With Libraries

Step 3 Not every library will need this step, what you need to
consider is: Do I need to know the contents of the library at compile
time? What that means is, are you using this library on the native
side or only in JavaScript? If you are only using it in JavaScript,
you are good to go! If you do need to call it from native, then we
need to know the library's headers. To achieve that you have to go to
your project's file, select Build Settings and search for Header
Search Paths. There you should include the path to your library. (This
documentation used to recommend using recursive, but this is no longer
recommended, as it can cause subtle build failures, especially with
CocoaPods.) 
For RN 0.60+ linking is done automatically.
Edit:
You can also install the SDK with cocoapods via the command in the directory <YOUR_PROJECT_DIRECTORY>/ios
pod install
You can also clone and test boilerplate for react-native 0.59.9
https://github.com/nomi9995/in-app-payments-0.59.9.git
change your podfile
platform :ios, '11.1'
target 'myproject' do
use_frameworks!
rn_path = '../node_modules/react-native'
pod 'React', path: rn_path, subspecs: [
'CxxBridge',
'RCTText',
'RCTNetwork',
'RCTWebSocket',
'RCTAnimation',
'RCTActionSheet',
'RCTGeolocation',
'RCTImage',
'RCTSettings',
'RCTVibration',
'RCTLinkingIOS'
]
pod 'yoga', :path => "#{rn_path}/ReactCommon/yoga"
pod 'DoubleConversion', :podspec => '../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec'
pod 'glog', :podspec => '../node_modules/react-native/third-party-podspecs/glog.podspec'
pod 'Folly', :podspec => '../node_modules/react-native/third-party-podspecs/Folly.podspec'
pod 'RNSquareInAppPayments', :path => '../node_modules/react-native-square-in-app-payments'
end
and install podfile againt
pod install

Is it possible to add a local dependency to .podspec file?

I'm using cocoapods now I would like to add a local pod dependency in my project, something like:
s.dependency = 'my pod', :path => ''
but I think is not possibile, some ideas?
I have faced with the same issue and after lot of googling and asking on the CocoaPods github I have finally found the suitable answer.
It's not possible to set a local pod as a dependency, but it's possible to set a pod's source for a specific Podfile, which will work the same way.
E.g., in your podspec, you still have ()
s.dependency = 'my pod', '~> 1.0' # or whatever version you have
Then in your Example/demo/test project's Podfile:
pod 'my pod', :path => '/path/to/the/local/my_pod'
Then just run pod install and you will see both pods as a Development pods.
This way is very useful when you're developing 2 pods (one of which is dependend on the other) simultaneously, yet for release you will still have to publish your pod to the repo (either CocoaPods or a private repo).
Put the local dependency inside your pod's folder root directory,
In your Podspec file, just add s.ios.dependency 'YourRootPodName/YourPodDependencyFolder'
After that, create a subspace like so:
s.subspec 'YourRootPodName' do |ss|
ss.source_files = 'YourRootPodName/**/*.{h,m}'
end
as in this answer Cocoa podspec and path for dependency

Migrating to CocoaPods 1.0.1

I am trying to migrate our existing CocoaPod configuration from 0.39.0 to 1.0.1.
Our existing Podfile looks like:
platform :ios, '9.0'
use_frameworks!
target 'Tools' do
pod 'zipzap', '~> 8.0.4'
pod 'Argo', '~> 2.2.0'
pod 'Curry', :git => 'https://github.com/thoughtbot/Curry.git', :commit => 'eeb459fac309833288e61e134a4e8fad649e99b0'
end
target 'ToolsTests' do
end
This compiled and the tests ran just fine previously. After following the migration guide. I restructured the Podfile like so:
platform :ios, '9.0'
target 'Tools' do
use_frameworks!
pod 'zipzap', '~> 8.0.4'
pod 'Argo', '~> 2.2.0'
pod 'Curry', :git => 'https://github.com/thoughtbot/Curry.git', :commit => 'eeb459fac309833288e61e134a4e8fad649e99b0'
target 'ToolsTests' do
inherit! :search_paths
end
end
This compiles and links just fine. Unfortunately when the tests run they crash with:
2016-06-07 12:04:06.265 xctest[56474:789900] The bundle “ToolsTests” couldn’t be loaded because it is damaged or missing necessary resources. Try reinstalling the bundle.
2016-06-07 12:04:06.299 xctest[56474:789900] (dlopen_preflight($HOME/Library/Developer/Xcode/DerivedData/Tools-dbmncsubtoarlhhcrpchrswefprz/Build/Intermediates/CodeCoverage/Products/Debug-iphonesimulator/ToolsTests.xctest/ToolsTests): Library not loaded: #rpath/Argo.framework/Argo
Referenced from: $HOME/Library/Developer/Xcode/DerivedData/Tools-dbmncsubtoarlhhcrpchrswefprz/Build/Intermediates/CodeCoverage/Products/Debug-iphonesimulator/ToolsTests.xctest/ToolsTests
Reason: image not found)
Program ended with exit code: 82
In the migration guide it says:
A large fraction of the bug reports we receive is due to ambiguity in the Podfile. It gave a lot of freedom to create all kinds of CocoaPods setups that would work by luck of implementation details, or work but are significantly more complex than they needed to be.
Is this one of those cases that used to "work by luck of implementation details"? If not what is the correct Podfile syntax?
I should note if I duplicate the pod defs in the ToolsTests everything works just fine. Though this feels wrong.
Similar question: Cocoapods testing linker error
Seems to be a common problem people are facing when upgrading. Your new Podfile looks right to me.
If you haven't already, I would try:
cleaning the build folder (in Xcode -> Option+Shift+Command+K)
clearing the derived data folder (rm -rf ~/Library/Developer/Xcode/DerivedData)
clearing your CocoaPods cache (rm -rf ~/Library/Caches/CocoaPods)
and run pod install again
EDIT:
The question I mentioned above has an answer now: https://stackoverflow.com/a/37705768/3067051

Cocoapods frameworks.sh error: no such file

So I'm fairly new at both Swift and working with cocoapods, and after spending several days of researching I cannot figure out why my project isn't building. I get the following error:
(My project)/Pods/Target Support Files/Pods-(My project)/Pods-(My project)-frameworks.sh: No such file or directory
I am using Xcode 7.2.1 and Cocoapods 0.39.0 and I seem to have tried all the troubleshooting tips from Cocoapods' website. Can anyone tell me what I need to do to make it work?
My podfile:
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.1'
use_frameworks!
pod 'GoogleMaps'
pod 'FontAwesome.swift'
pod 'Lock', '~> 1.21'
pod 'JWTDecode', '~> 1.0'
pod 'Lock-Facebook', '~> 2.1'
pod 'SimpleKeychain', '~> 0.7'
pod 'Bolts', '~> 1.6'
pod 'FBSDKCoreKit', '~> 4.1'
pod 'FBSDKLoginKit', '~> 4.1'
pod 'MBProgressHUD', '~> 0.9.2'
pod 'Alamofire', '~> 2.0'
pod 'CocoaLumberjack/Swift'
pod 'AFNetworking', '~> 2.5'
pod 'Auth0', '~> 0.2'
You're probably missing the target block for your target, in the Podfile.
I added a target to my project, and forgot to add a target block to the Podfile for that target, and I had the same error.
(My project)/Pods/Target Support Files/Pods-(My project)/Pods-(My project)-frameworks.sh: No such file or directory
The path components are actually named after the target:
(My project)/Pods/Target Support Files/Pods-[target]/Pods-[target]-frameworks.sh
Cocoapods builds configuration files for each target that you specify. Try adding a target entry to your Podfile, like so:
target "SOME TARGET" do
specify pods here
end
If you end up adding a lot of targets, it might be a good idea to define pod groups that you can easily use inside your target entries. So, you would define your groups above your target entries, like so:
def commonPods
specify pods here
end
Then you can use the group name in your pod entry, instead of copying all the pod entries for every target:
target "SOME TARGET" do
commonPods
end
Adding the target entry in your Podfile will cause CocoaPods to generate a new set of files the next time you run pod install. However, before you run that command, you will probably need to set your configurations to None, so that Cocoapods can assign its own configuration. Here's how to do that:
Go to your project-level target
For each configuration listed under Configurations, select None for your target, in the drop-down menu under Based on Configuration File.
These steps will eliminate the Cocoapods warning that reads:
CocoaPods did not set the base configuration of your project because your project already has a custom config set. In order for CocoaPods integration to work at all...
Once you've edited your Podfile and you nullified your configurations, you're ready to run pod install on the command line. After the process is completed, check back with your base configuration settings, and note that they have been set to the configuration file that was generated by CocoaPods!
I hope that helps!
This is kind of dumb, but it happened to me:
You might be in the wrong directory.
I was running pod install from directory Desktop/Project/Project Files, and I kept getting an error like this.
Then I realized I was in one step too far, so I went up to directory Desktop/Project, and it worked.
As to why pod install even ran considering the Podfile was in Desktop/Project and not Desktop/Project/Project Files... ¯\_(ツ)_/¯
My problem is that " blablabla Pods-XXXX-frameworks.sh: No such file or directory"
Firstly, I fix it by using command line "pod install" , it has nothing effection.
The finally solution :
Touch "Build Phases" -> "Embed Pods Frameworks" ,you can see the path :XXXXX.sh"
Be sure that the XXX.sh is the same as your project's. if not, change the path.
Then clean and build.
It's done.
Make sure that you are running pod install in the same directory where you have your xcode project.

Cocoapods - include certain dependencies only for XCTest files

I have the following Podfile:
platform :ios, '7.0'
pod 'CocoaLumberjack'
target :MyProjectTests do
pod 'OCHamcrest'
end
I want to include CocoaLumberjack in all targets and OCHamcrest only in the test target. This seems to work great when I was using GHUnit (as I had to create a specific GHUnit test target).
However, I thought I would try XCTest to see how I like it (given that GHUnit seems to be getting a few cobwebs and has changed ownership recently).
When I check my Pods.xconfig, it shows that it is including OCHamcrest
HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers" "${PODS_ROOT}/Headers/CocoaLumberjack" "${PODS_ROOT}/Headers/OCHamcrest"
So, it looks like XCTests are not a separate target.
What can I do to ensure that I'm not including testing frameworks in my release build? Is this something I have to manually manage or can Cocoapods do this for me?,
This should do the trick.
target :MyProjectTests, :exclusive => true do
pod 'OCHamcrest'
end
Source: http://guides.cocoapods.org/syntax/podfile.html#target

Resources