Linking to J2ObjC from another CocoaPod - ios

We use J2ObjC and are trying to make the switch to Xcode 6's dynamic frameworks in order to incorporate Swift into the project. Simply adding use_frameworks! to our Podfile works great in the case where we're just using J2ObjC, but the problem comes when adding other libraries that reference it.
In this particular example, I have two pods in my Podfile, J2ObjC and any other pod that uses it. Let's call it whatever. The current J2ObjC podspec can be found here. Here's the podspec for whatever:
Pod::Spec.new do |s|
s.ios.deployment_target = '8.0'
s.requires_arc = true
s.source_files = '**/*.{h,m}'
s.dependency 'J2ObjC'
s.xcconfig = { 'HEADER_SEARCH_PATHS' => '${PODS_ROOT}/J2ObjC/dist/include',
'LIBRARY_SEARCH_PATHS' => '${PODS_ROOT}/J2ObjC/dist/lib' }
end
So far so good. Now, if I want to reference a Java class, say JavaUtilArrayList inside my app, I can do that.
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
JavaUtilArrayList *arrayList = [[JavaUtilArrayList alloc]init];
NSString *whatever = #"o hai";
[arrayList addWithId:[whatever copy]];
NSLog(#"%#", arrayList);
}
Awesome, J2ObjC works inside my main target. But if I try to do the same thing inside whatever, even though the compiler thinks everything is fine (J2ObjC imports work, classes are available, etc.), I get a linker error:
#import "SomeClass.h"
#import "java/util/ArrayList.h"
#implementation SomeClass // Inside 'whatever'
-(JavaUtilArrayList *)arrayList {
NSString *aThing = #"o hai";
JavaUtilArrayList *myList = [[JavaUtilArrayList alloc]init];
[myList addWithId:aThing];
NSLog(#"%#", myList);
return myList;
}
leads to:
Undefined symbols for architecture x86_64:
"_OBJC_CLASS_$_JavaUtilArrayList", referenced from:
objc-class-ref in SomeClass.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
I've been going crazy reading the CocoaPods guides, man ld, and the J2ObjC guides and am still not getting anywhere. Has anyone built a pod on top of J2ObjC and successfully installed it using use_frameworks!? Any advice would be super appreciated.

Any symbol begging with "_OBJC_CLASS" is from J2ObjC. If it begins "_OBJC_CLASS_$_Java" then it's from the Java Runtime Environment (JRE). If it doesn't have "$_Java" then see this answer.
The linker is missing out the libjre_emul.a library from J2ObjC (JRE emulation library). You need to configure the following:
LIBRARY_SEARCH_PATHS: J2OBJC_HOME/lib
OTHER_LDFLAGS: -l"jre_emul"
I'd suggest trying out the J2ObjC Gradle Plugin as it will automatically configure this for you. Alternatively, see the Xcode Build Rules.

Related

Pinterest Linker Error when added through CocoaPods

1)I have did all steps given at Pinterest developer site here
2)This is my pod file
# Uncomment this line to define a global platform for your project
platform :ios, ‘7.0’
# Uncomment this line if you're using Swift
# use_frameworks!
target 'xyz.com' do
pod "PinterestSDK", :git => "https://github.com/pinterest/ios-pdk.git"
end
target 'xyz.comTests' do
end
3)When I run without #import "PDKPin.h" & following code
[PDKPin pinWithImageURL:[NSURL URLWithString:imageUrl]
link:[NSURL URLWithString:shareUrl]
suggestedBoardName:#""
note:productName
withSuccess:^
{
NSLog(#"Succesful to pin");
}
andFailure:^(NSError *error)
{
NSLog(#"Failed to pin");
}];
it runs without error
4)But when I add the above code it gives linker error
Edit: I have tried it in blank project it works fine. But I am unable
to figure out what all the dependencies still there in old project.
Start Fresh
Use Xcode 7.1+, create a new project, run pod install:
target 'SO-34633492' do
pod "PinterestSDK", :git => "https://github.com/pinterest/ios-pdk.git"
end
You probably have inconsistencies in your existing project ; while figuring out what is wrong may be enlightening, may I suggest starting on a clean slate.
Must include headers
You cannot compile your .m without including #import <PDKPin.h>:
~/SO-34633492/SO-34633492/ViewController.m:21:6: Use of undeclared identifier 'PDKPin'
This does work:
#import <PDKPin.h>
NSString * imageUrl = #"";
NSString * shareUrl = #"";
NSString * productName = #"";
[PDKPin pinWithImageURL:[NSURL URLWithString:imageUrl]
link:[NSURL URLWithString:shareUrl]
suggestedBoardName:#""
note:productName
withSuccess:^
{
NSLog(#"Succesful to pin");
}
andFailure:^(NSError *error)
{
NSLog(#"Failed to pin");
}];
Things that may have gone wrong
Compare your projects: https://stackoverflow.com/a/2889730/218152
Delete Derived data: https://stackoverflow.com/a/32859942/218152
Library not found: https://stackoverflow.com/a/31419234/218152
Configuration error: https://stackoverflow.com/a/33509278/218152
Read more: https://stackoverflow.com/search?q=user%3A218152+cocoapod
After a long search & tries
I have found the following solution
I have changed the target's build settings in
the other linker flags section.
I have added the flag $(inherited) in other linker flags

Defining a new interface causes "Undefined symbols for architecture x86_64:". Existing interfaces work fine

I have an iOS app and am using XCode Version 6.3.1 (6D1002).
I have a m file in which I define
#interface CustomObject:NSObject {} #end
and I try to use in viewDidLoad as
CustomObject* obj = [[CustomObject alloc]init];
When I run this, I get linkage errors saying
Undefined symbols for architecture x86_64:
"_OBJC_CLASS_$_CustomObject", referenced from:
objc-class-ref in ChooseAlbumViewController.o
ld: symbol(s) not found for architecture x86_64
I have similar interfaces defined for other objects and those continue to build, link and run fine. Any new interfaces I'm defining are failing with these linkage errors. I could use some help to figure out what's causing this. I'm new to iOS development so if I'm missing information crucial to figure this out please let me know and I'll add it.
Few flags from my Build Settings that might help -
Build Active Architecture Only = YES
Architectures = Standard Architecture armv7 armv64
Valid Architectures = arm64 armv7 armv7s
Here is the code in which I define the interface and try to use it
#interface CustomAlbum : NSObject {
}
#end
#implementation ChooseAlbumViewController
{
}
- (void)viewDidLoad {
[super viewDidLoad];
CustomAlbum* a = [[CustomAlbum alloc] init];
}
Figured it out, the problem was that I had only defined an interface but had not defined an implementation. Adding
#implementation User
#end
to the .m file solved the linkage issues.
Thanks for the help guys
Most of the time, this happens when your class isn't being compiled into the target you want. Select the .m file that CustomObject is in and check the right sidebar. In the first tab, there should be a list of targets. Check ✔️ your current target so that Xcode compiles it.
while compiling the source file ChooseAlbumViewController looks for a corresponding header. The header named CustomAlbum doesn't match. This causes the error message.

Unable to integrate ZXingObjC in a iOS Swift Project

Im working on an iOS project, which shows the customer number in a barcode. I had installed the framework ZXingObjC with CocoaPods, described in GitHub.
I can compile my Project without errors. I can also use the classes of ZXingObjC in my Objective-C classes, without errors. After than, I have added the import Command #import <ZXingObjC/ZXingObjC.h> to my bridging header file, like my other custom objective-c classes, without compile errors. (I had testet the header file by destroying some import statements and got the expected file not found exception.)
But now, I can't use any class of ZXingObjC in my swift classes. I only got the following compile error: Use of undeclared type '...'. The Xcode autocomplete is not working, too.
e.g.
var test : ZXMultiFormatWriter?
>> Use of undeclared type 'ZXMultiFormatWriter'
I tried:
setup new project, same issue
checked header search path: $(SRCROOT)/Pods/Headers/Public/Adjust
reinstalled the ZXingObjC framework
checked build settings: Enable Modules: YES
checked build settings: Other Linker Flags: $(inherited) -ObjC
-framework "ZXingObjC"
checked linked binaries in the build phases: framework is added
checked import statement in the bridging header file (#import
<ZXingObjC/ZXingObjC.h> and #import "ZXingObjC/ZXingObjC.h" -- no
difference)
Windows style: restarting Xcode and Mac ;-)
I'm using:
Xcode: 6.3.2
CocoaPods: 0.37.2
Project Deployment target: iOS 8.0
SDK: 8.3
Does anyone know the problem? Can anyone help?
How can I make the ZXingObjC framework available in swift?
Actually it is an easy issue:
Podfile
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'
use_frameworks!
pod 'ZXingObjC', '~> 3.1'
So, on terminal:
cd workspace
pod install
Then, once opened project on Xcode, you have to edit bridging-header adding ZXingObj:
#import <ZXingObjC/ZXingObjC.h>
Finally, in your swift classes that uses ZXingObjC, you have to import ZXingObjC.
import ZXingObjC
class ZXingObjCWrapper {
func encode() {
let writer = ZXMultiFormatWriter.writer()
....
}
}
The rest of the code for when you need to set an UIImage with this bar code:
func generateDataMatrixQRCode(from string: String) -> UIImage? {
do {
let writer = ZXMultiFormatWriter()
let hints = ZXEncodeHints() as ZXEncodeHints
let result = try writer.encode(string, format: kBarcodeFormatDataMatrix, width: 1000, height: 1000, hints: hints)
if let imageRef = ZXImage.init(matrix: result) {
if let image = imageRef.cgimage {
return UIImage.init(cgImage: image)
}
}
}
catch {
print(error)
}
return nil
}
The header search path was not correct in my project. The right values are:
$(inherited)
"${PODS_ROOT}/Headers/Public"
"${PODS_ROOT}/Headers/Public/ZXingObjC"
The second and third lines were not added by installation with CocoaPods.
EDIT: The installed framework have to be added to "Embedded Binaries" in General tab of the project.
I tried everything on this page to add ZXingObjC as a Pod. My goal was to generate an Aztec barcode.
I checked my Header Search Path. As Reddas said, I had to manually add "${PODS_ROOT}/Headers/Public/ZXingObjC". I also added ZXingObjC as an Embedded Binary (in the General Tab).
I checked my bridging file & all was good. I checked my view controllers where I wanted to generate the barcode. The import ZXingObjC was there.
No compile errors. But I can't declare a variable of ZXingObjC.
No luck. Any more suggestions?
EDIT - I went into the Targets, Build Settings and searched for Header Search Paths. I added in BOTH "${PODS_ROOT}/Headers/Public/ZXingObjC" and "${PODS_ROOT}/Headers/Private/ZXingObjC"
This seemed to unclog whatever broke. It works now. Strangely, I can now even delete those entries and it works.

Can't allocate anything from my project - static library (using XCTests)

When i try tests like
#interface My_Tests : XCTestCase
- (void)testExample {
XCTAssertTrue(#YES, #"has to be passed");
}
Everything is working fine. However when i try such pattern:
#import "NSString+Additions.h"
//...
- (void)testNameValidation {
NSString *string = #"Harry";
XCTAssertTrue([string stringIsValid], #"Name validation error");
}
I get:
file:///Users/username/project/ProjectTests/ProjectTest.m: test failure:
-[Project_test testNameValidation] failed: (([string stringIsValid]) is true)
failed: throwing "-[__NSCFConstantString stringIsValid]: unrecognized selector
sent to instance 0x2f58ae8" - Name validation error
I can also just do something like this:
#import "MyViewController.h"
//...
- (void)testSomething {
MyViewController *a = [[MyViewController alloc] init];
XCTAssertTrue(#YES, #"Impossible!");
}
I get 2 errors (first and last line):
Undefined symbols for architecture i386:
"_OBJC_CLASS_$_MyViewController", referenced from:
objc-class-ref in MyTest.o
ld: symbol(s) not found for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Can someone explain me what am I doing wrong..? I can't do anything with my classes. It may be worth adding that i'm trying to test my custom static library and files included in it. I'm using CocoaPods and I've set environment basing on Kiwi description (only to be able to use CocoaPods files in my tests, I was also wondering whether to use Kiwi or XCTests).
PS. This is my first try with unit tests of any type, so please forgive eventual noobish question ;)
The unit tests aren't linked against the static library.
Add the library to the "Link Binary with Libraries" section of the build phases for the test target.

iOS. Cannot run a project after updating cocos2d library inside this project

It cannot compile sources and writes:
Undefined symbols for architecture i386:
"_CTFontManagerRegisterFontsForURL", referenced from:
-[CCLabelTTF getFontName:] in CCLabelTTF.o ld: symbol(s) not found for architecture i386 clang: error: linker command failed with
exit code 1 (use -v to see invocation)
but when I replace all the code in the following function in CCLabelTTF with "return nil":
- (NSString*) getFontName:(NSString*)fontName
{
// Custom .ttf file ?
if ([[fontName lowercaseString] hasSuffix:#".ttf"])
{
// This is a file, register font with font manager
NSString* fontFile = [[CCFileUtils sharedFileUtils] fullPathForFilename:fontName];
NSURL* fontURL = [NSURL fileURLWithPath:fontFile];
CTFontManagerRegisterFontsForURL((CFURLRef)fontURL, kCTFontManagerScopeProcess, NULL);
return [[fontFile lastPathComponent] stringByDeletingPathExtension];
}
return fontName;
}
then I can compile my code but I cannot use labels.
So how to solve this without creating of a new project and copying all the sources to it?
EDITED
Previous version is 2.x, now I have the last rc2 version.
I have deleted all the files of the old library, copied the files from the new library into the project folder and added them to project via xcode. xcode can create projects with a new library files, so I took them from this new project. Then I made some changes to remove warnings.
Solved by importing CoreText.framework
But I think I will create a new project because I still have some troubles with identifying of iphone5 screen size

Resources