Hi team,
a little heads up on an issue that I‘ve been looking the last days, on how to proper
support both an Obj-C and a Swift library (in-parallel) on Cocoapods. There was a
discussion on the cocoapods issues tracker[1] basically around two ideas:
a) being a separate project, with a new name plus utilising Swift specific language
propers.
b) having one project, utilising cocoapods subspec mechanism to include specific files per
spec requested. In a nutshell users will employ in their Podfile something of a form:
—
pod “MyFooBarLibrary/Objc’ (objective-c)
or
pod “ MyFooBarLibrary/Swift’ (Swift)
—
Solution (b) was intrigued and went on to discover more, since I haven’t used before the
subspec mechanism and was a good opportunity to learn. The issue mentioned two projects,
QueryKit[2] and ReactiveCocoa[3] (their Swift branch) that utilise this mechanism, so I
dive in trying to see how it works.
My realisations:
a) both projects are designed with ‘Swift first’ approach, employing _some_
'Objective-C code’ to ease the interaction in a mixed project e.g Objective-C code
calling the ‘Swift’ library, see [4] where the author describes more details on this.
b) since ‘Swift first’, both produce frameworks where they can be integrated either in
objective-c or swift language projects, no ‘static-library’ targets.
c) both are designed for iOS >= 8.0
To make it short and from my understanding, the projects are _not_ designed around the
idea of: take either the Objective-C or the Swift port in you project, but instead employ
an Objective-C subspec to “ease” the interaction in a mixed environment, aka Objective-C
code calling the Swift library.
Regardless and to better understand, I did some testing with our push-sdk:
a) having a single Swift Project employing both the objective-c code and Swift code
b) having a .workspace with a) Obj-c xcodeproj, b) Swift xcodeproj.
In both cases, this mixed approaches, at the end caused issues and wasn’t able to generate
a proper solution. Issues around a) cocoapods 'pod install’ steps, b) tests on the
library are done with two different dependencies c) various other integration issues…
It’s my sense, the most clean way is to go with separate libraries, that is solution (a)
described above (a solution proposed also from @orta [5]) This has the added benefit of
cleaner 'logistics’ that is: commit history, releases, static/framework library
generations etc etc.
But there is one issue if we go with separate approach: _cocoapods naming_, that is how
to properly separate between the two.
Currently searching for AeroGear-Push in
cocoapods.org site we get the following:
In my cocoapods PR [6] I went with the approach to name the ‘Swift’ equivalent library as
'AeroGear-Push-Swift’, so the same searching above will reveal:
—
AeroGear-Push
AeroGear-Push-Swift
—
Some of you have already noticed, that the ‘hyphen’ character as a podspec name doesn’t
work well with a Swift Project, cause the podspec name is used as the name of the final
#import statement the user does. That is the following import statement doesn’t work:
—
import AeroGear-Push-Swift
—
Solving this, there are two approaches:
a) rename both library podspecs : Objective-C to -> AeroGearPush and Swift to ->
AeroGearPushSwift
b) continue the same naming, but use the new ‘module_name’ podspec directive in the Swift
project(added in cocoapods [6]) to specify the final module name the user will use on the
import. That is the approach I have taken in my PR[6]
If we go with (b) the entries will look like this:
——
Obj-c: (no changes needed)
Podfile: pod 'AeroGear-Push’
Class: #import <AeroGearPush/AeroGearPush.h>
Swift:
Podfile: pod 'AeroGear-Push-Swift’
Class: import “AeroGearPush” (notice _no_ ‘Swift’ postfix is needed cause of the
‘module_name’ override)
——
I am fine with both albeit more towards (b) mostly not to break existing ‘pod installs’
the users may use and since support with the ‘module_name’ directive is provided from
cocoapods. Current PR[6] goes with this approach.
Let me know your comments and suggestions
Thanks
Christos
[1]
https://github.com/CocoaPods/CocoaPods/issues/3016
[2]
https://github.com/QueryKit/QueryKit
[3]
https://github.com/ReactiveCocoa/ReactiveCocoa/tree/swift-development
[4]
https://github.com/CocoaPods/CocoaPods/issues/3016#issuecomment-69092100
[5]
https://github.com/CocoaPods/CocoaPods/issues/3016#issuecomment-69073109
[6]
https://github.com/aerogear/aerogear-ios-push/pull/41
[7]
http://blog.cocoapods.org/Pod-Authors-Guide-to-CocoaPods-Frameworks/