From ec697b3f756fd3c3222dde4bd3aa82ed3b974c68 Mon Sep 17 00:00:00 2001 From: Joshua Date: Wed, 14 May 2014 21:30:37 -0400 Subject: [PATCH 1/3] Update to GA3 for ios --- include.nmml | 13 +- ndll/iPhone/libHypGA.iphoneos-v7.a | Bin 13616 -> 15752 bytes ndll/iPhone/libHypGA.iphoneos.a | Bin 13568 -> 15648 bytes ndll/iPhone/libHypGA.iphonesim.a | Bin 12512 -> 14592 bytes project/.DS_Store | Bin 6148 -> 0 bytes project/iPhone/HypGA.mm | 26 +- project/iPhone/include/GAI.h | 89 ++-- project/iPhone/include/GAIDictionaryBuilder.h | 178 ++++++++ project/iPhone/include/GAIFields.h | 127 ++++++ project/iPhone/include/GAILogger.h | 49 +++ .../iPhone/include/GAITrackedViewController.h | 16 +- project/iPhone/include/GAITracker.h | 406 +----------------- project/iPhone/include/GAITransaction.h | 78 ---- project/iPhone/include/GAITransactionItem.h | 49 --- project/iphone.sh | 0 15 files changed, 459 insertions(+), 572 deletions(-) mode change 100755 => 100644 ndll/iPhone/libHypGA.iphoneos-v7.a mode change 100755 => 100644 ndll/iPhone/libHypGA.iphoneos.a mode change 100755 => 100644 ndll/iPhone/libHypGA.iphonesim.a delete mode 100644 project/.DS_Store create mode 100644 project/iPhone/include/GAIDictionaryBuilder.h create mode 100644 project/iPhone/include/GAIFields.h create mode 100644 project/iPhone/include/GAILogger.h delete mode 100644 project/iPhone/include/GAITransaction.h delete mode 100644 project/iPhone/include/GAITransactionItem.h mode change 100644 => 100755 project/iphone.sh diff --git a/include.nmml b/include.nmml index c921201..c3902ce 100644 --- a/include.nmml +++ b/include.nmml @@ -11,10 +11,13 @@ - - - - + + + + + + + @@ -24,4 +27,4 @@ - \ No newline at end of file + diff --git a/ndll/iPhone/libHypGA.iphoneos-v7.a b/ndll/iPhone/libHypGA.iphoneos-v7.a old mode 100755 new mode 100644 index 7795766b062994824718581ba42213d58d4f88ee..48e4eec916d7d86168367b576c66bf2f647e4b98 GIT binary patch literal 15752 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 literal 13616 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 literal 13568 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 Hen5c_oy$X{ diff --git a/project/iPhone/HypGA.mm b/project/iPhone/HypGA.mm index 7124016..17f2654 100644 --- a/project/iPhone/HypGA.mm +++ b/project/iPhone/HypGA.mm @@ -2,6 +2,8 @@ #import #import "GAI.h" +#import "GAIDictionaryBuilder.h" +#import "GAIFields.h" #import "GAITracker.h" namespace hypga { @@ -18,7 +20,8 @@ void startNewSession( const char *sUID , int iPeriod ){ void sendView( const char *sPage ){ NSString *NSPage = [[NSString alloc] initWithUTF8String:sPage]; NSLog( @"sendView %@" , NSPage ); - [tracker sendView:NSPage]; + [tracker set:kGAIScreenName value:NSPage]; + [tracker send:[[GAIDictionaryBuilder createAppView] build]]; } void sendEvent( const char *sCat , const char *sAction , const char *sLabel , int iValue ){ @@ -26,32 +29,43 @@ void sendEvent( const char *sCat , const char *sAction , const char *sLabel , in NSString *NS_Act = [ [NSString alloc] initWithUTF8String:sAction]; NSString *NS_Lab = [ [NSString alloc] initWithUTF8String:sLabel]; NSLog( @"SendEvent cat:%@ act:%@ label:%@ val%i" , NS_Cat , NS_Act , NS_Lab , iValue ); - [tracker sendEventWithCategory:NS_Cat withAction:NS_Act withLabel:NS_Lab withValue:[NSNumber numberWithInt:iValue]]; + [tracker send:[[GAIDictionaryBuilder createEventWithCategory:NS_Cat + action:NS_Act + label:NS_Lab + value:[NSNumber numberWithInt:iValue]] + build]]; } void setCustom_dimension( int iIndex , const char *sValue ){ NSString *NS_Val = [[NSString alloc] initWithUTF8String:sValue]; NSLog( @"setCustom_dimension index:%i value:%s" , iIndex , sValue ); - [tracker setCustom:iIndex dimension:NS_Val]; + [tracker set:[GAIFields customDimensionForIndex:iIndex] value:NS_Val]; } void setCustom_metric( int iIndex , int iMetric ){ NSLog( @"setCustom_metric index:%i metrid:%i",iIndex,iMetric); - [tracker setCustom:iIndex metric:[NSNumber numberWithInt:iMetric]]; + [tracker set:[GAIFields customMetricForIndex:iIndex] value:[NSString stringWithFormat:@"%d", iMetric]]; } void sendTiming( const char *sCat , int iInterval , const char *sName , const char *sLabel ){ NSString *NS_Cat = [ [NSString alloc] initWithUTF8String:sCat]; NSString *NS_Name = [ [NSString alloc] initWithUTF8String:sName]; NSString *NS_Label = [ [NSString alloc] initWithUTF8String:sLabel]; - [tracker sendTimingWithCategory:NS_Cat withValue:iInterval withName:NS_Name withLabel:NS_Label]; + [tracker send:[[GAIDictionaryBuilder createTimingWithCategory:NS_Cat + interval:[NSNumber numberWithInt:iInterval] + name:NS_Name + label:NS_Label] + build]]; } void sendSocial( const char *sSocial_network , const char *sAction , const char *sTarget ){ NSString *NS_Net = [ [NSString alloc] initWithUTF8String:sSocial_network]; NSString *NS_Act = [ [NSString alloc] initWithUTF8String:sAction]; NSString *NS_Tgt = [ [NSString alloc] initWithUTF8String:sTarget]; - [tracker sendSocial:NS_Net withAction:NS_Act withTarget:NS_Tgt]; + [tracker send:[[GAIDictionaryBuilder createSocialWithNetwork:NS_Net + action:NS_Act + target:NS_Tgt] + build]]; } void stopSession( ){ diff --git a/project/iPhone/include/GAI.h b/project/iPhone/include/GAI.h index f900201..d9e60e4 100644 --- a/project/iPhone/include/GAI.h +++ b/project/iPhone/include/GAI.h @@ -1,11 +1,12 @@ /*! @header GAI.h @abstract Google Analytics iOS SDK Header - @version 2.0 - @copyright Copyright 2011 Google Inc. All rights reserved. + @version 3.0 + @copyright Copyright 2013 Google Inc. All rights reserved. */ #import +#import "GAILogger.h" #import "GAITracker.h" #import "GAITrackedViewController.h" @@ -49,11 +50,9 @@ typedef enum { @property(nonatomic, assign) id defaultTracker; /*! - If true, Google Analytics debug messages will be logged with `NSLog()`. This is - useful for debugging calls to the Google Analytics SDK. - - By default, this flag is set to `NO`. */ -@property(nonatomic, assign) BOOL debug; + The GAILogger to use. + */ +@property(nonatomic, retain) id logger; /*! When this is true, no tracking information will be gathered; tracking calls @@ -69,14 +68,9 @@ typedef enum { @property(nonatomic, assign) BOOL optOut; /*! - If this value is negative, tracking information must be sent manually by - calling dispatch. If this value is zero, tracking information will - automatically be sent as soon as possible (usually immediately if the device - has Internet connectivity). If this value is positive, tracking information - will be automatically dispatched every dispatchInterval seconds. - - When the dispatchInterval is non-zero, setting it to zero will cause any queued - tracking information to be sent immediately. + If this value is positive, tracking information will be automatically + dispatched every dispatchInterval seconds. Otherwise, tracking information must + be sent manually by calling dispatch. By default, this is set to `120`, which indicates tracking information should be dispatched automatically every 120 seconds. @@ -94,31 +88,72 @@ typedef enum { */ @property(nonatomic, assign) BOOL trackUncaughtExceptions; +/*! + When this is 'YES', no tracking information will be sent. Defaults to 'NO'. + */ +@property(nonatomic, assign) BOOL dryRun; + /*! Get the shared instance of the Google Analytics for iOS class. */ + (GAI *)sharedInstance; /*! - Create or retrieve a GAITracker implementation with the specified tracking - ID. If the tracker for the specified tracking ID does not already exist, then + Creates or retrieves a GAITracker implementation with the specified name and + tracking ID. If the tracker for the specified name does not already exist, then it will be created and returned; otherwise, the existing tracker will be - returned. If defaultTracker is not set, it will be set to the tracker instance - returned here. + returned. If the existing tracker for the respective name has a different + tracking ID, that tracking ID is not changed by this method. If defaultTracker + is not set, it will be set to the tracker instance returned here. + + @param name The name of this tracker. Must not be `nil` or empty. - @param trackingId The tracking ID (a string that begins with "UA-"). Must not - be `nil` or empty. + @param trackingID The tracking ID to use for this tracker. It should be of + the form `UA-xxxxx-y`. - @return A GAITracker associated with the specified tracking ID. The tracker + @return A GAITracker associated with the specified name. The tracker can be used to send tracking data to Google Analytics. The first time this - method is called with a particular tracking ID, the tracker for that tracking - ID will be returned, and subsequent calls with the same tracking ID will return - the same instance. It is not necessary to retain the tracker because the - tracker will be retained internally by the library. + method is called with a particular name, the tracker for that name will be + returned, and subsequent calls with the same name will return the same + instance. It is not necessary to retain the tracker because the tracker will be + retained internally by the library. - If an error occurs or the tracker ID is not valid, this method will return + If an error occurs or the name is not valid, this method will return + `nil`. + */ +- (id)trackerWithName:(NSString *)name + trackingId:(NSString *)trackingId; + +/*! + Creates or retrieves a GAITracker implementation with name equal to + the specified tracking ID. If the tracker for the respective name does not + already exist, it is created, has it's tracking ID set to |trackingId|, + and is returned; otherwise, the existing tracker is returned. If the existing + tracker for the respective name has a different tracking ID, that tracking ID + is not changed by this method. If defaultTracker is not set, it is set to the + tracker instance returned here. + + @param trackingID The tracking ID to use for this tracker. It should be of + the form `UA-xxxxx-y`. The name of the tracker will be the same as trackingID. + + @return A GAITracker associated with the specified trackingID. The tracker + can be used to send tracking data to Google Analytics. The first time this + method is called with a particular trackingID, the tracker for the respective + name will be returned, and subsequent calls with the same trackingID + will return the same instance. It is not necessary to retain the tracker + because the tracker will be retained internally by the library. + + If an error occurs or the trackingId is not valid, this method will return `nil`. */ - (id)trackerWithTrackingId:(NSString *)trackingId; +/*! + Remove a tracker from the trackers dictionary. If it is the default tracker, + clears the default tracker as well. + + @param name The name of the tracker. + */ +- (void)removeTrackerByName:(NSString *)name; + /*! Dispatches any pending tracking information. diff --git a/project/iPhone/include/GAIDictionaryBuilder.h b/project/iPhone/include/GAIDictionaryBuilder.h new file mode 100644 index 0000000..20adff8 --- /dev/null +++ b/project/iPhone/include/GAIDictionaryBuilder.h @@ -0,0 +1,178 @@ +/*! + @header GAIDictionaryBuilder.h + @abstract Google Analytics iOS SDK Hit Format Header + @copyright Copyright 2013 Google Inc. All rights reserved. + */ + +#import + +/*! + * Helper class to build a dictionary of hit parameters and values. + *
+ * Examples: + * + * id t = // get a tracker. + * [t send:[[[GAIDictionaryBuilder createEventWithCategory:@"EventCategory" + * action:@"EventAction" + * label:nil + * value:nil] + * set:@"dimension1" forKey:[GAIFields customDimensionForIndex:1]] build]]; + * + * This will send an event hit type with the specified parameters + * and a custom dimension parameter. + *
+ * If you want to send a parameter with all hits, set it on GAITracker directly. + * + * [t set:kGAIScreenName value:@"Home"]; + * [t send:[[GAIDictionaryBuilder createSocialWithNetwork:@"Google+" + * action:@"PlusOne" + * target:@"SOME_URL"] build]]; + * [t send:[[GAIDictionaryBuilder createSocialWithNetwork:@"Google+" + * action:@"Share" + * target:@"SOME_POST"] build]]; + * [t send:[[GAIDictionaryBuilder createSocialWithNetwork:@"Google+" + * action:@"HangOut" + * target:@"SOME_CIRCLE"] + * build]]; + * + * You can override a value set on the tracker by adding it to the dictionary. + * + * [t set:kGAIScreenName value:@"Home"]; + * [t send:...]; + * [t send[[[GAIDictionaryBuilder createEventWithCategory:@"click" + * action:@"popup" + * label:nil + * value:nil] + * set:@"popup title" forKey:kGAIScreenName] build]]; + * + * The values set via [GAIDictionaryBuilder set] or + * [GAIDictionaryBuilder setAll] will override any existing values in the + * GAIDictionaryBuilder object (i.e. initialized by + * [GAIDictionaryBuilder createXYZ]). e.g. + * + * GAIDictionaryBuilder *m = + * GAIDictionaryBuilder createTimingWithCategory:@"category" + * interval:@0 + * name:@"name" + * label:nil]; + * [t send:[m.set:@"10" forKey:kGAITimingVar] build]; + * [t send:[m.set:@"20" forKey:kGAITimingVar] build]; + * + */ +@interface GAIDictionaryBuilder : NSObject + +- (GAIDictionaryBuilder *)set:(NSString *)value + forKey:(NSString *)key; + +/*! + * Copies all the name-value pairs from params into this object, ignoring any + * keys that are not NSString and any values that are neither NSString or + * NSNull. + */ +- (GAIDictionaryBuilder *)setAll:(NSDictionary *)params; + +/*! + * Returns the value for the input parameter paramName, or nil if paramName + * is not present. + */ +- (NSString *)get:(NSString *)paramName; + +/*! + * Return an NSMutableDictionary object with all the parameters set in this + */ +- (NSMutableDictionary *)build; + +/*! + * Parses and translates utm campaign parameters to analytics campaign param + * and returns them as a map. + * + * @param params url containing utm campaign parameters. + * + * Valid campaign parameters are: + *
    + *
  • utm_id
  • + *
  • utm_campaign
  • + *
  • utm_content
  • + *
  • utm_medium
  • + *
  • utm_source
  • + *
  • utm_term
  • + *
  • dclid
  • + *
  • gclid
  • + *
  • gmob_t
  • + *
+ *

+ * Example: + * http://my.site.com/index.html?utm_campaign=wow&utm_source=source + * utm_campaign=wow&utm_source=source. + *

+ * For more information on auto-tagging, see + * http://support.google.com/googleanalytics/bin/answer.py?hl=en&answer=55590 + *

+ * For more information on manual tagging, see + * http://support.google.com/googleanalytics/bin/answer.py?hl=en&answer=55518 + */ +- (GAIDictionaryBuilder *)setCampaignParametersFromUrl:(NSString *)urlString; + +/*! + Returns a GAIDictionaryBuilder object with parameters specific to an appview + hit. + + Note that using this method will not set the screen name for followon hits. To + do that you need to call set:kGAIDescription value: on the + GAITracker instance. + */ ++ (GAIDictionaryBuilder *)createAppView; + +/*! + Returns a GAIDictionaryBuilder object with parameters specific to an event hit. + */ ++ (GAIDictionaryBuilder *)createEventWithCategory:(NSString *)category + action:(NSString *)action + label:(NSString *)label + value:(NSNumber *)value; + +/*! + Returns a GAIDictionaryBuilder object with parameters specific to an exception + hit. + */ ++ (GAIDictionaryBuilder *)createExceptionWithDescription:(NSString *)description + withFatal:(NSNumber *)fatal; + +/*! + Returns a GAIDictionaryBuilder object with parameters specific to an item hit. + */ ++ (GAIDictionaryBuilder *)createItemWithTransactionId:(NSString *)transactionId + name:(NSString *)name + sku:(NSString *)sku + category:(NSString *)category + price:(NSNumber *)price + quantity:(NSNumber *)quantity + currencyCode:(NSString *)currencyCode; + +/*! + Returns a GAIDictionaryBuilder object with parameters specific to a social hit. + */ ++ (GAIDictionaryBuilder *)createSocialWithNetwork:(NSString *)network + action:(NSString *)action + target:(NSString *)target; + +/*! + Returns a GAIDictionaryBuilder object with parameters specific to a timing hit. + */ ++ (GAIDictionaryBuilder *)createTimingWithCategory:(NSString *)category + interval:(NSNumber *)intervalMillis + name:(NSString *)name + label:(NSString *)label; + +/*! + Returns a GAIDictionaryBuilder object with parameters specific to a transaction + hit. + */ ++ (GAIDictionaryBuilder *)createTransactionWithId:(NSString *)transactionId + affiliation:(NSString *)affiliation + revenue:(NSNumber *)revenue + tax:(NSNumber *)tax + shipping:(NSNumber *)shipping + currencyCode:(NSString *)currencyCode; + +@end diff --git a/project/iPhone/include/GAIFields.h b/project/iPhone/include/GAIFields.h new file mode 100644 index 0000000..c4961b1 --- /dev/null +++ b/project/iPhone/include/GAIFields.h @@ -0,0 +1,127 @@ +/*! + @header GAIFields.h + @abstract Google Analytics iOS SDK Hit Format Header + @copyright Copyright 2013 Google Inc. All rights reserved. + */ + +#import + +/*! + These fields can be used for the wire format parameter names required by + the |GAITracker| get, set and send methods as well as the set methods in the + |GAIDictionaryBuilder| class. + */ +extern NSString *const kGAIUseSecure; + +extern NSString *const kGAIHitType; +extern NSString *const kGAITrackingId; +extern NSString *const kGAIClientId; +extern NSString *const kGAIAnonymizeIp; +extern NSString *const kGAISessionControl; +extern NSString *const kGAIScreenResolution; +extern NSString *const kGAIViewportSize; +extern NSString *const kGAIEncoding; +extern NSString *const kGAIScreenColors; +extern NSString *const kGAILanguage; +extern NSString *const kGAIJavaEnabled; +extern NSString *const kGAIFlashVersion; +extern NSString *const kGAINonInteraction; +extern NSString *const kGAIReferrer; +extern NSString *const kGAILocation; +extern NSString *const kGAIHostname; +extern NSString *const kGAIPage; +extern NSString *const kGAIDescription; // synonym for kGAIScreenName +extern NSString *const kGAIScreenName; // synonym for kGAIDescription +extern NSString *const kGAITitle; +extern NSString *const kGAIAppName; +extern NSString *const kGAIAppVersion; +extern NSString *const kGAIAppId; +extern NSString *const kGAIAppInstallerId; +extern NSString *const kGAIUserId; + +extern NSString *const kGAIEventCategory; +extern NSString *const kGAIEventAction; +extern NSString *const kGAIEventLabel; +extern NSString *const kGAIEventValue; + +extern NSString *const kGAISocialNetwork; +extern NSString *const kGAISocialAction; +extern NSString *const kGAISocialTarget; + +extern NSString *const kGAITransactionId; +extern NSString *const kGAITransactionAffiliation; +extern NSString *const kGAITransactionRevenue; +extern NSString *const kGAITransactionShipping; +extern NSString *const kGAITransactionTax; +extern NSString *const kGAICurrencyCode; + +extern NSString *const kGAIItemPrice; +extern NSString *const kGAIItemQuantity; +extern NSString *const kGAIItemSku; +extern NSString *const kGAIItemName; +extern NSString *const kGAIItemCategory; + +extern NSString *const kGAICampaignSource; +extern NSString *const kGAICampaignMedium; +extern NSString *const kGAICampaignName; +extern NSString *const kGAICampaignKeyword; +extern NSString *const kGAICampaignContent; +extern NSString *const kGAICampaignId; + +extern NSString *const kGAITimingCategory; +extern NSString *const kGAITimingVar; +extern NSString *const kGAITimingValue; +extern NSString *const kGAITimingLabel; + +extern NSString *const kGAIExDescription; +extern NSString *const kGAIExFatal; + +extern NSString *const kGAISampleRate; + +extern NSString *const kGAIIdfa; +extern NSString *const kGAIAdTargetingEnabled; + +// hit types +extern NSString *const kGAIAppView; +extern NSString *const kGAIEvent; +extern NSString *const kGAISocial; +extern NSString *const kGAITransaction; +extern NSString *const kGAIItem; +extern NSString *const kGAIException; +extern NSString *const kGAITiming; + +/*! + This class provides several fields and methods useful as wire format parameter + names. The methods are used for wire format parameter names that are indexed. + */ + +@interface GAIFields : NSObject + +/*! + Generates the correct parameter name for a content group with an index. + + @param index the index of the content group. + + @return an NSString representing the content group parameter for the index. + */ ++ (NSString *)contentGroupForIndex:(NSUInteger)index; + +/*! + Generates the correct parameter name for a custon dimension with an index. + + @param index the index of the custom dimension. + + @return an NSString representing the custom dimension parameter for the index. + */ ++ (NSString *)customDimensionForIndex:(NSUInteger)index; + +/*! + Generates the correct parameter name for a custom metric with an index. + + @param index the index of the custom metric. + + @return an NSString representing the custom metric parameter for the index. + */ ++ (NSString *)customMetricForIndex:(NSUInteger)index; + +@end diff --git a/project/iPhone/include/GAILogger.h b/project/iPhone/include/GAILogger.h new file mode 100644 index 0000000..06291f2 --- /dev/null +++ b/project/iPhone/include/GAILogger.h @@ -0,0 +1,49 @@ +/*! + @header GAILogger.h + @abstract Google Analytics iOS SDK Source + @copyright Copyright 2011 Google Inc. All rights reserved. + */ + +#import + +typedef NS_ENUM(NSUInteger, GAILogLevel) { + kGAILogLevelNone = 0, + kGAILogLevelError = 1, + kGAILogLevelWarning = 2, + kGAILogLevelInfo = 3, + kGAILogLevelVerbose = 4 +}; + +/*! + Protocol to be used for logging debug and informational messages from the SDK. + Implementations of this protocol can be provided to the |GAI| class, + to be used as the logger by the SDK. See the |logger| property in GAI.h. + */ +@protocol GAILogger +@required + +/*! + Only messages of |logLevel| and below are logged. + */ +@property (nonatomic, assign) GAILogLevel logLevel; + +/*! + Logs message with log level |kGAILogLevelVerbose|. + */ +- (void)verbose:(NSString *)message; + +/*! + Logs message with log level |kGAILogLevelInfo|. + */ +- (void)info:(NSString *)message; + +/*! + Logs message with log level |kGAILogLevelWarning|. + */ +- (void)warning:(NSString *)message; + +/*! + Logs message with log level |kGAILogLevelError|. + */ +- (void)error:(NSString *)message; +@end diff --git a/project/iPhone/include/GAITrackedViewController.h b/project/iPhone/include/GAITrackedViewController.h index 0a10070..5cbabdd 100644 --- a/project/iPhone/include/GAITrackedViewController.h +++ b/project/iPhone/include/GAITrackedViewController.h @@ -11,18 +11,14 @@ @protocol GAITracker; /*! - Extends UIViewController to generate Google Analytics view tracking calls + Extends UIViewController to generate Google Analytics appview calls whenever the view appears; this is done by overriding the `viewDidAppear:` - method. The view name must be set for any tracking calls to be made. + method. The screen name must be set for any tracking calls to be made. By default, this will use [GAI defaultTracker] for tracking calls, but one can override this by setting the tracker property. */ -@interface GAITrackedViewController : UIViewController { - @private - id tracker_; - NSString *trackedViewName_; -} +@interface GAITrackedViewController : UIViewController /*! The tracker on which view tracking calls are be made, or `nil`, in which case @@ -30,9 +26,9 @@ */ @property(nonatomic, assign) id tracker; /*! - The view name, for purposes of Google Analytics view tracking. If this is - `nil`, no tracking calls will be made. + The screen name, for purposes of Google Analytics tracking. If this is `nil`, + no tracking calls will be made. */ -@property(nonatomic, copy) NSString *trackedViewName; +@property(nonatomic, copy) NSString *screenName; @end diff --git a/project/iPhone/include/GAITracker.h b/project/iPhone/include/GAITracker.h index 35a80f6..43b5e20 100644 --- a/project/iPhone/include/GAITracker.h +++ b/project/iPhone/include/GAITracker.h @@ -1,12 +1,11 @@ /*! @header GAITracker.h @abstract Google Analytics iOS SDK Tracker Header - @version 2.0 - @copyright Copyright 2011 Google Inc. All rights reserved. + @version 3.0 + @copyright Copyright 2013 Google Inc. All rights reserved. */ #import -#import "GAITransaction.h" /*! Google Analytics tracking interface. Obtain instances of this interface from @@ -18,364 +17,19 @@ @protocol GAITracker /*! - The tracking identifier (the string that begins with "UA-") this tracker is - associated with. - - This property is read-only. - */ -@property(nonatomic, copy, readonly) NSString *trackingId; - -/*! - The application name associated with this tracker. By default, this property is - populated with the `CFBundleName` string from the application bundle. If you - wish to override this property, you must do so before making any tracking - calls. - */ -@property(nonatomic, copy) NSString *appName; - -/*! - The application identifier associated with this tracker. This should be set to - the iTunes Connect application identifier assigned to your application. By - default, this property is `nil`. If you wish to set this property, you must do - so before making any tracking calls. - - Note that this is not your app's bundle id (e.g. com.example.appname), but the - identifier used by the App Store. - */ -@property(nonatomic, copy) NSString *appId; - -/*! - The application version associated with this tracker. By default, this property - is populated with the `CFBundleShortVersionString` string from the application - bundle. If you wish to override this property, you must do so before making any - tracking calls. - */ -@property(nonatomic, copy) NSString *appVersion; - -/*! - Tracking data collected while this is true will be anonymized by the Google - Analytics servers by zeroing out some of the least significant bits of the - IP address. - - In the case of IPv4 addresses, the last octet is set to zero. For - IPv6 addresses, the last 10 octets are set to zero, although this is subject to - change in the future. - - By default, this flag is false. - */ -@property(nonatomic, assign) BOOL anonymize; - -/*! - Tracking information collected while this is true will be submitted to Google - Analytics using HTTPS connection(s); otherwise, HTTP will be used. Note that - there may be additional overhead when sending data using HTTPS in terms of - processing costs and/or battery consumption. - - By default, this flag is true. - */ -@property(nonatomic, assign) BOOL useHttps; - -/*! - The sampleRate parameter controls the probability that the visitor will be - sampled. By default, sampleRate is 100, which signifies no sampling. sampleRate - may be set to any value between 0 and 100, inclusive. A value of 90 means 90% - of visitors should be sampled (10% of visitors to be sampled out). - - When a visitor is not sampled, no data is collected by Google Analytics for iOS - library about that visitor's activity. If your application is subject to heavy - traffic spikes, you may wish to adjust the sample rate to ensure uninterrupted - report tracking. Sampling in Google Analytics occurs consistently across unique - visitors, ensuring integrity in trending and reporting even when sampling is - enabled, because unique visitors remain included or excluded from the sample, - as set from the initiation of sampling. - */ -@property(nonatomic, assign) double sampleRate; - -/*! - The client ID for the tracker. - - This is a persistent unique identifier generated the first time the library is - called and persisted unchanged thereafter. It is used to identify the client - across multiple application sessions. - */ -@property(nonatomic, copy, readonly) NSString *clientId; - -/*! - The current screen set for this tracker. - - Calling trackView: will also update this property before it dispatches tracking - information to Google Analytics. However, if you wish to update the current - screen without sending any tracking information, set this property directly. - The updated screen will be reflected in subsequent tracking information. - */ -@property(nonatomic, copy) NSString *appScreen; - -/*! - The referrer URL for this tracker. Changing this value causes it to be sent - with the next dispatch of tracking information. - */ -@property(nonatomic, copy) NSString *referrerUrl; - -/*! - The campaign URL for this tracker. This is not directly propagated to Google - Analytics, but if there are campaign parameter(s), either manually or - auto-tagged, present in this URL, the SDK will include those parameters in the - next dispatch of tracking information. Google Analytics treats tracking - information with differing campaign information as part of separate sessions. - - For more information on auto-tagging, see - http://support.google.com/googleanalytics/bin/answer.py?hl=en&answer=55590 - - For more information on manual tagging, see - http://support.google.com/googleanalytics/bin/answer.py?hl=en&answer=55518 + Name of this tracker. */ -@property(nonatomic, copy) NSString *campaignUrl; - -/*! - If true, indicates the start of a new session. Note that when a tracker is - first instantiated, this is initialized to true. To prevent this default - behavior, set this to `NO` when the tracker is first obtained. - - By itself, setting this does not send any data. If this is true, when the next - tracking call is made, a parameter will be added to the resulting tracking - information indicating that it is the start of a session, and this flag will be - cleared. - */ -@property(nonatomic, assign) BOOL sessionStart; - -/*! - If non-negative, indicates how long, in seconds, the application must - transition to the inactive or background state for before the tracker will - automatically indicate the start of a new session when the app becomes active - again by setting sessionStart to true. For example, if this is set to 30 - seconds, and the user receives a phone call that lasts for 45 seconds while - using the app, upon returning to the app, the sessionStart parameter will be - set to true. If the phone call instead lasted 10 seconds, sessionStart will not - be modified. - - To disable automatic session tracking, set this to a negative value. To - indicate the start of a session anytime the app becomes inactive or - backgrounded, set this to zero. - - By default, this is 30 seconds. - */ -@property(nonatomic, assign) NSTimeInterval sessionTimeout; - -/*! - Track that the current screen (as set in appScreen) was displayed. If appScreen - has not been set, this will not generate any tracking information. - - If [GAI optOut] is true, this will not generate any tracking information. - - @return `YES` if the tracking information was queued for dispatch, or `NO` if - there was an error (e.g. the tracker was closed or appScreen is not set). - */ -- (BOOL)sendView; - -/*! - This method is deprecated. See sendView. - */ -- (BOOL)trackView; - -/*! - Track that the specified view or screen was displayed. This call sets - the appScreen property and generates tracking information to be sent to Google - Analytics. - - If [GAI optOut] is true, this will not generate any tracking information. - - @param screen The name of the screen. Must not be `nil`. - - @return `YES` if the tracking information was queued for dispatch, or `NO` if - there was an error (e.g. the tracker was closed). - */ -- (BOOL)sendView:(NSString *)screen; - -/*! - This method is deprecated. See sendView. - */ -- (BOOL)trackView:(NSString *)screen; - -/*! - Track an event. - - If [GAI optOut] is true, this will not generate any tracking information. - - @param category The event category, or `nil` if none. - - @param action The event action, or `nil` if none. - - @param label The event label, or `nil` if none. - - @param value The event value, to be interpreted as a 64-bit signed integer, or - `nil` if none. - - @return `YES` if the tracking information was queued for dispatch, or `NO` if - there was an error (e.g. the tracker was closed). - */ -- (BOOL)sendEventWithCategory:(NSString *)category - withAction:(NSString *)action - withLabel:(NSString *)label - withValue:(NSNumber *)value; - -/*! - This method is deprecated. See sendEventWithCategory. - */ -- (BOOL)trackEventWithCategory:(NSString *)category - withAction:(NSString *)action - withLabel:(NSString *)label - withValue:(NSNumber *)value; - -/*! - Track a transaction. - - If [GAI optOut] is true, this will not generate any tracking information. - - @param transaction The GAITransaction object. - - @return `YES` if the tracking information was queued for dispatch, or `NO` if - there was an error (e.g. the tracker was closed). - */ -- (BOOL)sendTransaction:(GAITransaction *)transaction; - -/*! - This method is deprecated. see sendTransaction. - */ -- (BOOL)trackTransaction:(GAITransaction *)transaction; - -/*! - Track an exception. - - If [GAI optOut] is true, this will not generate any tracking information. - - @param isFatal A boolean indicating whether the exception is fatal. - - @param format A format string that will be used to create the exception - description. - - @param ... An optional list of arguments to be substituted using the format - string. - - @return `YES` if the tracking information was queued for dispatch, or `NO` if - there was an error (e.g. the tracker was closed). - */ -- (BOOL)sendException:(BOOL)isFatal - withDescription:(NSString *)format, ...; - -/*! - This method is deprecated. See sendException. - */ -- (BOOL)trackException:(BOOL)isFatal - withDescription:(NSString *)format, ...; - -/*! Convenience method for tracking an NSException that passes the exception - name to trackException:withDescription:. - - If [GAI optOut] is true, this will not generate any tracking information. - - @param isFatal A boolean indicating whether the exception is fatal. - - @param exception The NSException exception object. - - @return `YES` if the tracking information was queued for dispatch, or `NO` if - there was an error (e.g. the tracker was closed). - */ -- (BOOL)sendException:(BOOL)isFatal - withNSException:(NSException *)exception; - -/*! - This method is deprecated. See sendException. - */ -- (BOOL)trackException:(BOOL)isFatal - withNSException:(NSException *)exception; - -/*! Convenience method for tracking an NSError that passes the domain, code, and - description to trackException:withDescription:. - - If [GAI optOut] is true, this will not generate any tracking information. - - @param isFatal A boolean indicating whether the exception is fatal. - - @param error The NSError error object. - - @return `YES` if the tracking information was queued for dispatch, or `NO` if - there was an error (e.g. the tracker was closed). - */ -- (BOOL)sendException:(BOOL)isFatal - withNSError:(NSError *)error; - -/*! - This method is deprecated. See sendException. - */ -- (BOOL)trackException:(BOOL)isFatal - withNSError:(NSError *)error; - -/*! - Track user timing. - - If [GAI optOut] is true, this will not generate any tracking information. - - @param category A string representing a timing category. - - @param time A timing value. - - @param name A string representing a timing name, or `nil` if none. - - @param label A string representing a timing variable label, or `nil` if none. - - @return `YES` if the tracking information was queued for dispatch, or `NO` if - there was an error (e.g. the tracker was closed). - */ -- (BOOL)sendTimingWithCategory:(NSString *)category - withValue:(NSTimeInterval)time - withName:(NSString *)name - withLabel:(NSString *)label; - -/*! - This method is deprecated. See sendTimingWithCategory. - */ -- (BOOL)trackTimingWithCategory:(NSString *)category - withValue:(NSTimeInterval)time - withName:(NSString *)name - withLabel:(NSString *)label; - -/*! - Track social action. - - If [GAI optOut] is true, this will not generate any tracking information. - - @param network A string representing social network. Must not be nil. - - @param action A string representing a social action. Must not be nil. - - @param target A string representing the target. May be nil. - - @return `YES` if the tracking information was queued for dispatch, or `NO` if - there was an error (e.g. the tracker was closed). - */ -- (BOOL)sendSocial:(NSString *)network - withAction:(NSString *)action - withTarget:(NSString *)target; - -/*! - This method is deprecated. See sendSocial. - */ -- (BOOL)trackSocial:(NSString *)network - withAction:(NSString *)action - withTarget:(NSString *)target; +@property(nonatomic, readonly) NSString *name; /*! Set a tracking parameter. @param parameterName The parameter name. - @param value The value to set for the parameter. If this is `nil`, the + @param value The value to set for the parameter. If this is nil, the value for the parameter will be cleared. - - @returns `YES` if the parameter was set to the given value, or `NO` if there - was an error (e.g. unknown parameter). */ -- (BOOL)set:(NSString *)parameterName +- (void)set:(NSString *)parameterName value:(NSString *)value; /*! @@ -383,7 +37,7 @@ @param parameterName The parameter name. - @returns The parameter value, or `nil` if no value for the given parameter is + @returns The parameter value, or nil if no value for the given parameter is set. */ - (NSString *)get:(NSString *)parameterName; @@ -391,51 +45,9 @@ /*! Queue tracking information with the given parameter values. - @param trackType The type of tracking information, e.g., @"appview". - @param parameters A map from parameter names to parameter values which will be - set just for this piece of tracking information. - - @return `YES` if the tracking information was queued for submission, or `NO` - if an error occurred (e.g. bad track type). - */ -- (BOOL)send:(NSString *)trackType - params:(NSDictionary *)parameters; - -/*! - Set a custom dimension value, to be sent at the next tracking call. - - @param index The index at which to set the dimension. Must be positive. - - @param dimension The dimension value, or `nil` if the dimension at the given - index is to be cleared. - - @return `YES` on success, or `NO` if an error occurred. - */ -- (BOOL)setCustom:(NSInteger)index - dimension:(NSString *)dimension; - -/*! - Set a custom metric value, to be sent at the next tracking call. - - @param index The index at which to set the metric. Must be positive. - - @param metric The metric value, which will be interpreted as a signed 64-bit - integer, or `nil` if the metric at the given index is to be cleared. - - @return `YES` on success, or `NO` if an error occurred. - */ -- (BOOL)setCustom:(NSInteger)index - metric:(NSNumber *)metric; - -/*! - Close the tracker. This will mark it as closed and remove it from the list of - trackers accessible through [GAI trackerWithTrackingId:], thus decrementing its - reference count (and causing it to be dealloced unless it has been retained by - the application). Once this method has been called, it is an error to call any - of the tracking methods, and they will not result in the generation of any - tracking information to be submitted to Google Analytics. + set just for this piece of tracking information, or nil for none. */ -- (void)close; +- (void)send:(NSDictionary *)parameters; @end diff --git a/project/iPhone/include/GAITransaction.h b/project/iPhone/include/GAITransaction.h deleted file mode 100644 index 9e081e3..0000000 --- a/project/iPhone/include/GAITransaction.h +++ /dev/null @@ -1,78 +0,0 @@ -/*! - @header GAITransaction.h - @abstract Google Analytics iOS SDK Transaction Header - @version 2.0 - @copyright Copyright 2011 Google Inc. All rights reserved. - */ - -#import -#import "GAITransactionItem.h" - -/*! A simple class to hold transaction data. */ -@interface GAITransaction : NSObject - -/*! Transaction ID. */ -@property(nonatomic, copy, readonly) NSString *transactionId; - -/*! Transaction affiliation. */ -@property(nonatomic, copy, readonly) NSString *affiliation; - -/*! Revenue in micros (millionths of a currency unit). Note that this must be - set manually because it is not updated when items are added. */ -@property(nonatomic, assign) int64_t revenueMicros; - -/*! Tax in micros (millionths of a currency unit). Note that this must be set - * manually because it is not updated when items are added. */ -@property(nonatomic, assign) int64_t taxMicros; - -/*! Shipping cost in micros (millionths of a currency unit). Note that - this must be set manually because it is not updated when items are added. */ -@property(nonatomic, assign) int64_t shippingMicros; - -/*! Transaction items, as an immutable array. */ -@property(nonatomic, readonly) NSArray *items; - -/*! - Create and initialize a transaction. - - @param transactionId The transaction ID. Required (must not be `nil`). - - @param affiliation The transaction affiliation. May be `nil`. - - @return A GAITransaction object with the specified transaction ID and - affiliation. - */ -+ (GAITransaction *)transactionWithId:(NSString *)transactionId - withAffiliation:(NSString *)affiliation; - -/*! - Add an item to the transaction. If an item with the same SKU already - exists in the transaction, that item will be replaced with this one. - - @param item The GAITransactionItem to add to the transaction. - */ -- (void)addItem:(GAITransactionItem *)item; - -/*! - Add an item to the transaction. If an item with the same SKU already - exists in the transaction, that item will be replaced with this one. - - @param productCode The item product code; must not be `nil` or empty. - - @param productName The item product name; may be `nil`. - - @param productCategory The item product category; may be `nil`. - - @param priceMicros The item price, in micros (millionths of a currency unit). - - @param quantity The item quantity, as an NSInteger. - - @return The newly initialized item. - */ -- (void)addItemWithCode:(NSString *)productCode - name:(NSString *)productName - category:(NSString *)productCategory - priceMicros:(int64_t)priceMicros - quantity:(NSInteger)quantity; - -@end diff --git a/project/iPhone/include/GAITransactionItem.h b/project/iPhone/include/GAITransactionItem.h deleted file mode 100644 index e8ee3fd..0000000 --- a/project/iPhone/include/GAITransactionItem.h +++ /dev/null @@ -1,49 +0,0 @@ -/*! - @header GAITransactionItem.h - @abstract Google Analytics iOS SDK Transaction Item Header - @version 2.0 - @copyright Copyright 2011 Google Inc. All rights reserved. - */ - -#import - -/*! A simple class to hold transaction item data. */ -@interface GAITransactionItem : NSObject - -/*! The item code, as a string. */ -@property(nonatomic, copy, readonly) NSString *productCode; - -/*! The item name. */ -@property(nonatomic, copy) NSString *productName; - -/*! The item variation. */ -@property(nonatomic, copy) NSString *productCategory; - -/*! The item price in micros (millionths of a currency unit). */ -@property(nonatomic, assign) int64_t priceMicros; - -/*! The item quantity. */ -@property(nonatomic, assign) NSInteger quantity; - -/*! - Create and initialize an item. - - @param productCode The item product code; must not be `nil` or empty. - - @param productName The item product name; must not be `nil` or empty. - - @param productCategory The item product category; may be `nil`. - - @param priceMicros The item price, in micros (millionths of a currency unit). - - @param quantity The item quantity, as an NSInteger. - - @return The newly initialized item. - */ -+ (GAITransactionItem *)itemWithCode:(NSString *)productCode - name:(NSString *)productName - category:(NSString *)productCategory - priceMicros:(int64_t)priceMicros - quantity:(NSInteger)quantity; - -@end diff --git a/project/iphone.sh b/project/iphone.sh old mode 100644 new mode 100755 From 86abe30e02d0d203f1f5e6cda307b6bd7876ed37 Mon Sep 17 00:00:00 2001 From: Joshua Date: Wed, 14 May 2014 21:30:51 -0400 Subject: [PATCH 2/3] Update the readme --- README.md | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 20dfcdb..7ceda1a 100644 --- a/README.md +++ b/README.md @@ -3,8 +3,10 @@ HypGA A Google Analytics native extension for NME ----------------------------- -This NME native extension allows you to integrate Google Analytics ( v2 Beta 4 ) into your NME application. -The supported compilation targets are [iOS](https://developers.google.com/analytics/devguides/collection/ios/v2/) & [Android](https://developers.google.com/analytics/devguides/collection/android/v2/) +This OpenFL native extension allows you to integrate Google Analytics v3 into your OpenFL application. +The supported compilation targets are +* [iOS](https://developers.google.com/analytics/devguides/collection/ios/v3/) +* [Android](https://developers.google.com/analytics/devguides/collection/android/v2/) Installation ------------ @@ -22,10 +24,11 @@ Usage ----- Just call the public methods on the HypGA class. -For iOS you need to link the Google Analytics class package to your XCode project. -Just drag & drop on your project the HypGA folder. ( [your_export_folder]/ios/[ProjectName]/HypGA ) +For iOS, put the following libs (from GA SDK) into projects/iPhone/libs: +* libAdIdAccess.a +* libGoogleAnalyticsServices.a -Baisc reference +Basic reference --------------- First start the session via : From 82cf5575983a3114c36544cd5c2bcd34229aab40 Mon Sep 17 00:00:00 2001 From: Joshua Date: Wed, 14 May 2014 21:49:16 -0400 Subject: [PATCH 3/3] make versions more clear --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7ceda1a..42d8814 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ HypGA A Google Analytics native extension for NME ----------------------------- -This OpenFL native extension allows you to integrate Google Analytics v3 into your OpenFL application. +This OpenFL native extension allows you to integrate Google Analytics into your OpenFL application. The supported compilation targets are * [iOS](https://developers.google.com/analytics/devguides/collection/ios/v3/) * [Android](https://developers.google.com/analytics/devguides/collection/android/v2/) @@ -24,7 +24,7 @@ Usage ----- Just call the public methods on the HypGA class. -For iOS, put the following libs (from GA SDK) into projects/iPhone/libs: +For iOS, put the following libs (from GA v3 SDK) into projects/iPhone/libs: * libAdIdAccess.a * libGoogleAnalyticsServices.a