views:

711

answers:

1

I recently upgraded to the iOS4 SDK and my app no longer compiles for the simulator, but does compile for the device.

This is due to the 3rd party library libGoogleAnalytics.a. The solution seems to be for google to release a new static library complied with the new SDK, unfortunately there is no word of any release date, and due to the new SDK licensing, they may never release a new library.

http://www.google.com/support/forum/p/Google+Analytics/thread?tid=0e35876711dc99b1&hl=en

I am getting the following compile errors:

Undefined symbols: ".objc_class_name_NSObject", referenced from: .objc_class_name_GANTCPSocket in libGoogleAnalytics.a(GANTCPSocket.o) .objc_class_name_GTMLogger in libGoogleAnalytics.a(GTMLogger.o) .objc_class_name_GTMLogBasicFormatter in libGoogleAnalytics.a(GTMLogger.o) .objc_class_name_GTMLogLevelFilter in libGoogleAnalytics.a(GTMLogger.o) .objc_class_name_GTMLogNoFilter in libGoogleAnalytics.a(GTMLogger.o) .objc_class_name_GTMLogASLWriter in libGoogleAnalytics.a(GTMLogger+ASL.o) .objc_class_name_GTMLoggerASLClient in libGoogleAnalytics.a(GTMLogger+ASL.o) .objc_class_name_GANDataDispatcher in libGoogleAnalytics.a(GANDataDispatcher.o) .objc_class_name_GANHTTPResponseParser in libGoogleAnalytics.a(GANHTTPResponseParser.o) .objc_class_name_GANEvent in libGoogleAnalytics.a(GANEvent.o) .objc_class_name_GTMLoggerRingBufferWriter in libGoogleAnalytics.a(GTMLoggerRingBufferWriter.o) .objc_class_name_GANTracker in libGoogleAnalytics.a(GANTracker.o) .objc_class_name_GANPersistentEventStore in libGoogleAnalytics.a(GANPersistentEventStore.o) ".objc_class_name_NSFileManager", referenced from: literal-pointer@_OBJC@_cls_refs@NSFileManager in libGoogleAnalytics.a(GANPersistentEventStore.o) ".objc_class_name_NSString", referenced from: literal-pointer@_OBJC@_cls_refs@NSString in libGoogleAnalytics.a(GTMLogger.o) literal-pointer@_OBJC@_cls_refs@NSString in libGoogleAnalytics.a(GANTracker.o) literal-pointer@_OBJC@_cls_refs@NSString in libGoogleAnalytics.a(GANPersistentEventStore.o) ".objc_class_name_NSError", referenced from: literal-pointer@_OBJC@_cls_refs@NSError in libGoogleAnalytics.a(GANTracker.o) literal-pointer@_OBJC@_cls_refs@NSError in libGoogleAnalytics.a(GANPersistentEventStore.o) ".objc_class_name_NSFileHandle", referenced from: literal-pointer@_OBJC@_cls_refs@NSFileHandle in libGoogleAnalytics.a(GTMLogger.o) ".objc_class_name_NSMutableString", referenced from: literal-pointer@_OBJC@_cls_refs@NSMutableString in libGoogleAnalytics.a(GANDataDispatcher.o) ".objc_class_name_NSTimer", referenced from: literal-pointer@_OBJC@_cls_refs@NSTimer in libGoogleAnalytics.a(GANTracker.o) ".objc_class_name_NSMutableArray", referenced from: literal-pointer@_OBJC@_cls_refs@NSMutableArray in libGoogleAnalytics.a(GANDataDispatcher.o) literal-pointer@_OBJC@_cls_refs@NSMutableArray in libGoogleAnalytics.a(GANPersistentEventStore.o) ".objc_class_name_UIScreen", referenced from: literal-pointer@_OBJC@_cls_refs@UIScreen in libGoogleAnalytics.a(GANDataDispatcher.o) ".objc_class_name_NSProcessInfo", referenced from: literal-pointer@_OBJC@_cls_refs@NSProcessInfo in libGoogleAnalytics.a(GTMLogger.o) "_objc_exception_extract", referenced from: +[GTMLogger sharedLogger] in libGoogleAnalytics.a(GTMLogger.o) +[GTMLogger setSharedLogger:] in libGoogleAnalytics.a(GTMLogger.o) -[GTMLogger setWriter:] in libGoogleAnalytics.a(GTMLogger.o) -[GTMLogger setFormatter:] in libGoogleAnalytics.a(GTMLogger.o) -[GTMLogger setFilter:] in libGoogleAnalytics.a(GTMLogger.o) -[NSFileHandle(GTMFileHandleLogWriter) logMessage:level:] in libGoogleAnalytics.a(GTMLogger.o) -[NSArray(GTMArrayCompositeLogWriter) logMessage:level:] in libGoogleAnalytics.a(GTMLogger.o) -[GTMLogStandardFormatter stringForFunc:withFormat:valist:level:] in libGoogleAnalytics.a(GTMLogger.o) -[GTMLoggerRingBufferWriter count] in libGoogleAnalytics.a(GTMLoggerRingBufferWriter.o) -[GTMLoggerRingBufferWriter droppedLogCount] in libGoogleAnalytics.a(GTMLoggerRingBufferWriter.o) -[GTMLoggerRingBufferWriter reset] in libGoogleAnalytics.a(GTMLoggerRingBufferWriter.o) -[GTMLoggerRingBufferWriter dumpContents] in libGoogleAnalytics.a(GTMLoggerRingBufferWriter.o) -[GTMLoggerRingBufferWriter logMessage:level:] in libGoogleAnalytics.a(GTMLoggerRingBufferWriter.o) +[GANTracker sharedTracker] in libGoogleAnalytics.a(GANTracker.o) +[GANTracker allocWithZone:] in libGoogleAnalytics.a(GANTracker.o) -[GANTracker startTrackerWithAccountID:dispatchPeriod:delegate:] in libGoogleAnalytics.a(GANTracker.o) -[GANTracker trackPageview:withError:] in libGoogleAnalytics.a(GANTracker.o) -[GANTracker trackEvent:action:label:value:withError:] in libGoogleAnalytics.a(GANTracker.o) -[GANTracker stopTracker] in libGoogleAnalytics.a(GANTracker.o) -[GANTracker dispatch] in libGoogleAnalytics.a(GANTracker.o) ".objc_class_name_NSDate", referenced from: literal-pointer@_OBJC@_cls_refs@NSDate in libGoogleAnalytics.a(GTMLogger.o) literal-pointer@_OBJC@_cls_refs@NSDate in libGoogleAnalytics.a(GANPersistentEventStore.o) ".objc_class_name_UIDevice", referenced from: literal-pointer@_OBJC@_cls_refs@UIDevice in libGoogleAnalytics.a(GANDataDispatcher.o) "_objc_exception_try_exit", referenced from: +[GTMLogger sharedLogger] in libGoogleAnalytics.a(GTMLogger.o) +[GTMLogger setSharedLogger:] in libGoogleAnalytics.a(GTMLogger.o) -[GTMLogger setWriter:] in libGoogleAnalytics.a(GTMLogger.o) -[GTMLogger setFormatter:] in libGoogleAnalytics.a(GTMLogger.o) -[GTMLogger setFilter:] in libGoogleAnalytics.a(GTMLogger.o) -[NSFileHandle(GTMFileHandleLogWriter) logMessage:level:] in libGoogleAnalytics.a(GTMLogger.o) -[NSArray(GTMArrayCompositeLogWriter) logMessage:level:] in libGoogleAnalytics.a(GTMLogger.o) -[GTMLogStandardFormatter stringForFunc:withFormat:valist:level:] in libGoogleAnalytics.a(GTMLogger.o) -[GTMLoggerRingBufferWriter count] in libGoogleAnalytics.a(GTMLoggerRingBufferWriter.o) -[GTMLoggerRingBufferWriter droppedLogCount] in libGoogleAnalytics.a(GTMLoggerRingBufferWriter.o) -[GTMLoggerRingBufferWriter reset] in libGoogleAnalytics.a(GTMLoggerRingBufferWriter.o) -[GTMLoggerRingBufferWriter dumpContents] in libGoogleAnalytics.a(GTMLoggerRingBufferWriter.o) -[GTMLoggerRingBufferWriter logMessage:level:] in libGoogleAnalytics.a(GTMLoggerRingBufferWriter.o) +[GANTracker sharedTracker] in libGoogleAnalytics.a(GANTracker.o) +[GANTracker allocWithZone:] in libGoogleAnalytics.a(GANTracker.o) -[GANTracker startTrackerWithAccountID:dispatchPeriod:delegate:] in libGoogleAnalytics.a(GANTracker.o) -[GANTracker trackPageview:withError:] in libGoogleAnalytics.a(GANTracker.o) -[GANTracker trackEvent:action:label:value:withError:] in libGoogleAnalytics.a(GANTracker.o) -[GANTracker stopTracker] in libGoogleAnalytics.a(GANTracker.o) -[GANTracker dispatch] in libGoogleAnalytics.a(GANTracker.o) ".objc_class_name_NSDateFormatter", referenced from: literal-pointer@_OBJC@_cls_refs@NSDateFormatter in libGoogleAnalytics.a(GTMLogger.o) "_objc_exception_try_enter", referenced from: +[GTMLogger sharedLogger] in libGoogleAnalytics.a(GTMLogger.o) +[GTMLogger setSharedLogger:] in libGoogleAnalytics.a(GTMLogger.o) -[GTMLogger setWriter:] in libGoogleAnalytics.a(GTMLogger.o) -[GTMLogger setFormatter:] in libGoogleAnalytics.a(GTMLogger.o) -[GTMLogger setFilter:] in libGoogleAnalytics.a(GTMLogger.o) -[NSFileHandle(GTMFileHandleLogWriter) logMessage:level:] in libGoogleAnalytics.a(GTMLogger.o) -[NSArray(GTMArrayCompositeLogWriter) logMessage:level:] in libGoogleAnalytics.a(GTMLogger.o) -[GTMLogStandardFormatter stringForFunc:withFormat:valist:level:] in libGoogleAnalytics.a(GTMLogger.o) -[GTMLoggerRingBufferWriter count] in libGoogleAnalytics.a(GTMLoggerRingBufferWriter.o) -[GTMLoggerRingBufferWriter droppedLogCount] in libGoogleAnalytics.a(GTMLoggerRingBufferWriter.o) -[GTMLoggerRingBufferWriter reset] in libGoogleAnalytics.a(GTMLoggerRingBufferWriter.o) -[GTMLoggerRingBufferWriter dumpContents] in libGoogleAnalytics.a(GTMLoggerRingBufferWriter.o) -[GTMLoggerRingBufferWriter logMessage:level:] in libGoogleAnalytics.a(GTMLoggerRingBufferWriter.o) +[GANTracker sharedTracker] in libGoogleAnalytics.a(GANTracker.o) +[GANTracker allocWithZone:] in libGoogleAnalytics.a(GANTracker.o) -[GANTracker startTrackerWithAccountID:dispatchPeriod:delegate:] in libGoogleAnalytics.a(GANTracker.o) -[GANTracker trackPageview:withError:] in libGoogleAnalytics.a(GANTracker.o) -[GANTracker trackEvent:action:label:value:withError:] in libGoogleAnalytics.a(GANTracker.o) -[GANTracker stopTracker] in libGoogleAnalytics.a(GANTracker.o) -[GANTracker dispatch] in libGoogleAnalytics.a(GANTracker.o) ".objc_class_name_NSUserDefaults", referenced from: literal-pointer@_OBJC@_cls_refs@NSUserDefaults in libGoogleAnalytics.a(GTMLogger.o) ".objc_class_name_NSThread", referenced from: literal-pointer@_OBJC@_cls_refs@NSThread in libGoogleAnalytics.a(GTMLogger+ASL.o) ".objc_class_name_NSBundle", referenced from: literal-pointer@_OBJC@_cls_refs@NSBundle in libGoogleAnalytics.a(GANDataDispatcher.o) ".objc_class_name_NSAssertionHandler", referenced from: literal-pointer@_OBJC@_cls_refs@NSAssertionHandler in libGoogleAnalytics.a(GANTracker.o) literal-pointer@_OBJC@_cls_refs@NSAssertionHandler in libGoogleAnalytics.a(GANPersistentEventStore.o) ".objc_class_name_NSLocale", referenced from: literal-pointer@_OBJC@_cls_refs@NSLocale in libGoogleAnalytics.a(GANDataDispatcher.o) ld: symbol(s) not found collect2: ld returned 1 exit status

