How to include objectiveC dependency in a swift library - objective-c

Xcode cannot find references to a obj-c library after adding the dependency to my library's Podspec file
I'm trying to write a flutter iOS plugin for the GVRAudioEngine. There are two parts to this:
The plugin implementation, which instantiates a native object--in this case a GVRAudioEngine instance--and a communication channel to the dart world. Dependencies for this part are defined in a Podspec file
A sample app that runs the plugin--for debugging and documentation purposes. Here is where a sample AppDelegate class would get implemented. Dependencies for this part are defined in a Podfile
I've been able to include the GVRAudioEngine as a Podfile dependency accessible from the sample app. For this I've had to create a header bridge.
However,I've so far not been able to access GVRAudioEngine from the library side i.e Podspec. I've added the dependecies, and tried creating a header bridge there, or checking the framework and header paths. I've not been able to get this to work.
Comparing this library to other libraries I do have access to, the only differences I've found so far are:
This one is written in objc
the framework is a .a file
I'm close to giving up. I'm a new iOS developer, so I fear there's something super obvious I'm missing.
I've added the following lines to my Podspec file.
s.dependency 'GVRKit', '1.140.0'
s.dependency 'GVRAudioSDK', '1.140.0'
s.static_framework = true
I expect to be able to declare a field of type GVRAudioEngine in my Podspec library. But Xcode complains that the type is undeclared

Related

AdMob: Could not find auto-linked framework 'FBLPromises'

I have a Objective C project and I want to add AdMob to it. Been following https://developers.google.com/admob/ios/quick-start#objective-c
I get the linker error
ld: warning: Could not find auto-linked framework 'FBLPromises'
Undefined symbols for architecture arm64:
"_OBJC_CLASS_$_UIScene"
I'm adding the frameworks manually. I dragged them in.
The tutorial doesn't say anything about the promises framework, but it comes in their download. And if I don't add it, I get a linker error saying a function is missing.
All of the frameworks are in the project and in Link With Binary Libraries list.
I tried deleting them and re-adding them, and quitting Xcode and clean build.
I tried adding framework search paths $(inherited) and $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME) and the folder they are in with recursive $(PROJECT_DIR)/Frameworks and all of their exact paths individually also.
I tried adding a new swift file to the project so that it becomes hybrid.
I added -ObjC linker flag to Other Linker Flags, and $(inherited)
The tutorial says to add "GoogleUtilities.framework" But what I downloaded has "GoogleUtilities.xcframework" folder. So I tried adding the folder both as a group and as not, and I tried adding the framework files in the folder only.
I tried making a new project with nothing else.
Can anyone get AdMob to work on an Objective C project with adding frameworks manually?
I have agreed to the latest terms from apple and have a paid developer account.
I had a similar error in a Swift project.
Undefined symbol: _OBJC_CLASS_$_JSContext
In my case the solution was to add the JavaScriptCore.framework to the project.
Figured out the issue for a hybrid project!
The project I was linking to used an ObjC Bridging Header, so I simply needed to import Firebase in the header file:
// ObjC-Bridging-Header.h
#import "Firebase.h"
Not sure if this relates to a pure ObjC project, but you might be able to add a dummy Swift file to make it a hybrid project and use the bridging header.
I had the same error. I had forgotten to add the following libs: nanopb.xcframework, PromisesObjC.xcframework, UserMessagingPlatform.framework - included in GoogleMobileAdsSdkiOS.. I just added the missed libraries and now everything is OK.
Try to add libz.tbd, libc++.tbd, libsqlite3.tbd and StoreKit libraries in Link Binary With Libraries at the Build Phases tab.

Problems creating a NativeScript plugin that uses Objective-C code

I have followed the NativeScript documentation on adding Objective-C code to a NS project although I am struggling to call the Objective-C code in my iOS project. I am only trying to implement appPlugin.h and appPlugin.m files into my project.
My folder structure for the Objective-C files are as follows:
Project/app/App_Resources/iOS/src/...
I have also tried creating a NativeScript plugin that gets added to the dependencies in the projects package.json.
Are there any additional files that need to be added to make the Objective-C code compatible with the NS project. The documentation simply says run "If you run 'tns prepare ios' you will see that the files are now part of the project."
Link to the documentation I have been following:
https://www.nativescript.org/blog/adding-objective-c-code-to-a-nativescript-app
https://docs.nativescript.org/plugins/building-plugins
SOLVED: Files are added to the TNSNativeSource folder (Check in Xcode) and are available to use like any JS object.

