Custom cocoapods xcodeproj file - ios

By default a CocoaPods installation makes Pods/Pods.xcodeproj. Is there a way I can set it to be called something else, like Pods/MyCustomPods.xcodeproj?
The scenario is that I have a workspace that contains multiple projects in multiple directories, and two of the projects there use CocoaPods. And not only would it then be confusing with two projects named Pods, but Xcode can't cope well with that and confuses the two projects.
Cheers
Nik

The approach with multiple Pods projects was incorrect. In this case, rather make a .xcorkspace and then point your Podfile at it
workspace 'MyCustom.xcworkspace'
then in each of your targets, point at the respective .xcodeproj:
target 'A' do
xcodeproj 'A.xcodeproj'
pod 'SamplePod'
end
target 'B' do
xcodeproj 'B.xcodeproj'
pod 'SamplePod'
pod 'OtherPod'
end
This works really well :-)

Related

Multiple commands produce frameworks issue (related to usage of cocoapod)

I have two frameworks 'GeneralABC' and 'GeneralXYZ'. Both of them have the same interface but different business logic. I define their module_name in podspec as General, so that other projects using my framework only need to define which General framework(GeneralABC or GeneralXYZ) they want to use in their Podfile, without changing their codes. (i.e. in their code file, they can always say import General)
In my example project, i have two targets, each target using different General framework. My Podfile is as follows:
target 'Example_ABC' do
pod 'GeneralABC'
end
target 'Example_XYZ' do
pod 'GeneralXYZ'
end
however when i try to build one of my target in xcode, I have got the following error
message
Multiple commands produce '/MYPATH/General.framework':
1) Target 'GeneralABC' has create directory command with output 'MYPATH/General.framework'
2) Target 'GeneralXYZ' has create directory command with output 'MYPATH/General.framework'
Multiple commands produce '/MYPATH/General.framework':
1)Target 'GeneralABC' has link command with output 'MYPATH/General.framework'
2)Target 'GeneralXYZ' has link command with output 'MYPATH/General.framework'
It can be solved by two approaches:
changing the workspace settings to legacy build system. however I don't think it is a solution in the future.
remove one of the target in the Podfile, and pod update every time we build the target. however, it is not so nice for maintenance and our build process.
is there any solution that i can manipulate my Podfile, so that i can fix the issue?
I appreciate very much of any suggestions.
Thank you for your attention!
I cannot find the exact solution that I want (1 pod file maintain all the targets). However, after some discussions with our teammates. we come up another kind of solution, so that we don't have to worry about the deprecated legacy build system.
solution are as follows:
create 2 podfile (i.e. 1 for target 'Example_ABC' the other for 'Example_XYZ')
create 2 workspace file (i.e. 1 for target 'Example_ABC' the other for 'Example_XYZ')
a mini shell script, that link the Podfile_ABC or Podfile_XYZ, when do the pod install/update/deintegrate

CocoaPods: How can I have multiple workspaces reference the same pods

