cocoa podspec subspec swift compatibility header file not found - ios

Pod lib could not find mymodule-swift.h header.
One of my objc.m file imports following code.
#import <devillogin/devillogin-Swift.h>
Xcode build is success. Everything is ok.
But when I'm trying to distribute with pod, following error printed.
pod lib lint mymodule.podspec
fatal error: 'devillogin/devillogin-Swift.h' file not found
My mylib.podpec is as following
Pod::Spec.new do |s|
...
s.subspec 'DevilLogin' do |devilLogin|
devilLogin.source_files = 'devillogin/devillogin/source/**/*.*'
devilLogin.public_header_files = 'Pod/Headers/*.h'
devilLogin.dependency 'devil/DevilCore'
devilLogin.dependency 'KakaoSDK'
end
end
Is there any syntax in podspec for mylib-swift.h ?

I'm answering to myself.
I found that the issue only occur when it is in the subspec.
No problem with root podspec.
Consequently I couldn't find way to let my pod-subspec import "XXX-swift" header.
But I found workaround.
I referenced firebase frameworks which use many pod-subspecs.
https://github.com/firebase/firebase-ios-sdk
Just watched root pod spect and 1 subspec.
It distributes sub-specs as root pod spec which is success with 'XXX-swift.h' header
And each subspecs depend on it above.
There is Firebase.podspec and FirebaseDynamicLinks.podspec.
FirebaseDynamicLinks is standalone independent frameworks.
But it is actually subspec.
Firebase podspec defines subspec like followings.
This is workaround
s.subspec 'DynamicLinks' do |ss|
ss.dependency 'Firebase/CoreOnly'
ss.ios.dependency 'FirebaseDynamicLinks', '~> 7.9.0'
end
It defines DynamicLinks as subspec and define dependency on independent FirebaseDynamicLinks.
Done

Related

Swift pod dependency Firebase, pod spec lint error

