Migrate my pod to Swift 4 - swift

I created my pod in Swift 3 and now I wanna migrate it to Swift 4.
I've already done the code migration in the Example project (I chose to create an example when running pod lib create), but my podspec is still not passing validation.
One of the reasons is that the default cocoapods configuration is compiling it as Swift 3.
The other is that in order to update the dependencies to compile with Swift 4, I need to reference a specific branch, like RxSwift, but I couldn't find a way to do that in the podspec.
How can I fix those problems?

As per the CocoaPods: point to a branch in pod spec
You can't use :git and :branch metadata in podspec. It is expected that the :git and :branch metadata will come from the podfile.
If you want to use tags then use like below : RxCocoa/RxSwift for swift 4 tag(4.0.0-beta.0)
Pod::Spec.new do |s|
###Your code here
s.dependency 'RxCocoa', '~> 4.0.0-beta.0'
s.dependency 'RxSwift', '~> 4.0.0-beta.0'
end
If you want to use branch, then
Your podspecis like below :
Pod::Spec.new do |s|
###Your code here
s.dependency 'RxSwift'
end
Your Podfile will be :
use_frameworks!
target 'YOUR_TARGET' do
pod 'RxSwift', :git => 'https://github.com/ReactiveX/RxSwift.git', :branch => 'rxswift4.0-swift4.0'
end

Related

Using static libraries in Swift with CocoaPods fails for Realm

Since Xcode 9 it is possible to use static libraries by omitting the use_frameworks! flag in the Podfile. However, when used with the Pod RealmSwift this results in the following error:
[!] The following Swift pods cannot yet be integrated as static libraries:
The Swift pod `RealmSwift` depends upon `Realm`, which do not define modules. To opt into those targets generating module maps (which is necessary to import them from Swift when building as static libraries), you may set `use_modular_headers!` globally in your Podfile, or specify `:modular_headers => true` for particular dependencies.
Sadly, the proposed solution with use_modular_headers! does not work.
Other things I have tried include:
Using the latest Realm version (3.15.0)
Use the Objective C version and add Swift support, this won't build and give a module not found error in the RLMSupport.swift file .
Adding a bridging header for the Objective C version.
Endless clean, rebuild, Xcode relaunches and Derived Data folder cleaning.
It would not be preferable to circumvent CocoaPods and have this dependency be installed in a separate way, since that would make updating a more complex process. I hope there is a solution that works with CocoaPods, Realm and Swift.
I did the job doing following:
pod 'RealmSwift', '~> 3.17', :modular_headers => true
pod 'Realm', '~> 3.17', :modular_headers => true
As far as I can tell adding use_modular_headers! to top of Podfile works.
Adding s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES' } to .podspec doesn't work as far as I can tell. (Cocoapods 1.6.0-beta.2)
example:
target 'Opportunity' do
use_modular_headers!
end
I don't see why it wouldn't work. I got the same issue, and I added use_modular_headers! following way in the podfile and it worked.
target 'Pick Up Lines' do
use_modular_headers!
pod 'RealmSwift'
end
By the way, before doing any of it, make sure, you set the deployment target of the project as 11.0.

create Pod with bridging header