I have several Xcode workspaces, each containing several projects. The projects in these workspaces are related and need to reference several of the same CocoaPods.
I want to create a single common directory into which I can download one copy of each pod I use, but I can't figure out how to set up the podfile so that it does treats each workspace independently. What happens is that when two workspaces are named, the second one gets both non-pod projects.
To simplify things, I created two simple projects, FooProject and BarProject, each contained in its own workspace (FooWorkspace and BarWorkspace). For clarity, my directory structure looks like this:
+ Common
- Podfile
- Podfile.lock
+ Pods
+ Workspace1
- FooProject.xcodeproj
- FooWorkspace.xcworkspace
+ Workspace2
- BarProject.xcodeproj
- BarWorkspace.xcworkspace
Here's my podfile:
# Uncomment this line to define a global platform for your project
platform :ios, '8.0'
def common_pods
pod "ConsoleBanner"
end
target 'FooProject' do
project '../Workspace1/FooProject.xcodeproj'
workspace '../Workspace1/FooWorkspace.xcworkspace'
common_pods
end
target 'BarProject' do
project '../Workspace2/BarProject.xcodeproj'
workspace '../Workspace2/BarWorkspace.xcworkspace'
common_pods
end
This almost does the trick. It downloads the pod only one time and puts it in the shared directory below this file. The only problem is that it updates BarWorkspace to include not only BarProject and the Pods project, but also FooProject. The first project/workspace referenced in the podfile works properly.
I tried adding inherit! :none within the target blocks, but it didn't have any effect. I also considered creating separate podfiles as peers in the same directory, but it seems that podfile has to be named, exactly, podfile.
How can I have the projects from separate workspaces reference the same podfiles?
I'm going to answer my own question based on my research efforts over the last few days. Hopefully this is useful to someone else at some point.
It doesn't seem that you can create a podfile that applies to multiple workspaces. But the more I think about it, maybe this is the way it should be.
One podfile maps to a collection of pods. Each pod has a specific version number. Presumably, different projects you might work on could require different versions of the same pods. For example, suppose Project 1 uses Pod X, version 3.0. But Project 2, because of legacy requirements, cannot use version 3.0 of Pod X but instead must use version 2.0.
In this case, you would need two different podfiles, each pointing to totally distinct collections of pods.
If you have a collection of projects that are so tightly linked that you can guarantee that they all use exactly the same versions of each pod they depend on, then maybe it makes sense to put those projects all together into a single workspace. That's what I ended up doing.
I may be wrong about some of these details, and I would welcome corrections if so. I hope this writeup is useful for others getting started with CocoaPods.

Xcode 7.3 Syntax Highlighting and Code Completion issues with Swift

