cocoapods pod lib create and schemes - ios

I am using the latest beta cocoapods release that support frameworks with xcode 6.1.1, sudo gem install cocoapods --prerelease
I then ran pod lib create podtry to create a sample app, no demo app, no testing framework, no view based testing. I then opened it in xcode and notice that it created 3 schemes, pods-podtry, pods-podtry-podtry-podtry, podtry-Example and 2 Pods targets, Pods-podtry, Pods-podtry-podtry-podtry. Can someone explain why there are 2 targets and 3 schemes? It seems like ony Pods-podtry-podtry-podtry target contains the plist.info version specified in podspec s.version field.

Ok I think I figured this out, hopefully this will help someone new to cocoapods. There are 2 targets and each of the scheme has one of the 2 targets. For example, podtry-Example scheme has Pods-podtry target plus testaction has podtry test added. Pods-podtry-podtry-podtry scheme has Pods-podtry-podtry-podtry target but no test action. Pods-podtry scheme has Pods-podtry target, no test action but has a target dependency on Pods-podtry-podtry-podtry. Phew that's a mouthful but there it is.
There are a couple of things I still don't quite get though
Why did cocoapods create Pods-podtry target that builds a Pods_podtry.framework in addition to podtry.framework. Ultimately I am only interested in podtry.framework and I am not sure about the purpose of Pods_podtry.framework.
Why did cocoapods not create a test target like xcode normally does for a new project, instead it make that a test action target dependency.
Any insights will be much appreciated.

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

Swift Build Error - No such module 'Feature1'

I am getting compile error when I added a framework into my app. Framework Feature1 is built successfully but from module App import is not working.
How to solve this issue?
There are several potential misconfigurations the issue can arise for,
Please confirm that you have opened the .xcworkspace but not .xcodeproj file. Also make sure you have build Feature1 first before you build App.
Make sure that iOS Deployment Target is set same for all modules with App. For example is Apps deployment target is set to 9.0, Feature1s deployment target also need to be set to 9.0.
Make sure your main module (App) and your used framework (Feature1) have same set of configurations. i.e. If your Project has three configurations, Debug, Release, ReleasePremium than your Framework also need to have three configurations Debug, Release, ReleasePremium. Also make sure that the archive configuration is set same for both App and Feature1. i.e. if your Apps archive scheme is set to ReleasePremium, your Fearure1s archive scheme also need to be set into ReleasePremium.
Please assure that you do not need to import Feature1 in each .swift files when its already added in the Bridging-Header.h.
In case of issue came from Pod files, make sure you have uncommented #use_frameworks! into use_frameworks! from you Podfile. Sometime re installing pod works if Feature1 has any dependency on pods.
If none of the above steps works, delete your derived data folder and try re building.

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

Swift frameworks do not work with build configurations named other than 'Debug' or 'Release': No such module

Whenever I try to use a build configuration named other than 'Debug' or 'Release', Xcode suddenly cannot find my Swift frameworks. The configurations are the exact same other than their name (in fact, the new configuration was duplicated from the working 'Debug' configuration).
Xcode reports 'No such module'
This seems like a really strange bug. Surely someone has come across this before? My Google search yielded no results. Does anyone have any idea what may be causing this issue? I'm pretty sure I added the framework correctly.
I've created a short screencast to show you exactly what I'm doing: http://www.screencast.com/t/zpgZ5ZYgvH
Bottom line:
Make sure project currently builds using third-party Swift frameworks
Select the project in the project/file navigator
Select the project above Targets in the editor left sidebar and make sure you are on the Info tab
Duplicate the current configuration (likely 'Debug') by clicking the + button below the list of configurations and selecting 'Duplicate XXX Configuration'
Modify your scheme to use the new configuration by going to Product (menu) > Scheme > Edit Scheme...
Select Run in the left sidebar
Select your new configuration under Build Configuration
Attempt to build again
You can also download the sample project: http://s000.tinyupload.com/?file_id=48797763216274271820
I'm running Xcode 6.0.1 (6A317) and Yosemite 10.10 (14A361c).
Add the following Framework Search Path in the Build Settings of your target:
$(SYMROOT)/Release$(EFFECTIVE_PLATFORM_NAME)
and make it non-recursive
In my case this was for Alamofire, which was added to my project as a git submodule.
The framework was being built correctly which can be seen in the build logs, but I assume the default framework search path is derived from the scheme name. The Alamofire framework & dSYM file are in Release-iphoneos/ Release-iphonesimulator.
This should work work with any Swift framework as long as it's scheme names are default. If not, check the build logs and adjust the framework search path accordingly.
I had this issue as well and fixed it by adding the same configuration names to the included Alamofire project.
My build schemes in my main project:
And the build schemes inside the Alamofire project:
Note:
Also, make sure your iOS deployment target is the same in both projects.
If you are using CocoaPods, try pod install this will generate some .xcconfig files with your configuration name. Clean your build folder and build again.
If you have a modular structure (e.g. the App uses frameworks to decouple UI, Services or Business Logic from the application's main module) then add the new Build Configuration to each subproject that builds these frameworks.
In this case if the author had, let's say, Services Framework in his workspace then he had to add a Debug Original configuration to it too. And then run pod install, of course.
This is how I fixed my issue.

How to handle Debug/TestFlight/AppStore releases without targets?

I use Cocoapods for my project and I need a specific set of frameworks for each Debug/TestFlight/AppStore release:
Debug (simulator or device): common frameworks + Calabash - Google Analytics
TestFlight: common frameworks + TestFlight SDK
App Store: common frameworks only
I could use targets, but they are annoying:
Every time you add a new file (or create one) you have to remember to add it to all targets. It makes it really easy to produce builds that don't have a required file.
Changes in build settings of one target don't propagate to other targets (i.e: changing a llvm flag).
On the other hand, cocoapods doesn't support weak frameworks, so I can't weak-link to Calabash in my main target and force-load it when building in Debug mode (because it'll still be in the framework set when building for the app store)
What would be a good balance between the very segregated option that are targets, and "all in" solution of a single target?
I have a makefile that removes certain pods then runs Pod install. We're making it much easier in the next release to do config based pods, so you will be able to do all of what your asking in version 0.34+. This is in the current HEAD on github.

Resources