Module not found for framework dependency in Xcode

I have a project with multiple framework targets, that also have pods dependencies.
I have:
No circular dependencies between targets
Everything, including pods, is in Objective-C, no Swift at all.
use_frameworks! in Podfile, so all pods are frameworks, not libraries.
Here is my structure:
TUSystemKit depends on TUModels (which is a framework).
TUModels depends on Pods_TUModels (generated by pods).
Pods_TUModels depends on JSONModel
TUModels is automatically linked with its own pod framework (which contains JSONModel).
TUSystemKit has TUModels as target dependency.
TUSystemKit is linked with TUModels.
Visually, the dependencies are like this:
TUSystemKit ➔ TUModels ➔ Pods_TUModels ➔ JSONModel
When I select MyModels as the build target in Xcode, build succeeds. However, when I select TUSystemKit, the build fails, saying that module JSONModel is not found while building module TUSystemKit (TUUser in screenshot belongs to TUModels):
What am I doing wrong? Obviously I shouldn't be explicitly linking against all the frameworks in the dependency tree. Why does TUModels build perfectly but TUSystemKit errs on a module import inside a linked framework's code? Do I need to change something with pods?
After hours of refactoring, I've managed to build my project. I can't tell what exactly was wrong as it took me literally a day to organize all the dependencies and frameworks and it kept failing at a different point, more than a 100 times, but here are some observations to lead to a successful build:
All the public-facing classes are added as public headers to the target, and not to any other target.
All the code (.m files) are in Compile Sources section of the target, and not in any other target.
All the public facing classes' headers are included at umbrella header (a header with the exact same name with the framework)
The application embeds all the custom frameworks (not the pods).
All the files inside a framework target only #import required files within the same target or a file listed on any targets umbrella header that the framework has a dependency on.
Obvious, redundant, but worth noting again: no classes between frameworks should have circular dependencies (e.g. ClassA in FrameworkA depends on ClassB in FrameworkB, while some class in FrameworkB depends on some class on FrameworkA). I had some, and created delegates. Do whatever pattern fits your design: IoT/dependency injection, notifications/publisher-subscriber etc. But do it: separate the concerns clearly.
Try to avoid using same classes in multiple targets. Instead, have it in one target, and make the other target depend on the containing target, creating a dependency chain.
After refactoring many files and playing with project settings, I managed to build and run everything again. My previous setup had various number of combinations of the issues that I mentioned above, messing everything up. After cleaning all the bits and grouping code into functional, modular frameworks, I could build it.
If you came here due to the parse error -> module not found,
in certain occasions you may be forced to add the path manually.
This is...
go to your project at the top
select your project target
select build settings
search the parameter Framework Search Paths under the title Search Paths
add the one where yours is located. Example: (using cocoa pods) $(SRCROOT)/Pods
indicate/set it to be recursive (access to the option by double-clicking your previously added path)
The problem should have been resolved by the 3erd party lib with commands like install / update / build or similar but if it fails and you are stuck, this is an option in order to continue.
In the same tone, if you get an error from pods indicating that
The sandbox is not in sync with the Podfile because the builder is unable to find files like Podfile.lock, then you may consider to go in the same direction adding some user-defined settings:
select build settings
press the '+' symbol, "Add User-Defined Setting".
add this pair:
param= PODS_PODFILE_DIR_PATH value = ${SRCROOT}/.
param = PODS_ROOT value = ${SRCROOT}/Pods
Cheers

Compilation issues with Mix and Match Objective-C & Swift Cocoapod

I'm working on a large mixed Objective-C and Swift codebase. I'm trying to move some of the code into a separate framework. This is going to end up being imported into the main project via a Cocoapod. The separate framework will end up having both Objective-C and Swift code.
So far I've moved all of the files for the new separate framework out of the main project and into a new folder. I've referenced these new files via a podspec and I'm importing them back into the main project as a development pod. All I'm trying to do right now is get this new framework to build on its own, I'm not trying to build it as part of the entire project yet.
The part I'm currently stuck on is, when it builds, in the MySplitOutFramework-Swift.h that it generates there is a a compilation error. The compilation error is on the line #import <MySplitOutFramework/MySplitOutFramework.h>. The error say 'this file cannot be found'.
What exactly am I doing wrong here? Is it some kind of circular dependency?