I'm trying to create a pod APod which has a 'AAnalytics' as a subspace. ''AAnalytics' has multiple dependencies such as Firebase and NewRelic. Here's how the podspec looks like:
Pod::Spec.new do |s|
s.name = 'APod'
s.version = '0.3.5'
s.summary = 'summary'
s.ios.deployment_target = '9.0'
s.tvos.deployment_target = '9.0'
s.watchos.deployment_target = '2.0'
s.static_framework = true
s.source_files = 'APod/Classes/*'
#### Subspec ####
s.subspec 'AAnalytics' do |ss|
ss.pod_target_xcconfig = { 'DEFINES_MODULE' => 'Yes' }
ss.source_files = 'Classes/AAnalytics/*'
ss.dependency 'NewRelicAgent', '~> 5.15.0'
ss.dependency 'Analytics', '~> 3.6.0'
ss.dependency 'Segment-Adjust', '~> 1.1.3'
ss.dependency 'FBSDKCoreKit', '~> 4.27.1'
ss.dependency 'Firebase/Core', '~> 4.4.0'
end
end
In AAnalytics, it has only one class AAnalytics.swift which has a wrapper methods of dependency pods. Everything works fine except NewRelicAgent. I can't import and use NewRelicAgent in Analytics.swift. However I could use NewRelicAgent in main project with bridging header.
After I searched for a while, I found that Xcode doesn't create module.modulemap file for NewRelicAgent (or it should be included in NewRelicAgent pod).
As you see above, FirebaseAnalytics has `Modules/module.modulemap'.
However NewRelicAgent doesn't have the path and file.
I have read this article and it seems Xcode create module.modulemap file if DEFINES_MODULE = Yes and there is a umbrella header which has same name with framework.
What am I missing and What should I do to use NewRelicAgent from AAnalytics.swift? I'm using cocoapods 1.4.1 beta 2.
Xcode doesn't generates module.modulemap files for binary frameworks. NewRelicAgent is a vendored_framework binary CocoaPod that doesn't include a module map. Other CocoaPod's include a module.modulemap within their framework.
If you do find . | grep module.modulemap, you'll see that the other binary CocoaPods with public APIs in your project include a Modules/module.modulemap file.

Adding static libraries to pod spec file

I am trying to create a framework out of the app that is using Google maps now.
This is my FuelMap framework podspec
target 'FuelMap' do
# Comment the next line if you're not using Swift and don't want to use dynamic frameworks
use_frameworks!
pod 'GoogleMaps'
end
podspec:
Pod::Spec.new do |s|
...
s.dependency 'GoogleMaps'
s.dependency 'Google-Maps-iOS-Utils'
end
Then, I have a regular project which has this pod file
target 'Mock' do
# Comment the next line if you're not using Swift and don't want to use dynamic frameworks
use_frameworks!
pod 'FuelMap', :path => './FuelMap'
end
Since the regular project is using use_frameworks
I keep running into this error whenever I do pod install
The 'Pods-Mock' target has transitive dependencies that include static binaries:
Is there a work around, so that I can have the library file from GoogleMap Ios statically in the touch framework and then add them as a reference in the pod spec file. So the error would be avoid?

"[!] Pods written in Swift can only be integrated as frameworks; add `use_frameworks!` to your Podfile to opt into using it

I have an existing project written in Objective C which contains private pods. I am writing a new private pod in swift language and need to integrate with existing objective C project as i have to go with Mix and Match approach. When I give "pod install" command i am getting below error
"[!] Pods written in Swift can only be integrated as frameworks; add
use_frameworks! to your Podfile or target to opt into using it. The
Swift Pod being used is: XXXXXNetworkManagerSwift"
Here "XXXXXNetworkManagerSwift" is a new pod written in Swift language. It is a framework template.
Existing private pods are written using static lib templates.
My podfile is as below where i am using XXXXXNetworkManagerSwift as a dependency
Podfiile:-
source 'https://github.com/xxxx/ios-specs.git'
source 'https://github.com/cocoaPods/Specs.git'
platform :ios, ‘8.0’
use_frameworks!
target 'XXXXFoundationFramework' do
podspec :path => 'XXXFoundationFramework.podspec'
end

Overlapping pod dependencies

I am using cocoapods 0.39. I added Cocoa Touch Framework "MyFramework" as a separate target to my Swift project. The framework is using Firebase as a Cocoapod dependency. I am using MyFramework inside the the app. When I try to build the app I get multiple errors:
class … is implemented in both …/MyFramework.framework/MyFramework and …/MyApp.app/MyApp. One of the two will be used. Which one is undefined.
I understand what this error is about, but I am not able to fix it. If I remove Firebase from MyApp target then I can't use MyFramework inside the app as it depends on it. It looks like a common problem, but unfortunately I can't make it work.
My Podfile looks like this:
use_frameworks!
target 'MyApp' do
pod 'Firebase'
end
target 'MyAppTests' do
end
target 'MyFramework' do
pod 'Firebase'
end
target 'MyFrameworkTests' do
pod 'Firebase'
end
You are linking Firebase twice.
You can use inherit! :search_patchs directive in Podfile (requires Cocoapods 1.0 or higher) to let MyApp know about the dependencies without actually linking them:
use_frameworks!
target 'MyFramework' do
pod 'Firebase'
pod 'FirebaseAnalytics'
target 'MyApp' do
inherit! :search_paths
end
end
This requires that you explicitly declare dependencies in your Podfile to make them available in MyApp target. For example, adding pod 'Firebase' won't make using FirebaseAnalytics available in your application.
You can also convert MyFramework to a CocoaPod dependency and let CocoaPods handle the dependencies for you. To do this, create a Podspec file for your framework, like this:
Pod::Spec.new do |s|
# Meta data
s.name = "MyFramework"
s.version = "1.0.0"
s.platform = :ios
s.ios.deployment_target = '8.0'
s.summary = "-"
s.homepage = "-"
s.license = { :type => "MIT" }
s.author = { "Me" => "-" }
s.platform = :ios
s.ios.deployment_target = '8.0'
s.source = { :path => "MyFramework" }
# Source configuration
s.source_files = "MyFramework/**/*.swift"
s.resources = "MyFramework/**/*.{png,jpeg,jpg,storyboard,xib,strings}"
s.requires_arc = true
# Dependencies
# Firebase for iOS
s.dependency 'Firebase', '~> 3.0'
end
Then, you can add a development dependency to MyFramework in your application Podfile and remove Firebase dependency:
target 'MyApp' do
pod 'MyFramework', :path => '.'
end
Update . to the MyFramework.podspec location if needed.