I had some problem when I create a cocoaPod by swift,my swift pod dependency firebase. Everything is ok when I develop my pod, but there is one error when I pod spec lint.
Here is the error:
- WARN | source: Git SSH URLs will NOT work for people behind firewalls configured to only allow HTTP, therefore HTTPS is preferred.
- WARN | url: There was a problem validating the URL https://xxxxxxxxxxx.
- ERROR | [iOS] unknown: Encountered an unknown error (The following Swift pods cannot yet be integrated as static libraries:
The Swift pod `MyPod` depends upon `FirebaseCore` and `FirebaseCrashlytics`, 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.
Here is my pod spec:
s.static_framework = true
s.subspec 'Common' do |ss|
ss.source_files = 'Source/Common/**/*.swift'
end
s.subspec 'MyPodFirebase' do |ss|
ss.source_files = 'Source/Firebase/**/*.swift'
ss.dependency 'FirebaseCore'
ss.dependency 'FirebaseAnalytics'
ss.dependency 'FirebaseCrashlytics'
ss.dependency 'MyPod/Common'
end
Can anybody help me?

Cocoapod subspec dependency not adding header/library search paths

I'm writing a Cocoapods podspec for a Swift library (https://github.com/promotedai/ios-metrics-sdk). One of our clients asked us to add Firebase Analytics tracking to the internals of this library. As a result, in the podspec, I broke the Firebase dependency into a subspec.
Pod::Spec.new do |s|
s.name = 'PromotedAIMetricsSDK'
...
s.subspec 'FirebaseAnalytics' do |a|
a.source_files = ['Sources/PromotedFirebaseAnalytics/**/*.{h,m,swift}']
a.dependency 'Firebase/Analytics', '~> 7.11.0'
a.dependency 'PromotedAIMetricsSDK/Core'
end
end
The problem I ran into was that the above subspec neither builds nor passes pod lib lint. The build complained about a missing Firebase framework, and the lint step complained about the same thing. I had to add the following xcconfig to the subspec to get things working.
analytics_xcconfig = {
'USER_HEADER_SEARCH_PATHS' => '"${PODS_ROOT}/Firebase/CoreOnly/Sources"',
'FRAMEWORK_SEARCH_PATHS' => '"${PODS_XCFRAMEWORKS_BUILD_DIR}/FirebaseAnalytics" "${PODS_XCFRAMEWORKS_BUILD_DIR}/GoogleUtilities" "${PODS_XCFRAMEWORKS_BUILD_DIR}/nanopb"',
'OTHER_LDFLAGS' => '-framework "FirebaseAnalytics" -framework "GoogleUtilities" -framework "nanopb"'
}
s.subspec 'FirebaseAnalytics' do |a|
a.source_files = ['Sources/PromotedFirebaseAnalytics/**/*.{h,m,swift}']
a.dependency 'Firebase/Analytics', '~> 7.11.0'
a.dependency 'PromotedAIMetricsSDK/Core'
a.pod_target_xcconfig = analytics_xcconfig
end
While the above configuration allows the subspec to build and pass lint validation, it defeats the purpose of having a package manager take care of these dependencies. I have other subspecs that pull in dependencies that don't encounter the same problem. Also, pulling in Firebase/Analytics directly in the app's Podfile works fine.
Am I missing something? Is there a reason why Firebase/Analytics requires this xcconfig hack when building from a subspec of a podspec? Can I get rid of this hack somehow?
For a demonstration of this problem, pull the above repo and remove the a.pod_target_xcconfig = ... lines from the FirebaseAnalytics subspec, then run pod lib lint. Commit 67cb6173ee0f43b33cfb726b6337cc14463d220b in the repo demonstrates a similar problem where the linker can't find the FirebaseAnalytics framework (run pod lib lint on that commit).
I'm using Cocoapods 1.10.1, Xcode 12.5, and macOS 11.3.
Thanks,

Add Cocoapods dependencies to my custom framework

I'm trying to create a custom framework and require some cocoa pods to be bundled along with it.
I have tried adding my framework as the target in pod file, but it is still not working.
Pod::Spec.new do |s|
s.default_subspec = 'Base'
s.subspec 'Base' do |ss|
ss.dependency 'Crashlytics'
end
end
More info here: link

Include Pod's Bridging-Header to Build Settings of Project's Target?

I created an objective-c pod with two files:
Source/SomeViewController.h
Source/SomeViewController.m
I also created a bridging header in the pod:
Source/Bridging-Header.h
with the content:
#import "SomeViewController.h"
My podspec looks like this:
Pod::Spec.new do |s|
s.name = 'TestLib'
s.version = '0.0.1'
s.license = 'MIT'
s.ios.deployment_target = '7.0'
s.source_files = 'Source/*.{h,m}'
s.requires_arc = true
s.xcconfig = { 'SWIFT_OBJC_BRIDGING_HEADER' => 'Source/Bridging-Header.h' }
end
I created a demo project did pod init and inserted my pod. Then after pod install I get the following output:
Installing TestLib 0.0.1 (was 0.0.1)
Generating Pods project
Integrating client project
[!] The `TestLibProject [Debug]` target overrides the `SWIFT_OBJC_BRIDGING_HEADER` build setting defined in `Pods/Target Support Files/Pods-TestLibProject/Pods-TestLibProject.debug.xcconfig'. This can lead to problems with the CocoaPods installation
- Use the `$(inherited)` flag, or
- Remove the build settings from the target.
[!] The `TestLibProject [Release]` target overrides the `SWIFT_OBJC_BRIDGING_HEADER` build setting defined in `Pods/Target Support Files/Pods-TestLibProject/Pods-TestLibProject.release.xcconfig'. This can lead to problems with the CocoaPods installation
- Use the `$(inherited)` flag, or
- Remove the build settings from the target.
When I open my TestLibProject.xcworkspace file I see that the pod was installed correctly but the bridging header from the pod is not installed correctly. I my Swift project I tried to do:
let vc: SomeViewController
This gives an error because the bridging header from the pod ist not installed.
How do I have to configure the podspec in order to get the bridging header of the pod being installed correctly?
Podspecs build frameworks, and frameworks cannot include bridging headers. If you want to import non-modular code into a Swift framework, you'll need to use a custom module map, instead, e.g. at MyLib/module.modulemap:
framework module MyLib {
umbrella header "MyLib.h"
// Load an SDK header, e.g. CommonCrypto.h
header "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/include/CommonCrypto/CommonCrypto.h"
export *
module * { export * }
}
Once there, you can specify the custom module map both in your Xcode project (either as the MODULEMAP_FILE setting in an .xcconfig file, or as the Module Map File of your target's Build Settings.
Now, the final piece of the puzzle: the podspec. You need to set the module_map:
Pod::Spec.new do |s|
# …
s.module_map = 'MyLib/module.modulemap'
end
The above is how SQLite.swift distributes itself, both as a general framework and as a pod.
Edit: Seems like I missed the point of the original question, as was clarified in this thread. The OP wanted to use a pod framework's bridging header to automatically load itself into the installing project's Swift code. This isn't possible. Even if Swift frameworks did support bridging headers, they would only be able to load Objective-C/C code (i.e. private framework code) into the framework's Swift code.

Cocoapods importing a framework to source code

In my cocoapod for iOS, I have a essentially items:
Open-source classes (.m & .h files)
MyFramework.framework (.framework directory, header files, and .bundle for resources)
One of the open-source classes calls import <MyFramework.MyFramework.h> so it can use the components of MyFramework in its implementation. But because of this, I'm having trouble getting the podspec to pass the spec lint test (pod spec lint MyCocoapod.podspec). When I run the spec lint validation, it says:
ERROR | [iOS] [xcodebuild] .../MyFile.h:54:9: fatal error: 'MyFramework/MyFramework.h' file not found
While investigating, I noticed that the podspec does pass the spec lint validation if I remove that open-source class in the podspec's source_files section, s.source_files = 'MyFiles.{h,m}'. Any idea why my class can't import my custom framework during the spec lint validation?
The relevant code in the podspec looks like this:
s.preserve_paths = 'myframework/MyFramework.framework'
s.frameworks = 'Foundation', 'MyFramework'
s.xcconfig = { 'FRAMEWORK_SEARCH_PATHS' => '$(SRCROOT)/myframework/' }
s.public_header_files = 'MyFramework.framework/Headers/*.h', 'SourceCode/*.h'
s.source_files = 'SourceCode/*.{h,m}' # Crashes here - Source_file imports MyFramework.h. If I take this out, it passes spec lint validation
EDIT This process is now entirely handled by the vendored_frameworks option. This handles preserving the paths, the framework search paths, and linking to the project.
To include a framework you can use:
s.vendored_frameworks = 'path/to/SomeFramework.framework'
To include bundle files do:
s.resources ='path/to/SomeBundle.bundle'

Resources