Dependency Management for iOS Library

First off: Why is dependency management for obj-c projects such a pain?!
I am writing a wrapper for my RESTful service in objective-c. The server is a simple sinatra app running locally on 'http://localhost:4567'.
I've included RestKit by following the steps outlined here.
I know RestKit is 'installed' correctly into my project because when I do #import <RestKit/RestKit.h> the project builds just fine.
Now, I'm testing my library using SenTesting.Framework. I have a class in my main library that looks like this:
#import "CITWCore.h"
#import <RestKit/RestKit.h>
#implementation CITWCore
- (id)init
{
self = [super init];
if (self) {
RKObjectManager *manager = [RKObjectManager objectManagerWithBaseURL:#"http://localhost:4567"];
// Initialization code here.
}
return self;
}
#end
And my unit test class:
#import "CITWCoreTests.h"
#implementation CITWCoreTests
- (void)testItCreatesAnInstance
{
CITWCore *newCoreObject = [[CITWCore alloc]init];
STAssertNotNil(newCoreObject, #"new object should not be nil");
}
#end
When I run the tests using ⌘U the test fails with this message:
error: testExample (CITWCoreTests) failed: -[__NSCFString isIPAddress]: unrecognized selector sent to instance 0xa115880
The error is being triggered by line 292 in RKClient.m
if ([newBaseURLString isEqualToString:#"localhost"] || [hostName isIPAddress]) {
There is a header file in the RestKit project called "NSString+RestKit.h" which contains the -isIPAddress method declaration, and as far as I can tell it is getting included, so I have no idea why the compiler/run-time does not know about that particular method. Is there something wrong with the way I've configured my testing target? How can I create an instance of RKObjectManager and get this test to pass?
More abstractly: How are people managing dependencies like this? I'm looking at things like VenderKit, but it seems lacking in documentation and I don't think I have the proper understanding of how compilers and linkers work to go to that big of an abstraction. What are some general guidelines when linking static libraries into my project, which is itself a static library?
Double check that your project build settings for "Other Linker Flags" has "-all_load" and "-ObjC" on your build target. While you are in there, check that you created the "Header Search Paths" entry ("$(SOURCE_ROOT)/RestKit").
The "Installing-RestKit-in-Xcode-4.x" page that you linked to, is slightly out of date with a) Xcode and b) RestKit HEAD (the build process was simplified recently. FMI see the mailing list.
If you want to see a project correctly setup (I just created it recently, with the newest Xcode and Restkit) take a look at https://github.com/lottadot/lottadot-restkit-ios-rails3-1-advanced
My guess is if you clone that project, edit it's configuration and remove "-all_load" you will see the exact same error, when you run it.
In this case, you need to find the file (or image/library) which defines/exports -[NSString isIPAddress]. Then you would need to add that file to your compile phase (if it is a source file), or link the library to your final binary (if it is a library or object file). In addition to linking it to your app, you will also need to compile and or link it into your unit test executable.
I know RestKit is 'installed' correctly into my project because when I do #import the project builds just fine.
#importing will not necessarily link or compile all of the necessary dependencies. You may have to do this manually. Xc4 may detect the dependency automatically, and build and link it for you if the option is enabled -- but it does not always get it right (it's good for basic dependencies).
Why is dependency management for obj-c projects such a pain?!
It's really not, IMO. Specifying files to compile and libraries to link with is something you'll need to get used to when compiling C family languages. Unless you want to be more specific about this criticism…
How are people managing dependencies like this?
Add the dependent projects to your Xcode projects. Configure them as build dependencies -- this will ensure they build before your app is built, and that the builds are up to date. For static libraries (targeting iOS), save the link stage for the final executables. In more complex scenarios, you will want to use xcconfig files in order to easily define build settings for any/all dependencies.
One simple solution is to use cocoapods, which is good dependency management tool similar to maven in Java world.
CocoaPods is quite a powerful and maturing dependency management tool that can manage libraries, the libraries these depend on (transitive dependencies) as well as compiler and header flags.
It works by linking your project to another workspace that includes the libraries in source form, where the main target emits a static lib. This gives a good compromise between speed and being able to see the source-code.