Some Cocoapods, e.g. YLTableView, don't set 'DEFINES_MODULE' => 'YES' as part of their pod_target_xcconfig. This means that, for example, import YLTableView doesn't work in Swift unless you set :modular_headers => true in your Podfile like so:
pod 'YLTableView', '~> 2.2.0', :modular_headers => true
If I'm writing a podspec, is there any reason I shouldn't include DEFINES_MODULE in my config like so?
ss.pod_target_xcconfig = { "DEFINES_MODULE" => "YES" }
It seems to me that this doesn't have any negative effect, and it enables Swift users to consume my library more easily.
There is one known issue (with workarounds): https://github.com/CocoaPods/CocoaPods/issues/7584. It may cause issues for users importing your Objective-C lib headers directly in their Precompiled Headers (*.pch). You may workaround it by including an empty swift file in your lib source files. Chances are there will be a clean fix in a future version of CocoaPods.
Otherwise, there is no real downside. It enables stricter search paths for imports at build time, which means:
either it builds, and it works like before (and as bonus you can now find it with #import in ObjC or import in Swift)
either it doesn't build anymore, and consequently you can't publish the podspec anymore
From the blog post regarding CocoaPods 1.5.0 release:
[...] CocoaPods allowed any pod to import any other pod with un-namespaced quote imports.
For example, pod B could have code that had a #import "A.h" statement, and CocoaPods will create build settings that will allow such an import to succeed. Imports such as these, however, will not work if you try to add module maps to these pods. We tried to automatically generate module maps for static libraries many years ago, and it broke some pods, so we had to revert.
In this release, you will be able to opt into stricter header search paths (and module map generation for Objective-C pods). As a pod author, you can add 'DEFINES_MODULE' => 'YES' to your pod_target_xcconfig. [...]
Related
I currently have the following dependency in a ReactNative project's package.json:
"vital-health-react-native": "file:../packages/vital-health-react-native"
This package has a .podspec with the following dependency:
s.dependency "VitalHealthKit", "~> 0.7.7"
Because I am dealing with HealthKit and background delivery, I need to be able to call a method from this dependency inside the AppDelegate.mm.
I have tried everything to import VitalHealthKit in the .mm and even in the .h, but the dependency is never found. The spec for VitalHealthKit can be found here.
What am I missing?
I’ve not done sub-dependency imports myself but I think one would need to add the pod to the app project’s Podfile like so
pod 'VitalHealthKitRN', path: "#{path_to_packages} /packages/vital-health-react-native/VitalHealthRN.podspec"
Having done that, if one still can’t import VitalHealthKit in the app, it might be necessary to reference VitalHealthKit native pod in the Podfile directly, either in a usual way (that might create a conflict of dependency versions with the RN pod) or using a local relative path, similar to the above. Might also have to use_frameworks! if you don’t already to avoid double-linking vital health kit. Hope this helps.
In my project I've around 20-30 PODS and all of them are in OBJECTIVE-C.
In some of the pods I've changed some pieces of code due to requirement.
Now I want to add a pod which is only written in swift. Is it possible to use swift for only that specific pod ? I don't want to use "use_framework" as it will force all other pods to use static frameworks.
Currently use_framework! is either all or none. There is currently an open issue to change that.
Swift static library support will be added in CocoaPods 1.5.0 so that is likely to be the soonest route to a solution for you, but still a ways off.
With the release of cocoapods 1.5.0. Not it's possible to use only a single swift pods. From official docs
you can add use_modular_headers! to enable the stricter search paths and
module map generation for all of your pods,
or you can add :modular_headers => true to a single pod declaration
to enable for only that pod.
By this we can improve store submission time. Here is the official doc page Cocoapods 1.5.0.
I added pod 'CrittercismSDK' to my Podfile and ran pod install, it finished with no error, all good.
Using import Crittercism gives No such module error. I looked into the Pods/ directory, there source code is there; however, the Pods project doesn't have a target called Pods-MyProject-Crittercism (but it does have targets for each dependency).
Build keeps failing because the import isn't found. What am I doing wrong?
PS: I'm using use_frameworks! directive in my Podfile, and I have another obj-c library that works fine, so I don't know why this one isn't working.
While this is not a general answer, I have found that:
Not using #use_frameworks
Using a Bridging-Header.h containing #import "Crittercism.h"
Not importing CrittercismSDK in the Swift class, but merely executing Crittercism.enableWithAppID("appId") does the trick.
See if below steps helps in your case. What version of pod/Xcode in use? It will be great if you can share your pod file, thanks.
Install dependencies using Cocoapods and the use_frameworks! flag.
As you need to use a Objective-C dependency, create a Bridging header. You can create one easily by importing an Objective-C class to your Swift project, than remove it (the wizard should ask you if need a bridging header). Otherwise, create a new header file. Then, navigate to your target configuration and enter the name of your file in Swift Compiler - Code Generation > Objective-C Bridging header.
Still in your target configuration, add a new entry in Search Paths > User Header Search Paths: Pods as value and flag it as recursive.
Remove any import instruction from your code, relative to your Objective-C library.
Build your project. You should have a success.
I have a podfile defined with the following pods.
platform :ios, '8.0'
use_frameworks!
target 'LifeStream' do
pod 'SSKeychain'
pod 'LiveSDK'
pod 'Alamofire', :git => 'https://github.com/Alamofire/Alamofire.git', :branch => 'swift-2.0'
end
I installed the pods and opened up my workspace. I have found that any usage of Alamofire works fine, due to the Swift 2 version of it importing the project as a framework.
When I try to use SSKeychain classes however, I receive a
Use of unresolved identifier 'SSKeychain`
Same applies with any class I try to use in the LiveSDK.
I have a bridge header in my projects root directory, and the project is configured to use it.
#ifndef Header_h
#define Header_h
#import "SSKeychain/SSKeychain.h"
#import "LiveSDK/LiveConnectClient.h"
#endif /* Header_h */
if I change the #import from
#import "SSKeychain/SSKeychain.h"
to
#import "SSKeychain.h"
Xcode fails to compile because it can't find the file. So I assume that the bridge header is working, as the way my bridge header is built now does not generate any compiler errors caused by not finding the headers.
Bridge Header
Framework Search Paths
I have also added my project root directory to the framework search path.
Linked Frameworks
Lastly I have linked all of the frameworks to the project as well.
Am I missing something with my setup? I have not been able to get Cocoapods to work on my project for nearly a week now. I even created a brand new project thinking that mine was just messed up; which didn't change a thing. I don't know what to do from here in order to resolve this.
Edit
After doing some additional research, I found a blog post showing that you have to include your Pods directory in the User Header Search
A commenter also mentioned that if you are using the newer Cocoapods Frameworks support for Swift, then it will need to include the Frameworks/** search path. I've included both Pods/** and Frameworks/** but still have the same issue.
After some further reading, it's beginning to sound like this is a limitation of Cocoapods. From what I understand, you can't use libraries and frameworks together at the same time in a project.
Once you use use_frameworks! in your Podfile, Objective-C Pods like SSKeychain also get build as frameworks.
The actual problem is that only module imports work in the bridging header when using frameworks. Also, you might want to get rid of the bridging header entirely, as it is unnecessary when using frameworks, they can be imported directly in Swift.
To clarify what you should do to make it work:
Be sure to have use_frameworks! in your Podfile
It doesn't matter if you have a Bridging header or not. Leave it untouched
In your SWIFT file just use import Podname
That's it, you're good to go. Of course it may happen that you need to clean your project or maybe delete the derived data folder. Build and you can use it.
If you're not using any swift pods,
Try removing the use_frameworks! on your Podfile.
Run pod install on terminal.
Clean & Build !
I spent almost half an hour fixing it, I tried adding those paths on Search Paths or re-adding the bridging-header but the error was the same.
Therefore, in my case, bridging header file was not the problem, its on the Podfile .
I hope it helps!
I'm having a problem with integrating a cocoa pod (CocoaLumberjack in this case) into an iOS app and my own frameworks.
The Podfile looks like this:
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, "8.0"
target "CommonModule" do
use_frameworks!
# CocoaLumberjack wasn't officially released with Swift support yet
# pod 'CocoaLumberjack'
pod 'CocoaLumberjack', :git => 'git#github.com:CocoaLumberjack/CocoaLumberjack.git', :commit => '6882fb5f03696247e394e8e75551c0fa8a035328'
xcodeproj 'CommonModule/CommonModule.xcodeproj'
end
I have a hierarchy of modules (dynamic frameworks) like this:
CommonModule
ModelsModule (has a dependency CommonModule)
And finally, the main app:
MySwiftApp (dependency both ModelsModule and CommonModule)
Now, CocoaLumberjack is used in several files in CommonModule and works as expected. However, every time I do import CommonModule in any file in ModelsModule, I get the following compile error:
~/Developer/ModelsModule/ModelsModule/SomeFile.swift:2:8: error: missing required module 'CocoaLumberjack'
import CommonModule
^
Any idea how to solve this issue?
UPDATE: Some people Recommend to use Carthage. I would like to avoid that, if possible.
You'll also need to ensure that CommonModule.framework and CocoaLumberjack.framework (and any other frameworks) are listed in the Embedded Binaries section of your application target.
All the new iOS 8-style dynamic frameworks must be embedded within your app—even those that you aren't using directly, but that are dependencies of your dependencies—so you might end up seeing references to items you don't recognize.
Incidentally, there is a new Swift-based logging engine called CleanroomLogger that might make things easier if you're having trouble interacting with CocoaLumberjack from Swift.
I am assuming that CommonModule is swift and that your also using CocoaPods 0.36 as I see your calling use_frameworks!. I'm also assuming that you're using the Obj-C version of CocoaLumberjack, and trying to use it with Swift. That use_frameworks! flag tells CocoaPods to generate frameworks of the pods for linking in your Xcode project. So you need to say at the top of your class
import CocoaLumberjack
instead of using the Swift-Bridging-Header
Here is the blog post on cocoapods.org where they talk about the how to author a pod for the new use_frameworks! flag. Scroll down to the part Common Header Pitfalls
It could also be that your podspec creates a dependency to use CocoaLumberjack, and when linked to your project CocoaLumberjack and CommonModules, but Common Module is not referencing it correctly in the library. To get past that you need to refer to it as a framework when you import it into your Objective-C library
#import <CocoaLumberjack/CocoaLumberjack.h>