One suggestion on the google forum is to create a dummy implementation of the GANTracker class for use in the simulator. ie to create a file GANTracker_stub.m:

#import "GANTracker.h"

#if TARGET_IPHONE_SIMULATOR

@implementation GANTracker

+ (GANTracker *)sharedTracker
{
    return [[[GANTracker alloc] init] autorelease];
}

- (void)startTrackerWithAccountID:(NSString *)accountID
               dispatchPeriod:(NSInteger)dispatchPeriod
                     delegate:(id<GANTrackerDelegate>)delegate
{
}

- (void)stopTracker
{  
}

- (BOOL)trackPageview:(NSString *)pageURL
        withError:(NSError **)error
{
    return YES;
}

- (BOOL)trackEvent:(NSString *)category
        action:(NSString *)action
         label:(NSString *)label
         value:(NSInteger)value
     withError:(NSError **)error
{
    return YES;
}

- (BOOL)dispatch
{
    return YES;
}

@end
#endif

This however is not working for me, is there something I'm missing?

+4  A: 

Solution found via the Google Analytics forum:

Use:

lipo libGoogleAnalytics.a -remove i386 -output libGoogleAnalytics2.a

Then delete libGoogleAnalytics.a from your project and add libGoogleAnalytics2.a

This only works in conjunction with the dummy implementation of GANTracker as shown above.

Eamonn
Nice find! This one has been causing me issues too.
Rob Segal
Would start another question, but would you kindly say just exactly *what* you did with GANTracker_stub.m? people on the forums are saying copy the code into GANTracker_stub.m but not what to do next? The solution with -remove i386 does not seem to me as if it would allow running under the sim?
Jann
I just created added a new file using XCode, called it GANTracker_Stub.m. Deleted the GANTracker_Stub.h file and copied the code above into it. Then when you compile your project, GANTracker_Stub.m automatically overrides the GANTracker implementation in the static library. Does that make sense?
Eamonn