Using React Native iOS dependency in Objective-c - ios

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.

Related

No such module 'TTTabBarItem' using CocoaPods

I'm trying to extend TTTabBar. When I had the lib in my project, it worked fine but I wanted to keep it as a pod (for maintenance and version management) and extend it as needed.
Since then, I can't import it without errors. Other similar answers (and there is a lot!) didn't help.
My Podfile:
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'
use_frameworks!
target 'Octoly' do
pod 'RealmSwift', '~> 0.98'
pod 'Mixpanel', '~> 2.9'
pod 'SwiftHTTP', '~> 1.0'
pod 'TTTabBar', '~> 1.1'
end
Here is the code where I try to import it and you also can see that I opened the workspace and TTTabBar is installed:
I have tried lots of things:
Clean / Rebuild
Remove pods and reinstall
Close / Reopen XCode
Add the frameworks to my building settings
Combinations of the previous steps
Here is the Binaries linked where I added TTTabBar:
It is good to know that it works fine for RealmSwift and import TTTabBar works but then it doesn't know what TTTabBarItem is in class TabBarItem: TTTabBarItem {}.
Notice that I've started iOS development 2 days ago so there might be obvious things that I am missing.
You are facing those issues because you are not supposed to import TTTabBarItem (the class you intend to use), but the whole library, in your case import TTTabBar. I think the linker is clever enough to only include the referenced files you use in your code.
So again, use import TTTabBar instead.
More importantly, the developer of the library made a fundamental mistake:
If you take a look at the source files, you can see this:
class TTTabBar: UIViewController { // rest of the code... }
He specified no public access modifier, which basically means that you cannot access it outside of the internal target of the library (you can basically only reference it within the source project/target itself, which is useless to any developer integrating this library).
You have an option though:
Due to the size of the library, you can just go ahead and copy the files into your project (any modifications you would add would always be overwritten if you just used the pod on subsequent pod install calls, so your initial intent to modify the library also doesn't seem to be a viable option).
The problem is actually in the TTTabBar module itself. The TTTabBar and TTTabBarItem classes and its method are not declared as public. So you don't get those classes in your app. The creator of that module should have made those classes and functions public
The solution is to change the local copy if your TTTabBar* files to include public access specifier in the classes and some of its methods and build your project.
E.g.
public class TTTabBar: UIViewController and public class TTTabBarItem: UIButton
You also have to mark 3 other methods as public as well.
In TTTabBar file viewDidLoad
in TTTabBarItem drawRect and init?

Include of non-modular header inside framework error - how do you make transitive dependencies work with cocoapods?

I have created an open source library (https://github.com/linkedin/LayoutTest-iOS) which has two Cocoapods inside - LayoutTest and LayoutTestBase. LayoutTest depends on LayoutTestBase and one of the .h files needs to import something from LayoutTestBase. Currently, I do this using:
#import LayoutTestBase;
However, this only works if the application uses use_frameworks! in their Podfile. Some apps do not want to use this cocoapods option. Without use_frameworks!, it works if I use:
#import <LayoutTestBase/LYTLayoutPropertyTester.h> // OR
#import "LYTLayoutPropertyTester.h"
However, when using this with use_frameworks!, it gives the error: "Include of non-modular header inside framework module 'LayoutTest.LYTLayoutTestCase'"
Clearly, there should be a way of doing this import regardless of whether the user uses use_frameworks! or not in their Podfile. How can I get this library to compile and run correctly?
Research
I've looked on stackoverflow, and this seems to be the most similar question:
CocoaPods framework with dependencies - include of non-modular header inside framework module. It mentions that it's a problem with the Parse library, but doesn't mention how it needs to be fixed. Since I own the dependency, I can fix this.
I've also tried setting Allow non-modular frameworks to YES in all settings (projects, unit tests, all pods, etc), and this doesn't seem to do anything.
To Reproduce
Create a new project. Add this Podfile:
target :'{MyAppTarget}Tests' do
pod 'LayoutTest'
end
Run pod install. Try to run unit tests on the app. It will fail. Now, try changing LYTLayoutTestCase.h to use #import <LayoutTestBase/LYTLayoutPropertyTester.h>. It now works. However, if you add use_frameworks! to the Podfile, it no longer works.
I don't think this is the optimal solution but the work around I found was to do an #if __has_include and do both solutions depending on whether it was built with use_frameworks!
Here's a link to the github issue with more details: https://github.com/linkedin/LayoutTest-iOS/issues/8
If anyone knows how libraries like parse-SDK do it without these workarounds, I'm still interested.

Private pod with static library in along with swift pod

I'm working on pods development for an iOS dev team (on private repo). My low-level C/Obj-C core pod contains a static library with some headers and is used as dependency in other pods (pushed with --use-libraries).
Now that the iOS team wants to integrate Swift pods, they had to add the use_framework! option in the Podfile of their projects. Of course, they obtained the following error during pod install :
The 'XXX' target has transitive dependencies that include static
binaries
I spent half a day on the web looking for a way to make my pods compatible with the use_framework! option, in vain. This is very frustrating, as Google Services pods are proofs that it's possible to bypass this problem in a clean way (not with the verify_no_static_framework_transitive_dependencies trick) : the main pod and almost all its dependencies contain static libraries, and everything works perfectly along with Swift pods. Exemple with Google/SignIn which depends on Google/Core (vendored_libraries: Libraries/libGGLCore.a) and GoogleSignIn (vendored_libraries: Libraries/libSignIn.a).
Any idea of what I can do to make my pods compatible with the use_framework! option ?
Thank you all,
Cheers,
Tom
I think I found a hack for my problem. This is quite weird, but I'd say it's clean enough to use it in production ;)
I found it here. The idea is simply to include a source file (even an empty one) in your source_files list inside your podspec.
Basically, the source section of my podspec looks like this :
s.source_files = "myLib/Empty.m", "myLib/Headers/*.h"
s.vendored_libraries = "myLib/myLib.a"
The only modification I made is to add "myLib/Empty.m" in the source files (Empty.m is strictly empty). Without it, I systematically have the transitive dependencies error when I pod install. With it, pod install works fine. It worked for me with both Cocoapods 0.0.39 and 1.0.0.beta.4.
Well, looks like it's a not so dirty solution, but I'm not sure it'll work in every case. And it's no good news about the cleanliness of Cocoapods...
As I mentionned in comments earlier, Google seems to have found a cleaner solution. So if anybody have an idea of the real clean solution, please share !
Cheers,
Tom
PS : I think I'll name the file DirtyCocoapodHack.m instead of Empty.m, sure they'll love it in the dev team ;)

CocoaPods not building target for Crittercism

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.

Missing required module 'CocoaLumberjack' in iOS 8 app / framework

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>

Resources