I am using the GData static library in my app that uses ARC. Google's instructions say to link the header files from the library to the project target.
The problem is that when I do so I get compiler errors as the GData library is not compatible with ARC.
Google states that:
ARC Compatibility
When the library source files are compiled directly into a project that uses ARC, then ARC must be disabled specifically for the library sources.
To disable ARC for source files in Xcode 4, select the project and the target in Xcode. Under the target "Build Phases" tab, expand the Compile Sources build phase, select the library source files, then press Enter to open an edit field, and type -fno-objc-arc as the compiler flag for those files.
(reference)
But since I have only the header files I can not use this flag in the app target.
Well I asked and found the unswear 10 minutes later. Any way if it will help someone:
The problem is only with the .h files, Goole remark is only for cases you embed the library not as static library.
After someone reported the problem to google, they added new macros that solve the problem, this is how:
search the header files for file named : GDataDefines.h
and add this code inside:
//
// Simple macros to allow building headers for non-ARC files
// into ARC apps
//
#ifndef GDATA_REQUIRES_ARC
#if defined(__clang__)
#if __has_feature(objc_arc)
#define GDATA_REQUIRES_ARC 1
#endif
#endif
#endif
#if GDATA_REQUIRES_ARC
#define GDATA_UNSAFE_UNRETAINED __unsafe_unretained
#else
#define GDATA_UNSAFE_UNRETAINED
#endif
Then in the GDataObject.h which causes the ARC errors
Change the GDataDescriptionRecord struct to
typedef struct GDataDescriptionRecord {
NSString GDATA_UNSAFE_UNRETAINED *label;
NSString GDATA_UNSAFE_UNRETAINED *keyPath;
GDataDescRecTypes reportType;
} GDataDescriptionRecord;
And the
__weak GDataObject *parent_; // parent in tree of GData objects
to
GDataObject GDATA_UNSAFE_UNRETAINED *parent_;
This is the link to google update:
http://code.google.com/p/gdata-objectivec-client/source/detail?r=712
That's it.
Hope it will help someone
Shani
Related
I'm writing a Cocoa Touch Static Library in Objective-C. It will be distributed through Cocoapods and the developers using it should also be able to do this in Swift.
In my test projects the library can be used perfectly in Objective-C, but in Swift I get the compiler error: No such module MyLibrary.
In the Library Target Defines Module is set to YES. According to the Apple guide here, that's the only thing one must do: https://developer.apple.com/library/content/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.html
To implement pch file in existing swift project:
File > New > File... (macOS app for your case)
then you can import your Objective-C library like this in your pch file (test.pch is my file)
#ifndef test_pch
#define test_pch
#import <YourLib/YourLibMainClass.h>
// Include any system framework and library headers here that should be included in all compilation units.
// You will also need to set the Prefix Header build setting of one or more of your targets to reference this file.
#endif /* test_pch */
Now you need to tell your project there is a pch file.
Go to your target build setting and make a search for "Prefix Header".
At Apple LLVM 8.0 - Language section add value for Prefix header key (be careful with your pch file project path)
You will could import your library on a swift file
import YouLibrary
I have a swift base project iPhone app. I would like to use Zoiper SDK within it.
What I got from them are static libraries (.a files):
- libcrypto.a
- libsipwrapper.a
- libssl.a
written probably in Objective-C.
And also external header files
- wrapper_defs.h,
- wrapper_cbk.h,
- wrapper.h
written in Objective-C.
I tried to add bridging header like this:
#ifndef ZoiperTest_Bridging_Header_h
#define ZoiperTest_Bridging_Header_h
#import "include/wrapper_defs.h"
#import "include/wrapper_cbk.h"
#import "include/wrapper.h"
#endif /* ZoiperTest_Bridging_Header_h */
But that returned lots of errors (types used in wrapper.h not being recognized)
Do I have to include also library .a files into bridging header?
What would be exact syntax for that?
I've tried adding #import into bridge header but that gives me file not found error.
I could integrate zoiper SDK on a swift project. The easy way for me was create an Static Library on Objetive-C with the libs and integrate this on my swift project. -> https://github.com/depazsierra/zoiperExample
On the static library, i reused the ZSDKLibControl that came with zoiper example.
Any question, just let me know.
What you can do is the following and it worked for me. Create a static library from scratch. Add the .h (wrappers), including the LibController from the demo. Then once you finish follow this link: How can I use an .a static library in swift?
I was able to use the methods and all but not fully tested yet.
I have a project that uses CocoaPods and uses the 'SCLAlertView-Objective-C' pod. That pod uses the #import UIKit; module style import. I've set "Enable Modules (C & Objective-C)" and the "Link Frameworks Automatically" to YES in both my target and project settings. I am still getting the "Use of '#import' when modules are disabled" error.
Is there anything that could prevent Xcode from being able to enable Modules such as the use of a .pch file, any linker flags, or anything else I haven't mentioned? I also tried to clean the project and the project build folder. That didn't have any effect.
Also worth noting is that my project has multiple targets and also has a deployment target of iOS 7.0. My Base SDK is set to iOS 8.3.
I guess your project contains XXX.mm files, however, the xcode only enable C and objective-c modules.
Please have a look at this answer for your reference:
Using #import in objective C in conjunction with __cplusplus
my solution is modify the #import xxx into #import .
Good luck.
I just solved this in a primarily ObjC++ project I was working on that needed to use Firebase.
Simply make a ObjC (.m) file which contains the following.
#import <Foundation/Foundation.h>
#import Firebase; // << swap this for your specific import
That's it, then simply use #include in your .mm files for the specific headers you need. For me that meant:
#include <"Firebase/Firebase.h">
#include <"FirebaseAuth/FirebaseAuth.h">
Just to stress the point, no amount of fiddling with link options made any difference to this "Enable Modules (C & Objective-C)" was already YES. Upgrading to XCode7 didn't seem to help.
Hope this helps someone :)
The build option does not really work as it should. I've solved this problem by adding -fcxx-modules (Objective C++) or -fmodules (Objective C) manually to "C Flags"/"C++ Flags".
Worked for me.
I added two files to a Xcode 5.1 vanilla single view project:
table.h
struct group {
int size;
};
table.c
#include "table.h"
and got this error:
Semantic issue
table.h:2:8: Redefinition of 'group'
"Previous definition" is:
iOS 7.1 > usr/include > grp.h
I am wondering why this grp.h is automatically included in my project. How can I not include it?
grp.h is one of the standard Unix-level files which defines some of the basic data structures; in this case, struct group is what gets returned by low-level C functions that deal with user permissions.
As for the question of why it's included in your project: When you create a new project in Xcode, it creates an include file that implicitly gets included in every .m or .c file in your project. In the project I just created to try this out, it's in the file browser in a group called Supporting Files, named something like [project]-Prefix.pch. Mine has the following contents:
#import <Availability.h>
#ifndef __IPHONE_5_0
#warning "This project uses features only available in iOS SDK 5.0 and later."
#endif
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#endif
That second to last line, #import <Foundation/Foundation.h>, then includes all the built-in Objective-C objects like NSObject, NSArray - and a bunch of things that work with the filesystem, and therefore need to be able to deal with permissions and group membership. One of those is then including grp.h.
So, back to your question - you can change your .pch file to not include Foundation/Foundation.h, and then manually include it wherever you need it.
But that will end up slowing down all your builds. The .pch file here is special; Xcode compiles it once and saves it in a binary format, so it doesn't have to parse the many thousands of lines of C code it expands to for every file you build.
My advice? Name your structure something else.
Normally of course it would be easier to change the naming of your struct, but as it comes from another library, here is my solution for you.
Turns out that if you allow your .pch file to include any of header files from iOS 7.1 > /usr/include then it will reference (include?) many more, including grp.h which causes the problem in your project.
So for example, if your .pch files contains this:
#import <Availability.h>
Then grp.h will cause the conflict.
If you comment out this line (and don't include any other headers from "iOS 7.1 > usr/include") then your project will compile.
As a test you can comment out <Availability.h> and add #import <cpio.h> and the result will be the same (although cpio.h is very small and don't reference any other header files).
I am not that good at understanding internals of compilation, so I can't explain why this happens but I traced down the issue to this file:
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator7.1.sdk/usr/include/module.map which seems to group together various Darwin header files.
Both iOS 7.0 and iOS 7.1 have this file while iOS 6.0 doesn't (which may explain why the same code worked on earlier iOS versions).
The good news is that although you need to remove /usr/include headers from your *.pch file, you can still include them in files where you actually need them and it won't break the compilation. That's probably because although the grp.h will eventually be included in those files, it won't be included in your table.c
grp.h has already declared a struct named 'group',
so you just need to rename your 'group' struct and everything will be ok.
(for example 'my_group')
There is a library that causes build errors when the project builds for the simulator.
Is there a way to set a flag in the build settings or somewhere else to make the compiler NOT link the specific library when building for the simulator?
This could be done by creating a new Target, but I would prefer not having to create a whole new target.
What would be the most convenient solution for something like this? (which works both in XCode 4 and 5)
You can #ifdef out the #import calls to the library using:
#ifdef TARGET_IPHONE_SIMULATOR
#import <...>
#endif
If you do that then the code won't try to link with the library.