XCode 4.5, Static Libraries, and Categories - objective-c

I'm trying to use a static library, and the categories that are in it aren't being used at run-time. There are no compile-time errors, but when I go to run, I get the standard 'unrecognized selector sent to instance' message and my app crashes.
Many solutions say to add -ObjC -all_load to the "Other Linker Flags" property in your application's target (many others say that as of XCode 4, that is no longer needed, this is the only reason I have bothered to include the XCode version). I've tried it and I get 115 errors during build:
Undefined symbols for architecture i386:
"_CLLocationCoordinate2DMake", referenced from:
-[QMapElement init] in libQuickDialog.a(QMapElement.o)
"_OBJC_CLASS_$_MKMapView", referenced from:
objc-class-ref in libQuickDialog.a(QMapViewController.o)
"_OBJC_CLASS_$_MKPinAnnotationView", referenced from:
objc-class-ref in libQuickDialog.a(QMapViewController.o)
"std::istream::gcount() const", referenced from:
GT::AES::decode(std::istream&, std::ostream&, unsigned int&, bool) in GD(gtaes.o)
GT::AES::encode(std::istream&, std::ostream&, unsigned int&, bool) in GD(gtaes.o)
"std::string::find_first_of(char const*, unsigned long, unsigned long) const", referenced from:
-[GDSetPasswordViewController checkPasswordStrength:] in GD(GDSetPasswordViewController.o)
GD::EacpCReq::EacpCReq(std::string, std::string, GT::Dbb&) in GD(GDEacpCommands.o)
GD::RawSocket::connect() in GD(GDRawSocket.o)
"std::string::copy(char*, unsigned long, unsigned long) const", referenced from:
GD::Socket::toString() const in GD(GDSocket.o)
(and so on, that's about 5 or 6 of the 115).
Whether I have either of those linker flags, or both, I get the exact same set of errors.
Not sure if this is the culprit, or just coincidental, but after looking at the errors a little more closely, it seems like they are all from one of two 3rd-party libraries I am using. One as an installed .framework, the other as a regular static library. Maybe I need to do something to their builds (if possible), as well?
Thanks!

It seems to me that the error message is pointing to a few missing frameworks:
CoreLocation (_CLLocationCoordinate2DMake symbol);
MapKit (_OBJC_CLASS_$_MKPinAnnotationView symbol);
C++ standard library.
Try to include them with your target... specifically, for the C++ standard library, you should check a specific build setting in Xcode under "Apple LLVM Compiler x.y - Language".
This will not rule out the chance of other missing frameworks, of course...

Related

Importing Objective-c framework in Swift?

I'm trying to import a library of objective-c into swift. I've created a bridging file (a .h) and added it to the build settings, in Objective-C Bridging Header under Swift Compiler - General. Into the bridging file I've added #import <MyFramework>.
The problem comes now. This framework is private and particular. To install it correctly in Objective-C they told you to change the main.m to main.mm (which don't have sense in swift).
When I try to build the project I get 111 errors (Apple Mach-O linker error). It start with:
Undefined symbols for architecture x86_64:
And all the errors are similar to:
std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::__grow_by(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long)", referenced from:
So I really don't understand it. Do you have any clue why is this happening?
If you need me to post some more information just tell me.
Thanks for the help.
.mm extension is used for using c++ code .. std :: is c++ code. you just need to edit yourBridgingHeaderFile.m to YourBridingHeaderName.mm and you would be good to go

how do I bridge a function taking a closure as a parameter to objc

I have
func verifyEmail(let email: String, let completionHandler:(Bool) -> Void) -> Bool
{
in my (swift) framework
exposing it as
FOUNDATION_EXPORT BOOL verifyEmail(NSString *email, void (^completionHandler)(BOOL verificationResult));
in my framework umbrella header
attempting to call it like so
verifyEmail(#"dfs", ^(BOOL verificationResult) {
NSLog(#"objc: using sdk v%f", whateverSdkVersionNumber);
});
in objective c sample code results in a link error:
Undefined symbols for architecture arm64:
"_verifyEmail", referenced from:
-[ObjCExample verify] in ObjCExample.o
ld: symbol(s) not found for architecture arm64
Same with other functions exported but if I can map closures
to blocks or whatever I'll surely fix the rest :^)
Resolved: converted globals to class func()s
You cannot access Swift functions declared in global scope in your Objective-C code. Per documentation:
You’ll have access to anything within a class or protocol that’s marked with the #objc attribute as long as it’s compatible with Objective-C. This excludes Swift-only features such as those listed here:
Generics
Tuples
Enumerations defined in Swift
Structures defined in Swift
Top-level functions defined in Swift
Global variables defined in Swift
Typealiases defined in Swift
Swift-style variadics
Nested types
Including FOUNDATION_EXPORT ... in your umbrella header exposes only the function's definition, the symbol itself is not ported to Objective-C.

struct addrinfo undeclared in Xcode 4

I'm running in to some strange errors when dabbling in some socket programming using Xcode 4. I get the error that addrinfo is undeclared, despite me simply copying the code from another project that did work (when using Xcode 3). The project is mainly in Objective-C, but I've tested creating another framework with plain C, and the error still remains.
I have the following frameworks included:
ApplicationServices.framework
Cocoa.framework
AppKit.framework
Foundation.framework
No added linker flags either.
However, other functions such as getaddrinfo (that uses addrinfo itself!) exists. Any ideas?
This issue wasn't IDE-related, it was a language issue. How structs are treated is apparently different in C (and thus Objective-c) and C++ (which the previous projects were=. So I changed the line
addrinfo hints;
To:
struct addrinfo hints;
Have you got the correct imports?
#import <netinet/in.h>
#import <sys/socket.h>
A quick grep shows that struct addrinfo is declared in <netdb.h>. Try explicitly including that. (Your Xcode 3 project may have included that, or some other header that includes it, in its prefix file.)

sqlite3 compile error with llvm compiler

Compiling my project on new xcode4 using llvm 2.0 compiler I get a strange error coming from standard <sqlite3.h> header. Problem is with the following line:
//<sqlite3.h>
typedef struct sqlite3 sqlite3;
Error message:
In file included from /Projects/trunk/MyProj/Classes/StatsProvider.m:14:
Elaborated type refers to a non-tag type in /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.3.sdk/usr/include/sqlite3.h
Using GCC 4.2 project compiles with no problem
How can I fix that error?
My guess: you are compiling sqlite as C++ code, whereas you should compile it as plain C code. class/struct keywords implicitly introduce a typedef in C++, but not so in C.
I interpret the error message as the compiler complaining about using struct sqlite3 when it hasn't seen a struct declaration with that name. Struct names are in a special "tag-space".
My next guess is that the new compiler is stricter than the old one, and has found a bug.

g++ compiler complains about conversions between related types (from int to enum, from void* to class*...)

g++ compiler complains about conversions between related types (from int to enum, from void* to class*, from const char* to unsigned char*, etc.). Compiler handles such convertions as errors and won't compile furthermore. It occurs only when I compile using Dev-C++ IDE, but when I compile the same code (using the compiler which Dev-C++ uses) such errors (even warnings) do not appears.
How to mute errors of such types?
I suspect that in one case you are compiling your code as C and the other as C++. In C++, there is no implicit conversion from void * to any other type of pointer, and a C++ compiler which did not diagnose this as an error would be broken. You need to supply more details of how you are compiling your code.
Also, DevC++ is a pretty awful piece of code. It's buggy and no longer being actively developed, as well as being butt-ugly. You should seriously consider switching to a more modern and capable IDE, such as Code::Blocks.
All of your implicit conversions are disallowed in standards conforming C++. G++ is simply enforcing these rules.