I am having an extremely frustrating issue with XCode 7.3 (however, this issue has persisted since I installed XCode 7.2) and Swift code, and I am hoping others have had this issue and know how to resolve it. Syntax highlighting and code completion work perfectly fine in Objective-C files, and also works fine when calling other Swift objects within Swift code. However, any Objective-C objects or methods mentioned in Swift code get no syntax highlighting, and XCode will not complete ANY Objective-C declared methods or properties. Everything compiles and runs just fine.
I should also add that I have also tried doing a completely clean install of XCode. I deleted all my derived data, deleted all XCode caches, and deleted my XCode preferences files (in addition to obviously deleting the XCode.app archive before re-installing).
It is making it extremely difficult to develop in Swift. I don't want to do this, but if I can't find a way to resolve this I'll be forced to go back to using Objective-C.
I have the same problem. But finally solved it.
I make two change, not sure which is the key point but you can try them all.
delete the module cache
Within the same folder as your project's Derived Data is a Module
Cache. When Code Completion stopped working, deleting this fixed it.
Close Xcode and delete the
~/Library/Developer/Xcode/DerivedData/ModuleCache directory.
change the Enable Modules value
Go to the Build Settings of your target, then search Enable
Modules
If it's Yes, change it to No, and you may get some build
error, just change it back to Yes.
After two steps above you should Clean(Shift+Command+K) your project.
For now you may fixed the problem.
So it seems the issue was with CocoaPods. I was using Cocoapods as a static library instead of as frameworks. Switching to frameworks (using use_frameworks! in my Podfile) and importing the libraries into Swift has resolved all my issues. I'm guessing all those third party library headers were just too much for XCode to process. Either way, the issue is now resolved. I hope this helps someone in the future.
This might not be necessary anymore but i still want to post this:
At the time of this post, the most recent version of cocoapods (1.0.0.beta.8) requires you to define pods for each Xcode target.
In my case I had a class compile for the project target and for a testing target. I added a pod only to the main target, because of laziness.
Now working in the code of class A I added the pod framework using import NAME and tried to use the classes of the framework. Xcode wouldn't highlight the particular code where I use the new classes, but compiling and running works fine. In the completion dialog the type of the variable was <<error type>>
The way to resolve this issue: in the Podfile add the newly added pod to all targets, the class A is member of.
Now Xcode finds the necessary frameworks for all targets and code highlighting works again.
EDIT 1:
A possible solution is defining a list of shared pods, like in my example:
platform :ios, '8.4'
use_frameworks!
inhibit_all_warnings!
def all_pods
pod 'MPMessagePack'
pod 'SwiftyDispatch'
pod 'BFKit'
pod 'Timepiece'
pod 'Alamofire'
pod 'AlamofireSwiftyJSON'
end
def testing_pods
pod 'Quick'
pod 'Nimble'
end
target 'App' do
all_pods
end
target 'AppLogicTests' do
all_pods
testing_pods
end
target 'AppUITests' do
pod 'RxTest'
all_pods
testing_pods
end
post_install do |installer|
installer.pods_project.targets.each do |target|
puts target.name
end
end
This will add all pods to all targets and adding all testing pods to the targets. Next to these I added 'RxTest' to the AppUITests.
(Chosen pods are examples of my projects, no advertising intended :-) )
We had the same issue in a mixed ObjC/Swift project. Tried all the suggestions about deleting derived data etc, to no avail. Sometimes it helped, but not in a reproducible way and after some time it stopped working.
The post of Galvin in this post put me on the track of the Module related build settings. However it was another setting that solved the code completion/coloring in a reproducible way: setting DEFINES_MODULE (under Packaging) from YES to NO for our main project was the solution.
Notes:
I expected this to break the ObjC/Swift interoperability in our project, but that still works. It seems that setting is only to be used for framework targets. (https://developer.apple.com/library/ios/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.html)
This project setting has not been changed for months, but the code completion issues came up only recently, both for my colleague and me.
If none of the above worked for you and you're using Cocoapods, you can try switching to Carthage.
I tried every suggestion I could find on Google to no avail. But consistently Cocoapods seemed to be coming up as a reason with many hacks in attempt to fix it. I have been reading up on Carthage, and how it doesn't modify your project, force you to use a workspace, or potentially fill your build folder with header files (which confuses Xcode and can cause the syntax highlighting and autocomplete to break).
After making the switch I haven't run into any issues yet, and to be honest I prefer the teensy bit of overhead to have a clean solution. This post really drove it home for me.

ObjC: Statics are not consistent across multiple frameworks when contained in cocoapod

So my situation specifically uses the Objection dependency injection library. However, I believe this could be an issue for other libraries as well.
Platform
iOS 8.0 Xcode 6.1.1. Cocoapods 0.35. Objective-C.
Set up:
I have 4 projects. 3 universal frameworks and a test app (I'm creating an api). The test app does not utilize cocoapods (though some other app might).
All three of my frameworks need to use injection. I created a pod file that looks like
workspace 'workspace.xcworkspace'
platform :ios, '8.0'
xcodeproj 'path/to/proj/one'
xcodeproj 'path/to/proj/two'
xcodeproj 'path/to/proj/three'
target :Project1 do
pod 'Objection', '1.4'
end
target :Project2 do
pod 'Objection', '1.4'
end
target :Project3 do
pod 'Objection', '1.4'
pod 'SDWebImage', '~>3.7.1'
end
Problem
When I use this set up singletons don't work in Objection. However, they only don't work if they (the singleton class) is defined in project 1 and then I call [JSObjection createInjector]; in project 2 (the projects don't make a difference, it is that create is called in a different project to the definition).
Current theory
After battling with this for a while I believe it is due to the warning along the lines of:
Objection is defined in Project 1, Project 2 and Project 3.
Which one will be used undefined.
So when the class registers itself with the injection system (e.g through objection_register_singleton(ClassX)). It is using the JSObjection definition from its project, which might not be the one being used for a class that injects it (e.g. objection_requires_sel(#selector(myClassXObject))).
Question
I want to be able to use the iOS frameworks setup as, from what I understand, it is better overall than static libs. However, I also want to be able to use Cocoapods (and have any app, that uses my api, use Cocoapods).
How do I either a) share one definition across multiple frameworks or b) setup a framework as a Cocoapod (I've seen that this is being developed).
I would love to be able to keep the frameworks linked through the xcode workspace so when one is built the frameworks it depends on are also built. Though having said that, my api will probably become a Cocoapod at some point anyway.
Thanks in advance (and for reading to here)
Indigo

Building a static library with cocoapods

I am trying to build a static library that has different dependencies (AFNetworking for example) specified in a Podfile. I don't want the dependencies to be included in the final static library (call libMyProject.a), I just want to link against them and then create a MyProject.Podspec file where I can put the same dependencies.
The problem is that when I build libMyProject.a the libPods.a is linked and included, so that if I distribute libMyProject.a and other people integrates it in a project which uses some of the same dependencies it will have duplicate symbols issues.
How can I link against the libPods.a lib but not include it in libMyProject.a? It should work just like linking with other existing frameworks.
Thanks!
I solved it by removing the libPods.a lib from the section "Link Binary With Libraries" in Build Phases.
Whilst manually removing the libPods.a from the "Link Binary with Libraries" build phase does indeed work, the real answer is to not let it get added there in the first place.
The reason it is added is because the pod install command is finding the static library target as one of its targets to link with. This could be because it is the first target in the list (cocoapods' implementation causes it to pick the first one if you haven't explicitly specified targets) or it could be because you have explicitly stated it in the 'link_with' section.
The answer I find is to use the link_with section of the Podfile to explicitly state your targets, and omit the static library target.
The pods project is still created, and your dependencies brought into there as you'd expect, but the libPods.a isn't added to the build phase of your static library.
The only problem is what to put into the link_with section, if not your static library. If you have other targets that you do want to link with (an iPhone app target for instance) that's a good choice. But if your only real target is your static library, you need a little workaround.
My successful strategy so far has been to create a static library target (yes, a separate one from your main static library) and call it "Dummy". Specify this target in your Podfile's link_with section.
It is a little distasteful, granted, but it does work.
platform :ios, '5.1.1'
link_with ['Dummy']
pod 'AFNetworking', '= 1.3.1'
Referenced libraries are not (by default) included in the static library product. The linker conflict you're seeing is more likely the result of both your static library and the client app both using the default (implicit) Pod target.
Every Cocoapods-generated target includes a "Pods-target-dummy.m" file that is compiled into the product; if you use the default Pods target, it's just called "Pods-dummy.m". When both the library and client use the default target, the identical symbols produced from compiling the dummy files will cause a link error.
I tried a variation of Craig's answer myself, and found that the link_with statement is also responsible for hooking up the xcconfig generated by Cocoapods, which provides the compiler flags that control the header search path. You can add the xcconfig (or the header search path project settings) manually, of course, but I went looking for a repeatable solution for my team.
My solution is to create an explicit target for the library, with a name that is unlikely to cause conflicts with a client project (for example, the name of the library):
target 'XYZLibrary' do
pod 'AFNetworking', '2.5.2'
...
end
You can include a link_with statement within the target block if the name of the static library target (in your Xcode project) is different, but if there's only one target, I usually prefer to use the same name in both places, making link_with unnecessary.
If you have a unit test target, create two separate targets. (I currently def a set of common pods that are used in both targets, since abstract targets are not currently an option, but they may be one day.) It looks like this:
def common_pods
pod 'AFNetworking', '2.5.2'
end
target 'XYZLibrary' do
common_pods
end
target 'XYZLibraryTests' do
common_pods
end
The key is to not have any pod elements in the root of the Podfile, so that Cocoapods won't generate a default target. That way, each product gets a unique "Pods-target-dummy.m", and there's no conflict when those object files are linked together.

Resources