How to resolve "redefinition of enumerator" errors from separate objc frameworks
Asked Answered
A

2

7

Both the AuthNet and PayPal mobile payment libraries have the ENV_LIVE enumerator defined. This reults in Xcode errors like:

Redefinition of enumerator 'ENV_LIVE' ...

In cases like this where one cannot afford to simply change the source code of dependent frameworks, what are some workarounds available in objective-c syntax or xcode configuration?

INITIALLY:

#import "PayPal.h"
#import "AuthNet.h"
...
// AuthNet
[AuthNet authNetWithEnvironment:ENV_TEST];

// PayPal
if (STATUS_COMPLETED_SUCCESS == [PayPal initializationStatus]) {
    [PayPal initializeWithAppID:@"APP-XXX" forEnvironment:ENV_SANDBOX];
}

UPDATE (here's what I ended up using as a workaround based on the correct answer):

#import "PayPal.h"
@class AuthNet;
#import "AuthNetWorkaround.h"
...
[AuthNet authNetWithEnvironment:AUTHNET_ENV_TEST];

extern const int AUTHNET_ENV_LIVE;
extern const int AUTHNET_ENV_TEST;

@interface AuthNetWorkaround : NSObject

@end

#import "AuthNetWorkaround.h"
#import "AuthNet.h"

@implementation AuthNetWorkaround

const int AUTHNET_ENV_LIVE = ENV_LIVE;
const int AUTHNET_ENV_TEST = ENV_TEST;

@end
Astro answered 22/3, 2012 at 21:13 Comment(2)
Do you see the error when you include the headers for both frameworks in the same .m file?Muenster
Yes, in that same file - appdelegate - I actually need to initialize both libraries and connect to either live or prod servers.Astro
M
5

This happens because both inclusions happen in the same compilation unit. You can work around this problem by moving the inclusion of one of the enums into a separate compilation unit, at a cost of making the values of that enumerator non-compile-time constants (in fact, they become global variables).

In pp_workaround.h:

extern const int PAYPAL_ENV_LIVE;

In pp_workaround.m:

#import "PayPal.h" // I'm completely making up the name of PayPal's header
// The import of "AuthNet.h" is missing

const int PAYPAL_ENV_LIVE = ENV_LIVE;

Now you can include "pp_workaround.h" instead of "PayPal.h", and use PAYPAL_ENV_LIVE instead of ENV_LIVE. Not everything will work the same, but the compile-time error should be gone.

EDIT If your code lets you import the conflicting headers only in your .m file, you can fix the problem (rather than working around it) by wrapping the connection code in an additional abstraction layer of your own, like this:

In the paypal_init.h:

extern void connect_paypal();

In the paypal_init.m:

#import "PayPal.h"
#import "paypal_init.h"

void connect_paypal() {
    // Use ENV_LIVE from PayPal.h here
}

in the authnet_init.h:

extern void connect_authnet();

in the authnet_init.m:

#import "AuthNet.h"
#import "authnet_init.h"

void connect_authnet() {
    // Use ENV_LIVE from AuthNet.h here
}

In your main file:

#import "authnet_init.h"
#import "paypal_init.h"

void init() {
    connect_paypal();
    connect_authnet();
}
Muenster answered 22/3, 2012 at 21:27 Comment(6)
What are you suggesting when you say "not everything will work the same"? what should i be on the look out for?Astro
@Astro Several C constructs require compile-time constants. For example, if you need to declare an array int vals[ENV_MAX] the standard requires ENV_MAX to be a compile-time constant. The compiler will always tell you that something is broken, though, so if everything compiles, you will be fine.Muenster
thanks a bunch for keeping this disc. going ... I followed the extern advice and am running into Undefined symbols for architecture i386: "_OBJC_CLASS_$_AuthNet", referenced from: objc-class-ref in Shoppin_PalAppDelegate.o objc-class-ref in CardProcessingUtils.o (maybe you meant: _OBJC_CLASS_$_AuthNetWorkaround)Astro
BTW I decided to extern the authnet stuff over the paypal stuffAstro
@Astro It looks like you did not add the AuthNet library to your project properly. If you search, say, Google, for "Undefined symbols for architecture i386" you will see multiple suggestions on how to fix this link problem; here is one.Muenster
@ dasblinkenlight right on! Thanks so much for sticking with me to resolve this.Astro
R
1

I just had this error, and a clean before building fixed the issue for me.

Rashid answered 31/5, 2013 at 7:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.