├── .editorconfig ├── .gitignore ├── .jshintrc ├── LICENSE ├── README.md ├── android ├── GoogleAnalyticsPlugin.java └── version.xml ├── ios ├── GAI.h ├── GAIDictionaryBuilder.h ├── GAIEcommerceFields.h ├── GAIEcommerceProduct.h ├── GAIEcommerceProductAction.h ├── GAIEcommercePromotion.h ├── GAIFields.h ├── GAILogger.h ├── GAITrackedViewController.h ├── GAITracker.h ├── GoogleAnalyticsPlugin.h ├── GoogleAnalyticsPlugin.m └── libGoogleAnalyticsServices.a ├── package.json ├── plugin.xml ├── prefix.md └── www └── analytics.js /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "node": true, 3 | "browser": true, 4 | "esnext": true, 5 | "bitwise": true, 6 | "white": true, 7 | "camelcase": false, 8 | "curly": false, 9 | "eqeqeq": true, 10 | "immed": true, 11 | "indent": 2, 12 | "maxstatements": 15, 13 | "maxparams": 10, 14 | "maxcomplexity": 10, 15 | "latedef": true, 16 | "newcap": true, 17 | "noarg": true, 18 | "quotmark": "single", 19 | "regexp": true, 20 | "undef": true, 21 | "unused": false, 22 | "strict": true, 23 | "trailing": true, 24 | "smarttabs": true, 25 | "globals": { 26 | "angular": false, 27 | "describe": false, 28 | "defaultModule": false, 29 | "beforeEach": false, 30 | "afterEach": false, 31 | "it": false, 32 | "runs": false, 33 | "spyOn": false, 34 | "helper": true, 35 | "expect": false, 36 | "inject": false, 37 | "waitsFor": false 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | 203 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | google-analytics-plugin 2 | ======================= 3 | 4 | Provides Apache Cordova/Phonegap support for Google Analytics using the native sdks for Android & iOS. 5 | 6 | * Android Native SDK v4 (using Google Play Services SDK) 7 | * iOS Native SDK v3 8 | 9 | This plugin provides support for some of the more specific analytics functions (screen, event & exception tracking, custom metrics & dimensions) and also the more generic set and send functions which can be used to implement all of the Google Analytics collection features. 10 | 11 | As an example tracking a screen could be implemented using either the sendAppView function or the send function: 12 | 13 | ```js 14 | 15 | var analytics = navigator.analytics; 16 | 17 | // set the tracking id 18 | analytics.setTrackingId('UA-XXXXX-X'); 19 | // ...or set multiple tracking ids 20 | analytics.setMultipleTrackingIds(['UA-XXXXX-1', 'UA-XXXXX-2']); 21 | 22 | analytics.sendAppView('home', successCallback, errorCallback); 23 | 24 | // or the same could be done using the send function 25 | 26 | var Fields = analytics.Fields, 27 | HitTypes = analytics.HitTypes, 28 | LogLevel = analytics.LogLevel, 29 | params = {}; 30 | 31 | params[Fields.HIT_TYPE] = HitTypes.APP_VIEW; 32 | params[Fields.SCREEN_NAME] = 'home'; 33 | 34 | analytics.setLogLevel(LogLevel.INFO); 35 | 36 | analytics.send(params, successCallback, errorCallback); 37 | 38 | ``` 39 | 40 | The send & set functions provide maximum flexibility and allow you to utilize all of the Google Analytics collection calls. Some helper functions are also provided to support some of the more common analytic functions. 41 | 42 | For more information about measurement protocol refer to the following page: 43 | 44 | [Measurement Protocol Developer Guide](https://developers.google.com/analytics/devguides/collection/protocol/v1/devguide) 45 | 46 | ## Installation 47 | ``` 48 | cordova plugin add com.cmackay.plugins.googleanalytics 49 | ``` 50 | 51 | To use a specific version of Google's `play-services-analytics` library just specify it with the `ANALYTICS_VERSION` variable. 52 | 53 | ``` 54 | cordova plugin add com.cmackay.plugins.googleanalytics --variable ANALYTICS_VERSION='11.0.1' 55 | ``` 56 | 57 | 58 | ## API 59 | 60 | 61 | ## analytics 62 | 63 | * [analytics](#module_analytics) 64 | * [.Fields](#module_analytics.Fields) 65 | * [.HitTypes](#module_analytics.HitTypes) 66 | * [.LogLevel](#module_analytics.LogLevel) 67 | * [.setTrackingId(trackingId, [success], [error])](#module_analytics.setTrackingId) 68 | * [.setMultipleTrackingIds(trackingIds, [success], [error])](#module_analytics.setMultipleTrackingIds) 69 | * [.setDispatchInterval(seconds, [success], [error])](#module_analytics.setDispatchInterval) 70 | * [.getAppOptOut([success])](#module_analytics.getAppOptOut) 71 | * [.setAppOptOut([enabled], [success], [error])](#module_analytics.setAppOptOut) 72 | * [.setLogLevel(logLevel, [success], [error])](#module_analytics.setLogLevel) 73 | * [.dispatchHits([success], [error])](#module_analytics.dispatchHits) 74 | * [.get(key, success, [error])](#module_analytics.get) 75 | * [.set(key, value, [success], [error])](#module_analytics.set) 76 | * [.send(params, [success], [error])](#module_analytics.send) 77 | * [.close([success], [error])](#module_analytics.close) 78 | * [.customDimension(id, [value], [success], [error])](#module_analytics.customDimension) 79 | * [.customMetric(id, [value], [success], [error])](#module_analytics.customMetric) 80 | * [.sendEvent(category, action, [label], [value], [success], [error])](#module_analytics.sendEvent) 81 | * [.sendEventWithParams(category, action, [label], [value], params, [success], [error])](#module_analytics.sendEventWithParams) 82 | * [.sendAppView(screenName, [success], [error])](#module_analytics.sendAppView) 83 | * [.sendAppViewWithParams(screenName, params, [success], [error])](#module_analytics.sendAppViewWithParams) 84 | * [.sendTiming(category, variable, label, time, [success], [error])](#module_analytics.sendTiming) 85 | * [.sendException(description, [fatal], [success], [error])](#module_analytics.sendException) 86 | * [.trackUnhandledScriptErrors([opts], [success], [error])](#module_analytics.trackUnhandledScriptErrors) 87 | 88 | 89 | 90 | ### analytics.Fields 91 | GA Field Types 92 | 93 | **Kind**: static property of [analytics](#module_analytics) 94 | 95 | 96 | ### analytics.HitTypes 97 | GA Hit Types 98 | 99 | **Kind**: static property of [analytics](#module_analytics) 100 | 101 | 102 | ### analytics.LogLevel 103 | Log Levels 104 | 105 | **Kind**: static property of [analytics](#module_analytics) 106 | 107 | 108 | ### analytics.setTrackingId(trackingId, [success], [error]) 109 | Sets the tracking id 110 | 111 | **Kind**: static method of [analytics](#module_analytics) 112 | 113 | | Param | Type | Description | 114 | | --- | --- | --- | 115 | | trackingId | string | the trackingId | 116 | | [success] | function | the success callback | 117 | | [error] | function | the error callback | 118 | 119 | 120 | 121 | ### analytics.setMultipleTrackingIds(trackingIds, [success], [error]) 122 | Sets multiple tracking ids. 123 | This will override any tracking id previously set. 124 | 125 | **Kind**: static method of [analytics](#module_analytics) 126 | 127 | | Param | Type | Description | 128 | | --- | --- | --- | 129 | | trackingIds | array | array of trackingId parameters | 130 | | [success] | function | the success callback | 131 | | [error] | function | the error callback | 132 | 133 | 134 | 135 | ### analytics.setDispatchInterval(seconds, [success], [error]) 136 | Sets the dispatch Interval 137 | 138 | **Kind**: static method of [analytics](#module_analytics) 139 | 140 | | Param | Type | Description | 141 | | --- | --- | --- | 142 | | seconds | number | the interval in seconds | 143 | | [success] | function | the success callback | 144 | | [error] | function | the error callback | 145 | 146 | 147 | 148 | ### analytics.getAppOptOut([success]) 149 | Get app-level opt out flag that will disable Google Analytics 150 | 151 | **Kind**: static method of [analytics](#module_analytics) 152 | 153 | | Param | Type | Description | 154 | | --- | --- | --- | 155 | | [success] | function | the success callback (value is passed to callback) | 156 | 157 | 158 | 159 | ### analytics.setAppOptOut([enabled], [success], [error]) 160 | Set app-level opt out flag that will disable Google Analytics 161 | 162 | **Kind**: static method of [analytics](#module_analytics) 163 | 164 | | Param | Type | Default | Description | 165 | | --- | --- | --- | --- | 166 | | [enabled] | boolean | true | true for opt out or false to opt in | 167 | | [success] | function | | the success callback | 168 | | [error] | function | | the error callback | 169 | 170 | 171 | 172 | ### analytics.setLogLevel(logLevel, [success], [error]) 173 | Sets the log level 174 | 175 | **Kind**: static method of [analytics](#module_analytics) 176 | 177 | | Param | Type | Description | 178 | | --- | --- | --- | 179 | | logLevel | number | the log level (refer to LogLevel for values) | 180 | | [success] | function | the success callback | 181 | | [error] | function | the error callback | 182 | 183 | 184 | 185 | ### analytics.dispatchHits([success], [error]) 186 | Manually dispatches hits 187 | 188 | **Kind**: static method of [analytics](#module_analytics) 189 | 190 | | Param | Type | Description | 191 | | --- | --- | --- | 192 | | [success] | function | the success callback | 193 | | [error] | function | the error callback | 194 | 195 | 196 | 197 | ### analytics.get(key, success, [error]) 198 | Gets a field value. Returned as argument to success callback. 199 | If multiple trackers are being used, this returns an array of trackerId and 200 | field value pairs, e.g., 201 | [{ "UA-XXXXX-1" : "field_value1" }, { "UA-XXXXX-2" : "field_value2" }] 202 | 203 | **Kind**: static method of [analytics](#module_analytics) 204 | 205 | | Param | Type | Description | 206 | | --- | --- | --- | 207 | | key | string | the key | 208 | | success | function | the success callback | 209 | | [error] | function | the error callback | 210 | 211 | 212 | 213 | ### analytics.set(key, value, [success], [error]) 214 | Sets a field value 215 | 216 | **Kind**: static method of [analytics](#module_analytics) 217 | 218 | | Param | Type | Description | 219 | | --- | --- | --- | 220 | | key | string | the key | 221 | | value | | the value | 222 | | [success] | function | the success callback | 223 | | [error] | function | the error callback | 224 | 225 | 226 | 227 | ### analytics.send(params, [success], [error]) 228 | Generates a hit to be sent with the specified params and current field values 229 | 230 | **Kind**: static method of [analytics](#module_analytics) 231 | 232 | | Param | Type | Description | 233 | | --- | --- | --- | 234 | | params | object | the params | 235 | | [success] | function | the success callback | 236 | | [error] | function | the error callback | 237 | 238 | 239 | 240 | ### analytics.close([success], [error]) 241 | Closes the tracker 242 | 243 | **Kind**: static method of [analytics](#module_analytics) 244 | 245 | | Param | Type | Description | 246 | | --- | --- | --- | 247 | | [success] | function | the success callback | 248 | | [error] | function | the error callback | 249 | 250 | 251 | 252 | ### analytics.customDimension(id, [value], [success], [error]) 253 | Sets a custom dimension 254 | 255 | **Kind**: static method of [analytics](#module_analytics) 256 | 257 | | Param | Type | Description | 258 | | --- | --- | --- | 259 | | id | number | the id | 260 | | [value] | string | the value | 261 | | [success] | function | the success callback | 262 | | [error] | function | the error callback | 263 | 264 | 265 | 266 | ### analytics.customMetric(id, [value], [success], [error]) 267 | Sets a custom metric 268 | 269 | **Kind**: static method of [analytics](#module_analytics) 270 | 271 | | Param | Type | Description | 272 | | --- | --- | --- | 273 | | id | number | the id | 274 | | [value] | number | the value | 275 | | [success] | function | the success callback | 276 | | [error] | function | the error callback | 277 | 278 | 279 | 280 | ### analytics.sendEvent(category, action, [label], [value], [success], [error]) 281 | Sends an event 282 | 283 | **Kind**: static method of [analytics](#module_analytics) 284 | 285 | | Param | Type | Default | Description | 286 | | --- | --- | --- | --- | 287 | | category | string | | the category | 288 | | action | string | | the action | 289 | | [label] | string | "''" | the label | 290 | | [value] | number | 0 | the value | 291 | | [success] | function | | the success callback | 292 | | [error] | function | | the error callback | 293 | 294 | 295 | 296 | ### analytics.sendEventWithParams(category, action, [label], [value], params, [success], [error]) 297 | Sends an event with additional params 298 | 299 | **Kind**: static method of [analytics](#module_analytics) 300 | 301 | | Param | Type | Default | Description | 302 | | --- | --- | --- | --- | 303 | | category | string | | the category | 304 | | action | string | | the action | 305 | | [label] | string | "''" | the label | 306 | | [value] | number | 0 | the value | 307 | | params | object | | the params | 308 | | [success] | function | | the success callback | 309 | | [error] | function | | the error callback | 310 | 311 | 312 | 313 | ### analytics.sendAppView(screenName, [success], [error]) 314 | Sends a screen view 315 | 316 | **Kind**: static method of [analytics](#module_analytics) 317 | 318 | | Param | Type | Description | 319 | | --- | --- | --- | 320 | | screenName | string | the screenName | 321 | | [success] | function | the success callback | 322 | | [error] | function | the error callback | 323 | 324 | 325 | 326 | ### analytics.sendAppViewWithParams(screenName, params, [success], [error]) 327 | Sends a screen view with additional params 328 | 329 | **Kind**: static method of [analytics](#module_analytics) 330 | 331 | | Param | Type | Description | 332 | | --- | --- | --- | 333 | | screenName | string | the screenName | 334 | | params | object | the params | 335 | | [success] | function | the success callback | 336 | | [error] | function | the error callback | 337 | 338 | 339 | 340 | ### analytics.sendTiming(category, variable, label, time, [success], [error]) 341 | Sends a user timing 342 | 343 | **Kind**: static method of [analytics](#module_analytics) 344 | 345 | | Param | Type | Description | 346 | | --- | --- | --- | 347 | | category | string | the category | 348 | | variable | string | the variable | 349 | | label | string | the label | 350 | | time | number | the time | 351 | | [success] | function | the success callback | 352 | | [error] | function | the error callback | 353 | 354 | 355 | 356 | ### analytics.sendException(description, [fatal], [success], [error]) 357 | Sends an exception 358 | 359 | **Kind**: static method of [analytics](#module_analytics) 360 | 361 | | Param | Type | Description | 362 | | --- | --- | --- | 363 | | description | string | the exception description | 364 | | [fatal] | boolean | marks the exception as fatal | 365 | | [success] | function | the success callback | 366 | | [error] | function | the error callback | 367 | 368 | 369 | 370 | ### analytics.trackUnhandledScriptErrors([opts], [success], [error]) 371 | Tracks unhandled scripts errors (window.onerror) and then calls sendException. 372 | This function optionally can be passed an object containing a formmatter function 373 | which takes in all the args to window.onError and should return a String with 374 | the formatted error description to be sent to Google Analytics. Also the object 375 | can provide a fatal property which will be passed to sendException (defaults 376 | to true). 377 | 378 | **Kind**: static method of [analytics](#module_analytics) 379 | 380 | | Param | Type | Description | 381 | | --- | --- | --- | 382 | | [opts] | object | the options { formatter: Function, fatal: Boolean } | 383 | | [success] | function | the success callback | 384 | | [error] | function | the error callback | 385 | 386 | -------------------------------------------------------------------------------- /android/GoogleAnalyticsPlugin.java: -------------------------------------------------------------------------------- 1 | /* 2 | Licensed to the Apache Software Foundation (ASF) under one 3 | or more contributor license agreements. See the NOTICE file 4 | distributed with this work for additional information 5 | regarding copyright ownership. The ASF licenses this file 6 | to you under the Apache License, Version 2.0 (the 7 | "License"); you may not use this file except in compliance 8 | with the License. You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, 13 | software distributed under the License is distributed on an 14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | KIND, either express or implied. See the License for the 16 | specific language governing permissions and limitations 17 | under the License. 18 | */ 19 | 20 | package com.cmackay.plugins.googleanalytics; 21 | 22 | import com.google.android.gms.analytics.Logger.LogLevel; 23 | import com.google.android.gms.analytics.Tracker; 24 | import com.google.android.gms.analytics.GoogleAnalytics; 25 | 26 | import org.apache.cordova.CordovaInterface; 27 | import org.apache.cordova.CordovaPlugin; 28 | import org.apache.cordova.CordovaWebView; 29 | import org.apache.cordova.CallbackContext; 30 | import org.apache.cordova.PluginResult; 31 | 32 | import org.json.JSONArray; 33 | import org.json.JSONException; 34 | import org.json.JSONObject; 35 | 36 | import java.util.ArrayList; 37 | import java.util.Collections; 38 | import java.util.List; 39 | import java.util.Map; 40 | import java.util.HashMap; 41 | import java.util.Iterator; 42 | 43 | public class GoogleAnalyticsPlugin extends CordovaPlugin { 44 | 45 | private static GoogleAnalytics ga; 46 | private static List trackers = new ArrayList(); 47 | 48 | /** 49 | * Initializes the plugin 50 | * 51 | * @param cordova The context of the main Activity. 52 | * @param webView The associated CordovaWebView. 53 | */ 54 | @Override 55 | public void initialize(CordovaInterface cordova, CordovaWebView webView) { 56 | super.initialize(cordova, webView); 57 | ga = GoogleAnalytics.getInstance(cordova.getActivity()); 58 | } 59 | 60 | /** 61 | * Executes the request. 62 | * 63 | * @param action The action to execute. 64 | * @param args The exec() arguments. 65 | * @param callback The callback context used when calling back into JavaScript. 66 | * @return Whether the action was valid. 67 | */ 68 | @Override 69 | public boolean execute(String action, String rawArgs, CallbackContext callback) 70 | throws JSONException { 71 | 72 | if ("setTrackingId".equals(action)) { 73 | setTrackingId(rawArgs, callback); 74 | return true; 75 | 76 | } else if ("dispatchHits".equals(action)) { 77 | dispatchHits(rawArgs, callback); 78 | return true; 79 | 80 | } else if ("setDispatchInterval".equals(action)) { 81 | setDispatchInterval(rawArgs, callback); 82 | return true; 83 | 84 | } else if ("setLogLevel".equals(action)) { 85 | setLogLevel(rawArgs, callback); 86 | return true; 87 | 88 | } else if ("setIDFAEnabled".equals(action)) { 89 | setIDFAEnabled(rawArgs, callback); 90 | return true; 91 | 92 | } else if ("get".equals(action)) { 93 | get(rawArgs, callback); 94 | return true; 95 | 96 | } else if ("set".equals(action)) { 97 | set(rawArgs, callback); 98 | return true; 99 | 100 | } else if ("send".equals(action)) { 101 | send(rawArgs, callback); 102 | return true; 103 | 104 | } else if ("close".equals(action)) { 105 | close(rawArgs, callback); 106 | return true; 107 | 108 | } else if ("setAppOptOut".equals(action)) { 109 | setAppOptOut(rawArgs, callback); 110 | return true; 111 | 112 | } else if ("getAppOptOut".equals(action)) { 113 | getAppOptOut(callback); 114 | return true; 115 | } 116 | 117 | return false; 118 | } 119 | 120 | private void setTrackingId(String rawArgs, CallbackContext callback) { 121 | try { 122 | trackers.clear(); 123 | JSONArray jsonArray = new JSONArray(rawArgs); 124 | for (int i = 0; i < jsonArray.length(); i++) { 125 | trackers.add(ga.newTracker(new JSONArray(rawArgs).getString(i))); 126 | } 127 | // setup uncaught exception handler 128 | // Currently we always use the first tracker id. Only one tracker may be 129 | // used to report uncaught exceptions - developers.google.com/analytics/devguides/collection/android/v4/advanced#multiple-trackers 130 | trackers.get(0).enableExceptionReporting(true); 131 | callback.success(); 132 | } catch (JSONException e) { 133 | callback.error(e.toString()); 134 | } 135 | } 136 | 137 | private void dispatchHits(String rawArgs, CallbackContext callback) { 138 | ga.dispatchLocalHits(); 139 | callback.success(); 140 | } 141 | 142 | private void setDispatchInterval(String rawArgs, CallbackContext callback) { 143 | try { 144 | ga.setLocalDispatchPeriod(new JSONArray(rawArgs).getInt(0)); 145 | callback.success(); 146 | } catch (JSONException e) { 147 | callback.error(e.toString()); 148 | } 149 | } 150 | 151 | private void setLogLevel(String rawArgs, CallbackContext callbackContext) { 152 | if (hasTracker(callbackContext)) { 153 | try { 154 | int level = new JSONArray(rawArgs).getInt(0); 155 | int logLevel = LogLevel.WARNING; 156 | switch (level) { 157 | case 0: 158 | logLevel = LogLevel.VERBOSE; 159 | break; 160 | case 1: 161 | logLevel = LogLevel.INFO; 162 | break; 163 | case 2: 164 | logLevel = LogLevel.WARNING; 165 | break; 166 | case 3: 167 | logLevel = LogLevel.ERROR; 168 | break; 169 | } 170 | ga.getLogger().setLogLevel(logLevel); 171 | callbackContext.success(); 172 | } catch (JSONException e) { 173 | callbackContext.error(e.toString()); 174 | } 175 | } 176 | } 177 | 178 | private void setIDFAEnabled(String rawArgs, CallbackContext callbackContext) { 179 | if (hasTracker(callbackContext)) { 180 | for (Tracker tracker : trackers) { 181 | tracker.enableAdvertisingIdCollection(true); 182 | } 183 | callbackContext.success(); 184 | } 185 | } 186 | 187 | private void get(String rawArgs, CallbackContext callbackContext) { 188 | if (hasTracker(callbackContext)) { 189 | try { 190 | String param = new JSONArray(rawArgs).getString(0); 191 | if (trackers.size() == 1) { 192 | callbackContext.success(trackers.iterator().next().get(param)); 193 | } else if (trackers.size() > 1) { 194 | /* 195 | * Returns an array of tracker id and value combinations, e.g., 196 | * [{ "tid1" : "param_value1" }, { "tid2" : "param_value2" }] 197 | */ 198 | JSONArray jsonArray = new JSONArray(); 199 | for (Tracker tracker : trackers) { 200 | String id = tracker.get("&tid"); 201 | if (id != null) { 202 | Object value = tracker.get(param); 203 | JSONObject obj = new JSONObject(); 204 | obj.putOpt(id, value != null ? value : JSONObject.NULL); 205 | jsonArray.put(obj); 206 | } 207 | } 208 | callbackContext.success(jsonArray.toString()); 209 | } else { 210 | callbackContext.success(); 211 | } 212 | } catch (JSONException e) { 213 | callbackContext.error(e.toString()); 214 | } 215 | } 216 | } 217 | 218 | private void set(String rawArgs, CallbackContext callbackContext) { 219 | if (hasTracker(callbackContext)) { 220 | try { 221 | JSONArray args = new JSONArray(rawArgs); 222 | String key = args.getString(0); 223 | String value = args.isNull(1) ? null : args.getString(1); 224 | for (Tracker tracker : trackers) { 225 | tracker.set(key, value); 226 | } 227 | callbackContext.success(); 228 | } catch (JSONException e) { 229 | callbackContext.error(e.toString()); 230 | } 231 | } 232 | } 233 | 234 | private void send(final String rawArgs, final CallbackContext callbackContext) { 235 | cordova.getThreadPool().execute(new Runnable() { 236 | public void run() { 237 | GoogleAnalyticsPlugin plugin = GoogleAnalyticsPlugin.this; 238 | if (plugin.hasTracker(callbackContext)) { 239 | try { 240 | JSONArray args = new JSONArray(rawArgs); 241 | for (Tracker tracker : plugin.trackers) { 242 | tracker.send(objectToMap(args.getJSONObject(0))); 243 | } 244 | callbackContext.success(); 245 | } catch (JSONException e) { 246 | callbackContext.error(e.toString()); 247 | } 248 | } 249 | } 250 | }); 251 | } 252 | 253 | private void close(final String rawArgs, final CallbackContext callbackContext) { 254 | cordova.getThreadPool().execute(new Runnable() { 255 | public void run() { 256 | GoogleAnalyticsPlugin plugin = GoogleAnalyticsPlugin.this; 257 | if (plugin.hasTracker(callbackContext)) { 258 | plugin.ga.dispatchLocalHits(); 259 | plugin.trackers.clear(); 260 | callbackContext.success(); 261 | } 262 | } 263 | }); 264 | } 265 | 266 | private boolean hasTracker(CallbackContext callbackContext) { 267 | if (trackers.isEmpty()) { 268 | callbackContext.error("Tracker(s) not initialized. Call setTrackingId or setMultipleTrackingIds prior to using tracker."); 269 | return false; 270 | } 271 | return true; 272 | } 273 | 274 | private static Map objectToMap(JSONObject o) throws JSONException { 275 | if (o.length() == 0) { 276 | return Collections.emptyMap(); 277 | } 278 | Map map = new HashMap(o.length()); 279 | Iterator it = o.keys(); 280 | String key, value; 281 | while (it.hasNext()) { 282 | key = it.next().toString(); 283 | value = o.has(key) ? o.get(key).toString(): null; 284 | map.put(key, value); 285 | } 286 | return map; 287 | } 288 | 289 | private void setAppOptOut(final String rawArgs, CallbackContext callbackContext) { 290 | try { 291 | ga.setAppOptOut(new JSONArray(rawArgs).getBoolean(0)); 292 | callbackContext.success(); 293 | } catch (JSONException e) { 294 | callbackContext.error(e.toString()); 295 | } 296 | } 297 | 298 | private void getAppOptOut(CallbackContext callbackContext) { 299 | callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, ga.getAppOptOut())); 300 | } 301 | 302 | } 303 | -------------------------------------------------------------------------------- /android/version.xml: -------------------------------------------------------------------------------- 1 | 2 | 6171000 3 | 4 | -------------------------------------------------------------------------------- /ios/GAI.h: -------------------------------------------------------------------------------- 1 | /*! 2 | @header GAI.h 3 | @abstract Google Analytics iOS SDK Header 4 | @version 3.17 5 | @copyright Copyright 2015 Google Inc. All rights reserved. 6 | */ 7 | 8 | #import 9 | 10 | #import "GAILogger.h" 11 | #import "GAITrackedViewController.h" 12 | #import "GAITracker.h" 13 | 14 | typedef NS_ENUM(NSUInteger, GAIDispatchResult) { 15 | kGAIDispatchNoData, 16 | kGAIDispatchGood, 17 | kGAIDispatchError 18 | }; 19 | 20 | /*! Google Analytics product string. */ 21 | extern NSString *const kGAIProduct; 22 | 23 | /*! Google Analytics version string. */ 24 | extern NSString *const kGAIVersion; 25 | 26 | /*! 27 | NSError objects returned by the Google Analytics SDK may have this error domain 28 | to indicate that the error originated in the Google Analytics SDK. 29 | */ 30 | extern NSString *const kGAIErrorDomain; 31 | 32 | /*! Google Analytics error codes. */ 33 | typedef enum { 34 | // This error code indicates that there was no error. Never used. 35 | kGAINoError = 0, 36 | 37 | // This error code indicates that there was a database-related error. 38 | kGAIDatabaseError, 39 | 40 | // This error code indicates that there was a network-related error. 41 | kGAINetworkError, 42 | } GAIErrorCode; 43 | 44 | /*! 45 | Google Analytics iOS top-level class. Provides facilities to create trackers 46 | and set behaviorial flags. 47 | */ 48 | @interface GAI : NSObject 49 | 50 | /*! 51 | For convenience, this class exposes a default tracker instance. 52 | This is initialized to `nil` and will be set to the first tracker that is 53 | instantiated in trackerWithTrackingId:. It may be overridden as desired. 54 | 55 | The GAITrackedViewController class will, by default, use this tracker instance. 56 | */ 57 | @property(nonatomic, assign) id defaultTracker; 58 | 59 | /*! 60 | The GAILogger to use. 61 | */ 62 | @property(nonatomic, retain) id logger; 63 | 64 | /*! 65 | When this is true, no tracking information will be gathered; tracking calls 66 | will effectively become no-ops. When set to true, all tracking information that 67 | has not yet been submitted. The value of this flag will be persisted 68 | automatically by the SDK. Developers can optionally use this flag to implement 69 | an opt-out setting in the app to allows users to opt out of Google Analytics 70 | tracking. 71 | 72 | This is set to `NO` the first time the Google Analytics SDK is used on a 73 | device, and is persisted thereafter. 74 | */ 75 | @property(nonatomic, assign) BOOL optOut; 76 | 77 | /*! 78 | If this value is positive, tracking information will be automatically 79 | dispatched every dispatchInterval seconds. Otherwise, tracking information must 80 | be sent manually by calling dispatch. 81 | 82 | By default, this is set to `120`, which indicates tracking information should 83 | be dispatched automatically every 120 seconds. 84 | */ 85 | @property(nonatomic, assign) NSTimeInterval dispatchInterval; 86 | 87 | /*! 88 | When set to true, the SDK will record the currently registered uncaught 89 | exception handler, and then register an uncaught exception handler which tracks 90 | the exceptions that occurred using defaultTracker. If defaultTracker is not 91 | `nil`, this function will track the exception on the tracker and attempt to 92 | dispatch any outstanding tracking information for 5 seconds. It will then call 93 | the previously registered exception handler, if any. When set back to false, 94 | the previously registered uncaught exception handler will be restored. 95 | */ 96 | @property(nonatomic, assign) BOOL trackUncaughtExceptions; 97 | 98 | /*! 99 | When this is 'YES', no tracking information will be sent. Defaults to 'NO'. 100 | */ 101 | @property(nonatomic, assign) BOOL dryRun; 102 | 103 | /*! Get the shared instance of the Google Analytics for iOS class. */ 104 | + (GAI *)sharedInstance; 105 | 106 | /*! 107 | Creates or retrieves a GAITracker implementation with the specified name and 108 | tracking ID. If the tracker for the specified name does not already exist, then 109 | it will be created and returned; otherwise, the existing tracker will be 110 | returned. If the existing tracker for the respective name has a different 111 | tracking ID, that tracking ID is not changed by this method. If defaultTracker 112 | is not set, it will be set to the tracker instance returned here. 113 | 114 | @param name The name of this tracker. Must not be `nil` or empty. 115 | 116 | @param trackingID The tracking ID to use for this tracker. It should be of 117 | the form `UA-xxxxx-y`. 118 | 119 | @return A GAITracker associated with the specified name. The tracker 120 | can be used to send tracking data to Google Analytics. The first time this 121 | method is called with a particular name, the tracker for that name will be 122 | returned, and subsequent calls with the same name will return the same 123 | instance. It is not necessary to retain the tracker because the tracker will be 124 | retained internally by the library. 125 | 126 | If an error occurs or the name is not valid, this method will return 127 | `nil`. 128 | */ 129 | - (id)trackerWithName:(NSString *)name 130 | trackingId:(NSString *)trackingId; 131 | 132 | /*! 133 | Creates or retrieves a GAITracker implementation with name equal to 134 | the specified tracking ID. If the tracker for the respective name does not 135 | already exist, it is created, has it's tracking ID set to |trackingId|, 136 | and is returned; otherwise, the existing tracker is returned. If the existing 137 | tracker for the respective name has a different tracking ID, that tracking ID 138 | is not changed by this method. If defaultTracker is not set, it is set to the 139 | tracker instance returned here. 140 | 141 | @param trackingID The tracking ID to use for this tracker. It should be of 142 | the form `UA-xxxxx-y`. The name of the tracker will be the same as trackingID. 143 | 144 | @return A GAITracker associated with the specified trackingID. The tracker 145 | can be used to send tracking data to Google Analytics. The first time this 146 | method is called with a particular trackingID, the tracker for the respective 147 | name will be returned, and subsequent calls with the same trackingID 148 | will return the same instance. It is not necessary to retain the tracker 149 | because the tracker will be retained internally by the library. 150 | 151 | If an error occurs or the trackingId is not valid, this method will return 152 | `nil`. 153 | */ 154 | - (id)trackerWithTrackingId:(NSString *)trackingId; 155 | 156 | /*! 157 | Remove a tracker from the trackers dictionary. If it is the default tracker, 158 | clears the default tracker as well. 159 | 160 | @param name The name of the tracker. 161 | */ 162 | - (void)removeTrackerByName:(NSString *)name; 163 | 164 | /*! 165 | Dispatches any pending tracking information. 166 | 167 | Note that this does not have any effect on dispatchInterval, and can be used in 168 | conjunction with periodic dispatch. */ 169 | - (void)dispatch; 170 | 171 | /*! 172 | Dispatches the next tracking beacon in the queue, calling completionHandler when 173 | the tracking beacon has either been sent (returning kGAIDispatchGood) or an error has resulted 174 | (returning kGAIDispatchError). If there is no network connection or there is no data to send, 175 | kGAIDispatchNoData is returned. 176 | 177 | Note that calling this method with a non-nil completionHandler disables periodic dispatch. 178 | Periodic dispatch can be reenabled by setting the dispatchInterval to a positive number when 179 | the app resumes from the background. 180 | 181 | Calling this method with a nil completionHandler is the same as calling the dispatch 182 | above. 183 | 184 | This method can be used for background data fetching in iOS 7.0 or later. It would be wise to 185 | call this when the application is exiting to initiate the submission of any unsubmitted 186 | tracking information. 187 | 188 | @param completionHandler The block to run after a single dispatch request. The GAIDispatchResult 189 | param indicates whether the dispatch succeeded, had an error, or had no hits to dispatch. 190 | */ 191 | - (void)dispatchWithCompletionHandler:(void (^)(GAIDispatchResult result))completionHandler; 192 | @end 193 | -------------------------------------------------------------------------------- /ios/GAIDictionaryBuilder.h: -------------------------------------------------------------------------------- 1 | /*! 2 | @header GAIDictionaryBuilder.h 3 | @abstract Google Analytics iOS SDK Hit Format Header 4 | @copyright Copyright 2013 Google Inc. All rights reserved. 5 | */ 6 | 7 | #import 8 | 9 | #import "GAIEcommerceProduct.h" 10 | #import "GAIEcommerceProductAction.h" 11 | #import "GAIEcommercePromotion.h" 12 | 13 | /*! 14 | * Helper class to build a dictionary of hit parameters and values. 15 | *
16 | * Examples: 17 | * 18 | * id t = // get a tracker. 19 | * [t send:[[[GAIDictionaryBuilder createEventWithCategory:@"EventCategory" 20 | * action:@"EventAction" 21 | * label:nil 22 | * value:nil] 23 | * set:@"dimension1" forKey:[GAIFields customDimensionForIndex:1]] build]]; 24 | * 25 | * This will send an event hit type with the specified parameters 26 | * and a custom dimension parameter. 27 | *
28 | * If you want to send a parameter with all hits, set it on GAITracker directly. 29 | * 30 | * [t set:kGAIScreenName value:@"Home"]; 31 | * [t send:[[GAIDictionaryBuilder createSocialWithNetwork:@"Google+" 32 | * action:@"PlusOne" 33 | * target:@"SOME_URL"] build]]; 34 | * [t send:[[GAIDictionaryBuilder createSocialWithNetwork:@"Google+" 35 | * action:@"Share" 36 | * target:@"SOME_POST"] build]]; 37 | * [t send:[[GAIDictionaryBuilder createSocialWithNetwork:@"Google+" 38 | * action:@"HangOut" 39 | * target:@"SOME_CIRCLE"] 40 | * build]]; 41 | * 42 | * You can override a value set on the tracker by adding it to the dictionary. 43 | * 44 | * [t set:kGAIScreenName value:@"Home"]; 45 | * [t send:...]; 46 | * [t send[[[GAIDictionaryBuilder createEventWithCategory:@"click" 47 | * action:@"popup" 48 | * label:nil 49 | * value:nil] 50 | * set:@"popup title" forKey:kGAIScreenName] build]]; 51 | * 52 | * The values set via [GAIDictionaryBuilder set] or 53 | * [GAIDictionaryBuilder setAll] will override any existing values in the 54 | * GAIDictionaryBuilder object (i.e. initialized by 55 | * [GAIDictionaryBuilder createXYZ]). e.g. 56 | * 57 | * GAIDictionaryBuilder *m = 58 | * GAIDictionaryBuilder createTimingWithCategory:@"category" 59 | * interval:@0 60 | * name:@"name" 61 | * label:nil]; 62 | * [t send:[m.set:@"10" forKey:kGAITimingVar] build]; 63 | * [t send:[m.set:@"20" forKey:kGAITimingVar] build]; 64 | * 65 | */ 66 | @interface GAIDictionaryBuilder : NSObject 67 | 68 | - (GAIDictionaryBuilder *)set:(NSString *)value 69 | forKey:(NSString *)key; 70 | 71 | /*! 72 | * Copies all the name-value pairs from params into this object, ignoring any 73 | * keys that are not NSString and any values that are neither NSString or 74 | * NSNull. 75 | */ 76 | - (GAIDictionaryBuilder *)setAll:(NSDictionary *)params; 77 | 78 | /*! 79 | * Returns the value for the input parameter paramName, or nil if paramName 80 | * is not present. 81 | */ 82 | - (NSString *)get:(NSString *)paramName; 83 | 84 | /*! 85 | * Return an NSMutableDictionary object with all the parameters set in this 86 | */ 87 | - (NSMutableDictionary *)build; 88 | 89 | /*! 90 | * Parses and translates utm campaign parameters to analytics campaign param 91 | * and returns them as a map. 92 | * 93 | * @param params url containing utm campaign parameters. 94 | * 95 | * Valid campaign parameters are: 96 | *
    97 | *
  • utm_id
  • 98 | *
  • utm_campaign
  • 99 | *
  • utm_content
  • 100 | *
  • utm_medium
  • 101 | *
  • utm_source
  • 102 | *
  • utm_term
  • 103 | *
  • dclid
  • 104 | *
  • gclid
  • 105 | *
  • gmob_t
  • 106 | *
  • aclid
  • 107 | *
  • anid
  • 108 | *
109 | *

110 | * Example: 111 | * http://my.site.com/index.html?utm_campaign=wow&utm_source=source 112 | * utm_campaign=wow&utm_source=source. 113 | *

114 | * For more information on manual and auto-tagging, see 115 | * https://support.google.com/analytics/answer/1733663?hl=en 116 | */ 117 | - (GAIDictionaryBuilder *)setCampaignParametersFromUrl:(NSString *)urlString; 118 | 119 | /*! 120 | Returns a GAIDictionaryBuilder object with parameters specific to an appview 121 | hit. 122 | 123 | Note that using this method will not set the screen name for followon hits. To 124 | do that you need to call set:kGAIDescription value: on the 125 | GAITracker instance. 126 | 127 | This method is deprecated. Use createScreenView instead. 128 | */ 129 | + (GAIDictionaryBuilder *)createAppView DEPRECATED_MSG_ATTRIBUTE("Use createScreenView instead."); 130 | 131 | /*! 132 | Returns a GAIDictionaryBuilder object with parameters specific to a screenview 133 | hit. 134 | 135 | Note that using this method will not set the screen name for followon hits. To 136 | do that you need to call set:kGAIDescription value: on the 137 | GAITracker instance. 138 | */ 139 | + (GAIDictionaryBuilder *)createScreenView; 140 | 141 | /*! 142 | Returns a GAIDictionaryBuilder object with parameters specific to an event hit. 143 | */ 144 | + (GAIDictionaryBuilder *)createEventWithCategory:(NSString *)category 145 | action:(NSString *)action 146 | label:(NSString *)label 147 | value:(NSNumber *)value; 148 | 149 | /*! 150 | Returns a GAIDictionaryBuilder object with parameters specific to an exception 151 | hit. 152 | */ 153 | + (GAIDictionaryBuilder *)createExceptionWithDescription:(NSString *)description 154 | withFatal:(NSNumber *)fatal; 155 | 156 | /*! 157 | Returns a GAIDictionaryBuilder object with parameters specific to an item hit. 158 | */ 159 | + (GAIDictionaryBuilder *)createItemWithTransactionId:(NSString *)transactionId 160 | name:(NSString *)name 161 | sku:(NSString *)sku 162 | category:(NSString *)category 163 | price:(NSNumber *)price 164 | quantity:(NSNumber *)quantity 165 | currencyCode:(NSString *)currencyCode; 166 | 167 | /*! 168 | Returns a GAIDictionaryBuilder object with parameters specific to a social hit. 169 | */ 170 | + (GAIDictionaryBuilder *)createSocialWithNetwork:(NSString *)network 171 | action:(NSString *)action 172 | target:(NSString *)target; 173 | 174 | /*! 175 | Returns a GAIDictionaryBuilder object with parameters specific to a timing hit. 176 | */ 177 | + (GAIDictionaryBuilder *)createTimingWithCategory:(NSString *)category 178 | interval:(NSNumber *)intervalMillis 179 | name:(NSString *)name 180 | label:(NSString *)label; 181 | 182 | /*! 183 | Returns a GAIDictionaryBuilder object with parameters specific to a transaction 184 | hit. 185 | */ 186 | + (GAIDictionaryBuilder *)createTransactionWithId:(NSString *)transactionId 187 | affiliation:(NSString *)affiliation 188 | revenue:(NSNumber *)revenue 189 | tax:(NSNumber *)tax 190 | shipping:(NSNumber *)shipping 191 | currencyCode:(NSString *)currencyCode; 192 | 193 | /*! 194 | Set the product action field for this hit. 195 | */ 196 | - (GAIDictionaryBuilder *)setProductAction:(GAIEcommerceProductAction *)productAction; 197 | 198 | /*! 199 | Adds a product to this hit. 200 | */ 201 | - (GAIDictionaryBuilder *)addProduct:(GAIEcommerceProduct *)product; 202 | 203 | /*! 204 | Add a product impression to this hit. 205 | */ 206 | - (GAIDictionaryBuilder *)addProductImpression:(GAIEcommerceProduct *)product 207 | impressionList:(NSString *)name 208 | impressionSource:(NSString *)source; 209 | 210 | /*! 211 | Add a promotion to this hit. 212 | */ 213 | - (GAIDictionaryBuilder *)addPromotion:(GAIEcommercePromotion *)promotion; 214 | @end 215 | -------------------------------------------------------------------------------- /ios/GAIEcommerceFields.h: -------------------------------------------------------------------------------- 1 | /*! 2 | @header GAIEcommerceFields.h 3 | @abstract Google Analytics iOS SDK Ecommerce Hit Format Header 4 | @copyright Copyright 2014 Google Inc. All rights reserved. 5 | */ 6 | 7 | #import 8 | 9 | /*! 10 | This class provides several fields and methods useful as wire format parameters for 11 | Enhanced Ecommerce. See the online developer guides for Enhanced Ecommerce for details 12 | on how to use the Enhanced Ecommerce features. 13 | */ 14 | 15 | // Enhanced Ecommerce Product fields 16 | extern NSString *const kGAIProductId; 17 | extern NSString *const kGAIProductName; 18 | extern NSString *const kGAIProductBrand; 19 | extern NSString *const kGAIProductCategory; 20 | extern NSString *const kGAIProductVariant; 21 | extern NSString *const kGAIProductPrice; 22 | extern NSString *const kGAIProductQuantity; 23 | extern NSString *const kGAIProductCouponCode; 24 | extern NSString *const kGAIProductPosition; 25 | 26 | extern NSString *const kGAIProductAction; 27 | 28 | // product action values 29 | extern NSString *const kGAIPADetail; 30 | extern NSString *const kGAIPAClick; 31 | extern NSString *const kGAIPAAdd; 32 | extern NSString *const kGAIPARemove; 33 | extern NSString *const kGAIPACheckout; 34 | extern NSString *const kGAIPACheckoutOption; 35 | extern NSString *const kGAIPAPurchase; 36 | extern NSString *const kGAIPARefund; 37 | 38 | // product action fields 39 | // used for 'purchase' and 'refund' actions 40 | extern NSString *const kGAIPATransactionId; 41 | extern NSString *const kGAIPAAffiliation; 42 | extern NSString *const kGAIPARevenue; 43 | extern NSString *const kGAIPATax; 44 | extern NSString *const kGAIPAShipping; 45 | extern NSString *const kGAIPACouponCode; 46 | // used for 'checkout' action 47 | extern NSString *const kGAICheckoutStep; 48 | extern NSString *const kGAICheckoutOption; 49 | // used for 'detail' and 'click' actions 50 | extern NSString *const kGAIProductActionList; 51 | extern NSString *const kGAIProductListSource; 52 | 53 | // Enhanced Ecommerce Impressions fields 54 | extern NSString *const kGAIImpressionName; 55 | extern NSString *const kGAIImpressionListSource; 56 | extern NSString *const kGAIImpressionProduct; 57 | extern NSString *const kGAIImpressionProductId; 58 | extern NSString *const kGAIImpressionProductName; 59 | extern NSString *const kGAIImpressionProductBrand; 60 | extern NSString *const kGAIImpressionProductCategory; 61 | extern NSString *const kGAIImpressionProductVariant; 62 | extern NSString *const kGAIImpressionProductPosition; 63 | extern NSString *const kGAIImpressionProductPrice; 64 | 65 | // Enhanced Ecommerce Promotions fields 66 | extern NSString *const kGAIPromotionId; 67 | extern NSString *const kGAIPromotionName; 68 | extern NSString *const kGAIPromotionCreative; 69 | extern NSString *const kGAIPromotionPosition; 70 | 71 | // Promotion actions 72 | extern NSString *const kGAIPromotionAction; 73 | extern NSString *const kGAIPromotionView; 74 | extern NSString *const kGAIPromotionClick; 75 | 76 | @interface GAIEcommerceFields : NSObject 77 | 78 | /*! 79 | Generates an enhanced ecommerce product field. Note that field names generated by 80 | customDimensionForIndex and customMetricForIndex can be used as suffixes. 81 | 82 | @param index the index of the product 83 | @param suffix the product field suffix (such as kGAIProductPrice). 84 | 85 | @return an NSString representing the product field parameter 86 | */ 87 | + (NSString *)productFieldForIndex:(NSUInteger)index suffix:(NSString *)suffix; 88 | 89 | /*! 90 | Genrates an enhanced ecommerce impression list field name with an index. The return value of 91 | this method should also be used as input to the productImpressionForList method below. 92 | 93 | @param index the index of the impression list 94 | 95 | @return an NSString representing the impression list parameter 96 | */ 97 | + (NSString *)impressionListForIndex:(NSUInteger)index; 98 | 99 | /*! 100 | Generates an enhanced ecommerce product impression field with the impression list, product index 101 | and product suffix as parameters. The output of the method impressionListForIndex above should be 102 | used as the input list for this method. The output of customDimensionForIndex and 103 | customMetricForIndex can be used as suffixes. 104 | 105 | @param list the impression list for this product impression 106 | @param index the index of this product in the impression list 107 | @param suffix the product impression suffix for this field 108 | 109 | @return an NSString representing this product impression field parameter 110 | */ 111 | + (NSString *)productImpressionForList:(NSString *)list 112 | index:(NSUInteger)index 113 | suffix:(NSString *)Suffix; 114 | 115 | /*! 116 | Generates an enhanced ecommerce promotion field with an index and suffix. 117 | 118 | @param index the index of the promotion 119 | @param suffix the promotion suffix (such as kGAIPromotionId) 120 | 121 | @return an NSString representing this promotion field paramter 122 | */ 123 | + (NSString *)promotionForIndex:(NSUInteger)index suffix:(NSString *)suffix; 124 | @end 125 | -------------------------------------------------------------------------------- /ios/GAIEcommerceProduct.h: -------------------------------------------------------------------------------- 1 | /*! 2 | @header GAIEcommerceProduct.h 3 | @abstract Google Analytics iOS SDK Hit Format Header 4 | @copyright Copyright 2014 Google Inc. All rights reserved. 5 | */ 6 | 7 | #import 8 | 9 | /*! 10 | * Class to construct product related information for a Google Analytics beacon. Use this class to 11 | * report information about products sold by merchants or impressions of products seen by users. 12 | * Instances of this class can be associated with both Product Actions and Product 13 | * Impression Lists. 14 | *
15 | * Typical usage: 16 | * 17 | * [tracker set:kGAIScreenName value:@"MyScreen"]; 18 | * GAIDictionaryBuilder *builder = [GAIDictionaryBuilder createScreenView]; 19 | * GAIEcommerceProduct *product = [[GAIEcommerceProduct alloc] init]; 20 | * [product setId:@""PID-1234""]; 21 | * [product setName:@"Space Monkeys!"]; 22 | * [product setPrice:@100]; 23 | * [product setQuantity:@2]; 24 | * [builder addProductImpression:product impressionList:@"listName"]; 25 | * [tracker send:[builder build]]; 26 | * 27 | */ 28 | @interface GAIEcommerceProduct : NSObject 29 | 30 | /*! 31 | Sets the id that is used to identify a product in GA reports. 32 | */ 33 | - (GAIEcommerceProduct *)setId:(NSString *)productId; 34 | 35 | /*! 36 | Sets the name that is used to indentify the product in GA reports. 37 | */ 38 | - (GAIEcommerceProduct *)setName:(NSString *)productName; 39 | 40 | /*! 41 | Sets the brand associated with the product in GA reports. 42 | */ 43 | - (GAIEcommerceProduct *)setBrand:(NSString *)productBrand; 44 | 45 | /*! 46 | Sets the category associated with the product in GA reports. 47 | */ 48 | - (GAIEcommerceProduct *)setCategory:(NSString *)productCategory; 49 | 50 | /*! 51 | Sets the variant of the product. 52 | */ 53 | - (GAIEcommerceProduct *)setVariant:(NSString *)productVariant; 54 | 55 | /*! 56 | Sets the price of the product. 57 | */ 58 | - (GAIEcommerceProduct *)setPrice:(NSNumber *)productPrice; 59 | 60 | /*! 61 | Sets the quantity of the product. This field is usually not used with product impressions. 62 | */ 63 | - (GAIEcommerceProduct *)setQuantity:(NSNumber *)productQuantity; 64 | 65 | /*! 66 | Sets the coupon code associated with the product. This field is usually not used with product 67 | impressions. 68 | */ 69 | - (GAIEcommerceProduct *)setCouponCode:(NSString *)productCouponCode; 70 | 71 | /*! 72 | Sets the position of the product on the screen/product impression list, etc. 73 | */ 74 | - (GAIEcommerceProduct *)setPosition:(NSNumber *)productPosition; 75 | 76 | /*! 77 | Sets the custom dimension associated with this product. 78 | */ 79 | - (GAIEcommerceProduct *)setCustomDimension:(NSUInteger)index value:(NSString *)value; 80 | 81 | /*! 82 | Sets the custom metric associated with this product. 83 | */ 84 | - (GAIEcommerceProduct *)setCustomMetric:(NSUInteger)index value:(NSNumber *)value; 85 | 86 | /*! 87 | Builds an NSDictionary of fields stored in this instance suitable for a product action. The 88 | index parameter is the index of this product in the product action list. 89 |
90 | Normally, users will have no need to call this method. 91 | */ 92 | - (NSDictionary *)buildWithIndex:(NSUInteger)index; 93 | 94 | /*! 95 | Builds an NSDictionary of fields stored in this instance suitable for an impression list. The 96 | lIndex parameter is the index of the product impression list while the index parameter is the 97 | index of this product in that impression list. 98 |
99 | Normally, users will have no need to call this method. 100 | */ 101 | - (NSDictionary *)buildWithListIndex:(NSUInteger)lIndex index:(NSUInteger)index; 102 | @end 103 | -------------------------------------------------------------------------------- /ios/GAIEcommerceProductAction.h: -------------------------------------------------------------------------------- 1 | /*! 2 | @header GAIProductAction.h 3 | @abstract Google Analytics iOS SDK Hit Format Header 4 | @copyright Copyright 2014 Google Inc. All rights reserved. 5 | */ 6 | 7 | #import 8 | 9 | /*! 10 | * Class to construct transaction/checkout or other product interaction related information for a 11 | * Google Analytics hit. Use this class to report information about products sold, viewed or 12 | * refunded. This class is intended to be used with GAIDictionaryBuilder. 13 | *
14 | * Typical usage: 15 | * 16 | * [tracker set:kGAIScreenName value:@"MyScreen"]; 17 | * GAIDictionaryBuilder *builder = [GAIDictionaryBuilder createScreenView]; 18 | * GAIEcommerceProductAction *action = [[GAIEcommerceProductAction alloc] init]; 19 | * [action setAction:kGAIPAPurchase]; 20 | * [action setTransactionId:@"TT-1234"]; 21 | * [action setRevenue:@3.14]; 22 | * [action setCouponCode:@"EXTRA100"]; 23 | * [builder setProductAction:action]; 24 | * GAIEcommerceProduct *product = [[GAIEcommerceProduct alloc] init]; 25 | * [product setId:@""PID-1234""]; 26 | * [product setName:@"Space Monkeys!"]; 27 | * [product setPrice:@100]; 28 | * [product setQuantity:@2]; 29 | * [builder addProduct:product]; 30 | * [tracker send:[builder build]]; 31 | * 32 | */ 33 | @interface GAIEcommerceProductAction : NSObject 34 | 35 | /*! 36 | Sets the product action field for this product action. Valid values can be found in 37 | GAIEcommerceFields.h under "product action values". 38 | */ 39 | - (GAIEcommerceProductAction *)setAction:(NSString *)productAction; 40 | 41 | /*! 42 | The unique id associated with the transaction. This value is used for kGAIPAPurchase and 43 | kGAIPARefund product actions. 44 | */ 45 | - (GAIEcommerceProductAction *)setTransactionId:(NSString *)transactionId; 46 | 47 | /*! 48 | Sets the transaction's affiliation value. This value is used for kGAIPAPurchase and 49 | kGAIPARefund product actions. 50 | */ 51 | - (GAIEcommerceProductAction *)setAffiliation:(NSString *)affiliation; 52 | 53 | /*! 54 | Sets the transaction's total revenue. This value is used for kGAIPAPurchase and kGAIPARefund 55 | product actions. 56 | */ 57 | - (GAIEcommerceProductAction *)setRevenue:(NSNumber *)revenue; 58 | 59 | /*! 60 | Sets the transaction's total tax. This value is used for kGAIPAPurchase and kGAIPARefund 61 | product actions. 62 | */ 63 | - (GAIEcommerceProductAction *)setTax:(NSNumber *)tax; 64 | 65 | /*! 66 | Sets the transaction's total shipping costs. This value is used for kGAIPAPurchase and 67 | kGAIPARefund product actions. 68 | */ 69 | - (GAIEcommerceProductAction *)setShipping:(NSNumber *)shipping; 70 | 71 | /*! 72 | Sets the coupon code used in this transaction. This value is used for kGAIPAPurchase and 73 | kGAIPARefund product actions. 74 | */ 75 | - (GAIEcommerceProductAction *)setCouponCode:(NSString *)couponCode; 76 | 77 | /*! 78 | Sets the checkout process's progress. This value is used for kGAICheckout and 79 | kGAICheckoutOptions product actions. 80 | */ 81 | - (GAIEcommerceProductAction *)setCheckoutStep:(NSNumber *)checkoutStep; 82 | 83 | /*! 84 | Sets the option associated with the checkout. This value is used for kGAICheckout and 85 | kGAICheckoutOptions product actions. 86 | */ 87 | - (GAIEcommerceProductAction *)setCheckoutOption:(NSString *)checkoutOption; 88 | 89 | /*! 90 | Sets the list name associated with the products in Google Analytics beacons. This value is 91 | used in kGAIPADetail and kGAIPAClick product actions. 92 | */ 93 | - (GAIEcommerceProductAction *)setProductActionList:(NSString *)productActionList; 94 | 95 | /*! 96 | Sets the list source name associated with the products in Google Analytics beacons. This value 97 | is used in kGAIPADetail and kGAIPAClick product actions. 98 | */ 99 | - (GAIEcommerceProductAction *)setProductListSource:(NSString *)productListSource; 100 | 101 | /*! 102 | Builds an NSDictionary of fields stored in this instance representing this product action. 103 |
104 | Normally, users will have no need to call this method. 105 | */ 106 | - (NSDictionary *)build; 107 | @end 108 | -------------------------------------------------------------------------------- /ios/GAIEcommercePromotion.h: -------------------------------------------------------------------------------- 1 | /*! 2 | @header GAIEcommercePromotion.h 3 | @abstract Google Analytics iOS SDK Hit Format Header 4 | @copyright Copyright 2014 Google Inc. All rights reserved. 5 | */ 6 | 7 | #import 8 | 9 | /*! 10 | * Class to construct promotion related fields for Google Analytics hits. The fields from this class 11 | * can be used to represent internal promotions that run within an app, such as banners, banner ads 12 | * etc. 13 | * 14 | * Typical usage: 15 | * 16 | * GAIDictionaryBuilder *builder = [GAIDictionaryBuilder createScreenView]; 17 | * GAIEcommercePromotion *promotion = [[GAIEcommercePromotion alloc] init]; 18 | * [promotion setId:@"PROMO-ID1234"]; 19 | * [promotion setName:@"Home screen banner"]; 20 | * [builder set:kGAIPromotionClick forKey:kGAIPromotionAction]; 21 | * [builder addPromotion:promotion]; 22 | * [tracker send:builder.build]]; 23 | * 24 | */ 25 | @interface GAIEcommercePromotion : NSObject 26 | 27 | /*! 28 | Sets the id that is used to identify a promotion in GA reports. 29 | */ 30 | - (GAIEcommercePromotion *)setId:(NSString *)pid; 31 | 32 | /*! 33 | Sets the name that is used to identify a promotion in GA reports. 34 | */ 35 | - (GAIEcommercePromotion *)setName:(NSString *)name; 36 | 37 | /*! 38 | Sets the name of the creative associated with the promotion. 39 | */ 40 | - (GAIEcommercePromotion *)setCreative:(NSString *)creative; 41 | 42 | /*! 43 | Sets the position of the promotion. 44 | */ 45 | - (GAIEcommercePromotion *)setPosition:(NSString *)position; 46 | 47 | /*! 48 | Builds an NSDictionary of fields stored in this instance. The index parameter is the 49 | index of this promotion in that promotion list. 50 |
51 | Normally, users will have no need to call this method. 52 | */ 53 | - (NSDictionary *)buildWithIndex:(NSUInteger)index; 54 | @end 55 | -------------------------------------------------------------------------------- /ios/GAIFields.h: -------------------------------------------------------------------------------- 1 | /*! 2 | @header GAIFields.h 3 | @abstract Google Analytics iOS SDK Hit Format Header 4 | @copyright Copyright 2013 Google Inc. All rights reserved. 5 | */ 6 | 7 | #import 8 | 9 | /*! 10 | These fields can be used for the wire format parameter names required by 11 | the |GAITracker| get, set and send methods as well as the set methods in the 12 | |GAIDictionaryBuilder| class. 13 | */ 14 | extern NSString *const kGAIUseSecure; 15 | 16 | extern NSString *const kGAIHitType; 17 | extern NSString *const kGAITrackingId; 18 | extern NSString *const kGAIClientId; 19 | extern NSString *const kGAIDataSource; 20 | extern NSString *const kGAIAnonymizeIp; 21 | extern NSString *const kGAISessionControl; 22 | extern NSString *const kGAIDeviceModelVersion; 23 | extern NSString *const kGAIScreenResolution; 24 | extern NSString *const kGAIViewportSize; 25 | extern NSString *const kGAIEncoding; 26 | extern NSString *const kGAIScreenColors; 27 | extern NSString *const kGAILanguage; 28 | extern NSString *const kGAIJavaEnabled; 29 | extern NSString *const kGAIFlashVersion; 30 | extern NSString *const kGAINonInteraction; 31 | extern NSString *const kGAIReferrer; 32 | extern NSString *const kGAILocation; 33 | extern NSString *const kGAIHostname; 34 | extern NSString *const kGAIPage; 35 | extern NSString *const kGAIDescription; // synonym for kGAIScreenName 36 | extern NSString *const kGAIScreenName; // synonym for kGAIDescription 37 | extern NSString *const kGAITitle; 38 | extern NSString *const kGAIAdMobHitId; 39 | extern NSString *const kGAIAppName; 40 | extern NSString *const kGAIAppVersion; 41 | extern NSString *const kGAIAppId; 42 | extern NSString *const kGAIAppInstallerId; 43 | extern NSString *const kGAIUserId; 44 | 45 | extern NSString *const kGAIEventCategory; 46 | extern NSString *const kGAIEventAction; 47 | extern NSString *const kGAIEventLabel; 48 | extern NSString *const kGAIEventValue; 49 | 50 | extern NSString *const kGAISocialNetwork; 51 | extern NSString *const kGAISocialAction; 52 | extern NSString *const kGAISocialTarget; 53 | 54 | extern NSString *const kGAITransactionId; 55 | extern NSString *const kGAITransactionAffiliation; 56 | extern NSString *const kGAITransactionRevenue; 57 | extern NSString *const kGAITransactionShipping; 58 | extern NSString *const kGAITransactionTax; 59 | extern NSString *const kGAICurrencyCode; 60 | 61 | extern NSString *const kGAIItemPrice; 62 | extern NSString *const kGAIItemQuantity; 63 | extern NSString *const kGAIItemSku; 64 | extern NSString *const kGAIItemName; 65 | extern NSString *const kGAIItemCategory; 66 | 67 | extern NSString *const kGAICampaignSource; 68 | extern NSString *const kGAICampaignMedium; 69 | extern NSString *const kGAICampaignName; 70 | extern NSString *const kGAICampaignKeyword; 71 | extern NSString *const kGAICampaignContent; 72 | extern NSString *const kGAICampaignId; 73 | extern NSString *const kGAICampaignAdNetworkClickId; 74 | extern NSString *const kGAICampaignAdNetworkId; 75 | 76 | extern NSString *const kGAITimingCategory; 77 | extern NSString *const kGAITimingVar; 78 | extern NSString *const kGAITimingValue; 79 | extern NSString *const kGAITimingLabel; 80 | 81 | extern NSString *const kGAIExDescription; 82 | extern NSString *const kGAIExFatal; 83 | 84 | extern NSString *const kGAISampleRate; 85 | 86 | extern NSString *const kGAIIdfa; 87 | extern NSString *const kGAIAdTargetingEnabled; 88 | 89 | // hit types 90 | extern NSString *const kGAIAppView DEPRECATED_MSG_ATTRIBUTE("Use kGAIScreenView instead."); 91 | extern NSString *const kGAIScreenView; 92 | extern NSString *const kGAIEvent; 93 | extern NSString *const kGAISocial; 94 | extern NSString *const kGAITransaction; 95 | extern NSString *const kGAIItem; 96 | extern NSString *const kGAIException; 97 | extern NSString *const kGAITiming; 98 | 99 | /*! 100 | This class provides several fields and methods useful as wire format parameter 101 | names. The methods are used for wire format parameter names that are indexed. 102 | */ 103 | 104 | @interface GAIFields : NSObject 105 | 106 | /*! 107 | Generates the correct parameter name for a content group with an index. 108 | 109 | @param index the index of the content group. 110 | 111 | @return an NSString representing the content group parameter for the index. 112 | */ 113 | + (NSString *)contentGroupForIndex:(NSUInteger)index; 114 | 115 | /*! 116 | Generates the correct parameter name for a custon dimension with an index. 117 | 118 | @param index the index of the custom dimension. 119 | 120 | @return an NSString representing the custom dimension parameter for the index. 121 | */ 122 | + (NSString *)customDimensionForIndex:(NSUInteger)index; 123 | 124 | /*! 125 | Generates the correct parameter name for a custom metric with an index. 126 | 127 | @param index the index of the custom metric. 128 | 129 | @return an NSString representing the custom metric parameter for the index. 130 | */ 131 | + (NSString *)customMetricForIndex:(NSUInteger)index; 132 | 133 | @end 134 | -------------------------------------------------------------------------------- /ios/GAILogger.h: -------------------------------------------------------------------------------- 1 | /*! 2 | @header GAILogger.h 3 | @abstract Google Analytics iOS SDK Source 4 | @copyright Copyright 2011 Google Inc. All rights reserved. 5 | */ 6 | 7 | #import 8 | 9 | typedef NS_ENUM(NSUInteger, GAILogLevel) { 10 | kGAILogLevelNone = 0, 11 | kGAILogLevelError = 1, 12 | kGAILogLevelWarning = 2, 13 | kGAILogLevelInfo = 3, 14 | kGAILogLevelVerbose = 4 15 | }; 16 | 17 | /*! 18 | Protocol to be used for logging debug and informational messages from the SDK. 19 | Implementations of this protocol can be provided to the |GAI| class, 20 | to be used as the logger by the SDK. See the |logger| property in GAI.h. 21 | */ 22 | @protocol GAILogger 23 | @required 24 | 25 | /*! 26 | Only messages of |logLevel| and below are logged. 27 | */ 28 | @property (nonatomic, assign) GAILogLevel logLevel; 29 | 30 | /*! 31 | Logs message with log level |kGAILogLevelVerbose|. 32 | */ 33 | - (void)verbose:(NSString *)message; 34 | 35 | /*! 36 | Logs message with log level |kGAILogLevelInfo|. 37 | */ 38 | - (void)info:(NSString *)message; 39 | 40 | /*! 41 | Logs message with log level |kGAILogLevelWarning|. 42 | */ 43 | - (void)warning:(NSString *)message; 44 | 45 | /*! 46 | Logs message with log level |kGAILogLevelError|. 47 | */ 48 | - (void)error:(NSString *)message; 49 | @end 50 | -------------------------------------------------------------------------------- /ios/GAITrackedViewController.h: -------------------------------------------------------------------------------- 1 | /*! 2 | @header GAITrackedViewController.h 3 | @abstract Google Analytics for iOS Tracked View Controller Header 4 | @copyright Copyright 2012 Google Inc. All rights reserved. 5 | */ 6 | 7 | #import 8 | #import 9 | 10 | @protocol GAITracker; 11 | 12 | /*! 13 | Extends UIViewController to generate Google Analytics screenview calls 14 | whenever the view appears; this is done by overriding the `viewDidAppear:` 15 | method. The screen name must be set for any tracking calls to be made. 16 | 17 | By default, this will use [GAI defaultTracker] for tracking calls, but one can 18 | override this by setting the tracker property. 19 | */ 20 | @interface GAITrackedViewController : UIViewController 21 | 22 | /*! 23 | The tracker on which view tracking calls are be made, or `nil`, in which case 24 | [GAI defaultTracker] will be used. 25 | */ 26 | @property(nonatomic, assign) id tracker; 27 | /*! 28 | The screen name, for purposes of Google Analytics tracking. If this is `nil`, 29 | no tracking calls will be made. 30 | */ 31 | @property(nonatomic, copy) NSString *screenName; 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /ios/GAITracker.h: -------------------------------------------------------------------------------- 1 | /*! 2 | @header GAITracker.h 3 | @abstract Google Analytics iOS SDK Tracker Header 4 | @copyright Copyright 2013 Google Inc. All rights reserved. 5 | */ 6 | 7 | #import 8 | 9 | /*! 10 | Google Analytics tracking interface. Obtain instances of this interface from 11 | [GAI trackerWithTrackingId:] to track screens, events, transactions, timing, 12 | and exceptions. The implementation of this interface is thread-safe, and no 13 | calls are expected to block or take a long time. All network and disk activity 14 | will take place in the background. 15 | */ 16 | @protocol GAITracker 17 | 18 | /*! 19 | Name of this tracker. 20 | */ 21 | @property(nonatomic, readonly) NSString *name; 22 | 23 | /*! 24 | Allow collection of IDFA and related fields if set to true. Default is false. 25 | */ 26 | @property(nonatomic) BOOL allowIDFACollection; 27 | 28 | /*! 29 | Set a tracking parameter. 30 | 31 | @param parameterName The parameter name. 32 | 33 | @param value The value to set for the parameter. If this is nil, the 34 | value for the parameter will be cleared. 35 | */ 36 | - (void)set:(NSString *)parameterName 37 | value:(NSString *)value; 38 | 39 | /*! 40 | Get a tracking parameter. 41 | 42 | @param parameterName The parameter name. 43 | 44 | @returns The parameter value, or nil if no value for the given parameter is 45 | set. 46 | */ 47 | - (NSString *)get:(NSString *)parameterName; 48 | 49 | /*! 50 | Queue tracking information with the given parameter values. 51 | 52 | @param parameters A map from parameter names to parameter values which will be 53 | set just for this piece of tracking information, or nil for none. 54 | */ 55 | - (void)send:(NSDictionary *)parameters; 56 | 57 | @end 58 | -------------------------------------------------------------------------------- /ios/GoogleAnalyticsPlugin.h: -------------------------------------------------------------------------------- 1 | /* 2 | Licensed to the Apache Software Foundation (ASF) under one 3 | or more contributor license agreements. See the NOTICE file 4 | distributed with this work for additional information 5 | regarding copyright ownership. The ASF licenses this file 6 | to you under the Apache License, Version 2.0 (the 7 | "License"); you may not use this file except in compliance 8 | with the License. You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, 13 | software distributed under the License is distributed on an 14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | KIND, either express or implied. See the License for the 16 | specific language governing permissions and limitations 17 | under the License. 18 | */ 19 | 20 | #import 21 | #import 22 | #import "GAI.h" 23 | 24 | @interface GoogleAnalyticsPlugin : CDVPlugin { 25 | NSMutableArray *trackers; 26 | } 27 | 28 | - (void) setTrackingId: (CDVInvokedUrlCommand*)command; 29 | - (void) setMultipleTrackingIds: (CDVInvokedUrlCommand*)command; 30 | - (void) dispatchHits: (CDVInvokedUrlCommand*)command; 31 | - (void) setDispatchInterval: (CDVInvokedUrlCommand*)command; 32 | - (void) setLogLevel: (CDVInvokedUrlCommand*)command; 33 | - (void) get: (CDVInvokedUrlCommand*)command; 34 | - (void) set: (CDVInvokedUrlCommand*)command; 35 | - (void) send: (CDVInvokedUrlCommand*)command; 36 | - (void) close: (CDVInvokedUrlCommand*)command; 37 | - (void) getAppOptOut: (CDVInvokedUrlCommand*)command; 38 | - (void) setAppOptOut: (CDVInvokedUrlCommand*)command; 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /ios/GoogleAnalyticsPlugin.m: -------------------------------------------------------------------------------- 1 | /* 2 | Licensed to the Apache Software Foundation (ASF) under one 3 | or more contributor license agreements. See the NOTICE file 4 | distributed with this work for additional information 5 | regarding copyright ownership. The ASF licenses this file 6 | to you under the Apache License, Version 2.0 (the 7 | "License"); you may not use this file except in compliance 8 | with the License. You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, 13 | software distributed under the License is distributed on an 14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | KIND, either express or implied. See the License for the 16 | specific language governing permissions and limitations 17 | under the License. 18 | */ 19 | 20 | #import "GoogleAnalyticsPlugin.h" 21 | #import "GAI.h" 22 | #import "GAIDictionaryBuilder.h" 23 | #import "GAIFields.h" 24 | 25 | @interface GoogleAnalyticsPlugin() 26 | 27 | - (void) _releaseTrackers; 28 | - (void) _setTrackingIds: (CDVInvokedUrlCommand*)command; 29 | 30 | @end 31 | 32 | @implementation GoogleAnalyticsPlugin 33 | 34 | - (void) _releaseTrackers 35 | { 36 | if (trackers) { 37 | for (NSUInteger i = 0; i < [trackers count]; i++) { 38 | [[GAI sharedInstance] removeTrackerByName:[[trackers objectAtIndex:i] name]]; 39 | } 40 | [trackers removeAllObjects]; 41 | } 42 | } 43 | 44 | - (void) _setTrackingIds: (CDVInvokedUrlCommand*)command 45 | { 46 | [GAI sharedInstance].trackUncaughtExceptions = YES; 47 | 48 | [self _releaseTrackers]; 49 | 50 | if (!trackers) { 51 | trackers = [[NSMutableArray alloc] initWithCapacity:[command.arguments count]]; 52 | } 53 | 54 | for (NSUInteger i = 0; i < [command.arguments count]; i++) { 55 | id tracker = [[GAI sharedInstance] trackerWithTrackingId:[command.arguments objectAtIndex:i]]; 56 | [trackers addObject:tracker]; 57 | } 58 | } 59 | 60 | - (void) setTrackingId: (CDVInvokedUrlCommand*)command 61 | { 62 | CDVPluginResult* result = nil; 63 | 64 | [self _setTrackingIds:command]; 65 | 66 | result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; 67 | 68 | [self.commandDelegate sendPluginResult:result callbackId:[command callbackId]]; 69 | } 70 | 71 | - (void) setMultipleTrackingIds: (CDVInvokedUrlCommand*)command 72 | { 73 | CDVPluginResult* result = nil; 74 | 75 | [self _setTrackingIds:command]; 76 | 77 | result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; 78 | 79 | [self.commandDelegate sendPluginResult:result callbackId:[command callbackId]]; 80 | } 81 | 82 | - (void) dispatchHits: (CDVInvokedUrlCommand*)command 83 | { 84 | CDVPluginResult* result = nil; 85 | 86 | [[GAI sharedInstance] dispatch]; 87 | result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; 88 | 89 | [self.commandDelegate sendPluginResult:result callbackId:[command callbackId]]; 90 | } 91 | 92 | - (void) setDispatchInterval: (CDVInvokedUrlCommand*)command 93 | { 94 | CDVPluginResult* result = nil; 95 | NSTimeInterval dispatchInterval = [[command.arguments objectAtIndex:0] unsignedLongValue]; 96 | 97 | [GAI sharedInstance].dispatchInterval = dispatchInterval; 98 | result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; 99 | 100 | [self.commandDelegate sendPluginResult:result callbackId:[command callbackId]]; 101 | } 102 | 103 | - (void) setLogLevel: (CDVInvokedUrlCommand*)command 104 | { 105 | CDVPluginResult* result = nil; 106 | 107 | GAILogLevel logLevel = (GAILogLevel)[command.arguments objectAtIndex:0]; 108 | 109 | [[[GAI sharedInstance] logger] setLogLevel:logLevel]; 110 | 111 | result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; 112 | 113 | [self.commandDelegate sendPluginResult:result callbackId:[command callbackId]]; 114 | } 115 | 116 | - (void) get: (CDVInvokedUrlCommand*)command 117 | { 118 | CDVPluginResult* result = nil; 119 | 120 | @try { 121 | NSString* key = [command.arguments objectAtIndex:0]; 122 | 123 | if (!trackers || ![trackers count]) { 124 | result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"tracker(s) not initialized"]; 125 | } else if ([trackers count] == 1) { 126 | id tracker = [trackers objectAtIndex:0]; 127 | result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:[tracker get:key]]; 128 | } else { 129 | /* 130 | * Returns an array of tracker id and value combinations, e.g., 131 | * [{ "tid1" : "param_value1" }, { "tid2" : "param_value2" }] 132 | */ 133 | NSMutableArray *array = [NSMutableArray arrayWithCapacity:[trackers count]]; 134 | for (NSUInteger i = 0; i < [trackers count]; i++) { 135 | id tracker = [trackers objectAtIndex:i]; 136 | NSString *tid = [tracker get:@"&tid"]; 137 | NSString *value = [tracker get:key]; 138 | NSMutableDictionary *dict = [[NSMutableDictionary alloc]init]; 139 | [dict setValue:value == nil ? [NSNull null] : value forKey:tid]; 140 | [array addObject:dict]; 141 | } 142 | 143 | NSError *err = nil; 144 | NSData *jsonData = [NSJSONSerialization dataWithJSONObject:array options:0 error:&err]; 145 | if (!jsonData) { 146 | // something went wrong with dict - json serialization 147 | result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:[err localizedDescription]]; 148 | } else { 149 | NSString *serialized = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; 150 | result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:serialized]; 151 | } 152 | } 153 | } @catch (NSException *e) { 154 | result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:[e reason]]; 155 | } 156 | 157 | [self.commandDelegate sendPluginResult:result callbackId:[command callbackId]]; 158 | } 159 | 160 | - (void) set: (CDVInvokedUrlCommand*)command 161 | { 162 | CDVPluginResult* result = nil; 163 | NSString* key = [command.arguments objectAtIndex:0]; 164 | NSString* value = [command.arguments objectAtIndex:1]; 165 | 166 | if (!trackers || ![trackers count]) { 167 | result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"tracker(s) not initialized"]; 168 | } else { 169 | for (NSUInteger i = 0; i < [trackers count]; i++) { 170 | [[trackers objectAtIndex:i] set:key value:value]; 171 | } 172 | result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; 173 | } 174 | 175 | [self.commandDelegate sendPluginResult:result callbackId:[command callbackId]]; 176 | } 177 | 178 | - (void) send: (CDVInvokedUrlCommand*)command 179 | { 180 | CDVPluginResult* result = nil; 181 | NSDictionary* params = [command.arguments objectAtIndex:0]; 182 | 183 | if (!trackers || ![trackers count]) { 184 | result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"tracker(s) not initialized"]; 185 | } else { 186 | for (NSUInteger i = 0; i < [trackers count]; i++) { 187 | [[trackers objectAtIndex:i] send:params]; 188 | } 189 | result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; 190 | } 191 | 192 | [self.commandDelegate sendPluginResult:result callbackId:[command callbackId]]; 193 | } 194 | 195 | - (void) close: (CDVInvokedUrlCommand*)command 196 | { 197 | CDVPluginResult* result = nil; 198 | 199 | if (!trackers || ![trackers count]) { 200 | result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"tracker(s) not initialized"]; 201 | } else { 202 | [self _releaseTrackers]; 203 | result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; 204 | } 205 | 206 | [self.commandDelegate sendPluginResult:result callbackId:[command callbackId]]; 207 | } 208 | 209 | - (void) getAppOptOut: (CDVInvokedUrlCommand*)command 210 | { 211 | CDVPluginResult* result = nil; 212 | 213 | if ([GAI sharedInstance].optOut) { 214 | result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsBool:(true)]; 215 | } else { 216 | result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsBool:(false)]; 217 | } 218 | 219 | [self.commandDelegate sendPluginResult:result callbackId:[command callbackId]]; 220 | } 221 | 222 | - (void) setAppOptOut: (CDVInvokedUrlCommand*)command 223 | { 224 | CDVPluginResult* result = nil; 225 | BOOL enabled = [[command.arguments objectAtIndex:0] boolValue]; 226 | 227 | if (enabled) { 228 | [[GAI sharedInstance] setOptOut:YES]; 229 | } else { 230 | [[GAI sharedInstance] setOptOut:NO]; 231 | } 232 | result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; 233 | 234 | [self.commandDelegate sendPluginResult:result callbackId:[command callbackId]]; 235 | } 236 | 237 | @end 238 | -------------------------------------------------------------------------------- /ios/libGoogleAnalyticsServices.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmackay/google-analytics-plugin/dcc61382085cfd141e813e16c0a82f58636ecdc4/ios/libGoogleAnalyticsServices.a -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "com.cmackay.plugins.googleanalytics", 3 | "version": "1.0.4", 4 | "description": "Plugin for Google Analytics Native SDKs (Android, iOS)", 5 | "cordova": { 6 | "id": "com.cmackay.plugins.googleanalytics", 7 | "platforms": [ 8 | "ios", 9 | "android" 10 | ] 11 | }, 12 | "scripts": { 13 | "docs": "./node_modules/.bin/rimraf README.md && cat prefix.md > README.md && ./node_modules/.bin/jsdoc2md ./www/*.js >> README.md" 14 | }, 15 | "repository": { 16 | "type": "git", 17 | "url": "git+https://github.com/cmackay/google-analytics-plugin.git" 18 | }, 19 | "keywords": [ 20 | "cordova", 21 | "analytics", 22 | "ecosystem:cordova", 23 | "cordova-ios", 24 | "cordova-android" 25 | ], 26 | "engines": [ 27 | { 28 | "name": "cordova", 29 | "version": ">=3.0.0" 30 | } 31 | ], 32 | "author": "Craig MacKay", 33 | "license": "Apache 2.0", 34 | "bugs": { 35 | "url": "https://github.com/cmackay/google-analytics-plugin/issues" 36 | }, 37 | "homepage": "https://github.com/cmackay/google-analytics-plugin#readme", 38 | "devDependencies": { 39 | "jsdoc-to-markdown": "^1.1.1", 40 | "rimraf": "^2.4.3" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /plugin.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | GoogleAnalytics 12 | Plugin for Google Analytics Native SDKs (Android, iOS) 13 | Craig MacKay 14 | Apache 2.0 15 | cordova,analytics 16 | https://github.com/cmackay/google-analytics-plugin.git 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | -keep class * extends java.util.ListResourceBundle { 89 | protected Object[][] getContents(); 90 | } 91 | -keep public class com.google.android.gms.common.internal.safeparcel.SafeParcelable { 92 | public static final *** NULL; 93 | } 94 | -keepnames @com.google.android.gms.common.annotation.KeepName class * 95 | -keepclassmembernames class * { 96 | @com.google.android.gms.common.annotation.KeepName *; 97 | } 98 | -keepnames class * implements android.os.Parcelable { 99 | public static final ** CREATOR; 100 | } 101 | 102 | 103 | 104 | 105 | -------------------------------------------------------------------------------- /prefix.md: -------------------------------------------------------------------------------- 1 | google-analytics-plugin 2 | ======================= 3 | 4 | Provides Apache Cordova/Phonegap support for Google Analytics using the native sdks for Android & iOS. 5 | 6 | * Android Native SDK v4 (using Google Play Services SDK) 7 | * iOS Native SDK v3 8 | 9 | This plugin provides support for some of the more specific analytics functions (screen, event & exception tracking, custom metrics & dimensions) and also the more generic set and send functions which can be used to implement all of the Google Analytics collection features. 10 | 11 | As an example tracking a screen could be implemented using either the sendAppView function or the send function: 12 | 13 | ```js 14 | 15 | var analytics = navigator.analytics; 16 | 17 | // set the tracking id 18 | analytics.setTrackingId('UA-XXXXX-X'); 19 | // ...or set multiple tracking ids 20 | analytics.setMultipleTrackingIds(['UA-XXXXX-1', 'UA-XXXXX-2']); 21 | 22 | analytics.sendAppView('home', successCallback, errorCallback); 23 | 24 | // or the same could be done using the send function 25 | 26 | var Fields = analytics.Fields, 27 | HitTypes = analytics.HitTypes, 28 | LogLevel = analytics.LogLevel, 29 | params = {}; 30 | 31 | params[Fields.HIT_TYPE] = HitTypes.APP_VIEW; 32 | params[Fields.SCREEN_NAME] = 'home'; 33 | 34 | analytics.setLogLevel(LogLevel.INFO); 35 | 36 | analytics.send(params, successCallback, errorCallback); 37 | 38 | ``` 39 | 40 | The send & set functions provide maximum flexibility and allow you to utilize all of the Google Analytics collection calls. Some helper functions are also provided to support some of the more common analytic functions. 41 | 42 | For more information about measurement protocol refer to the following page: 43 | 44 | [Measurement Protocol Developer Guide](https://developers.google.com/analytics/devguides/collection/protocol/v1/devguide) 45 | 46 | ## Installation 47 | ``` 48 | cordova plugin add com.cmackay.plugins.googleanalytics 49 | ``` 50 | 51 | To use a specific version of Google's `play-services-analytics` library just specify it with the `ANALYTICS_VERSION` variable. 52 | 53 | ``` 54 | cordova plugin add com.cmackay.plugins.googleanalytics --variable ANALYTICS_VERSION='11.0.1' 55 | ``` 56 | 57 | ## API 58 | -------------------------------------------------------------------------------- /www/analytics.js: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Licensed to the Apache Software Foundation (ASF) under one 4 | * or more contributor license agreements. See the NOTICE file 5 | * distributed with this work for additional information 6 | * regarding copyright ownership. The ASF licenses this file 7 | * to you under the Apache License, Version 2.0 (the 8 | *: 'License',); you may not use this file except in compliance 9 | * with the License. You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, 14 | * software distributed under the License is distributed on an 15 | *: 'AS IS', BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | * KIND, either express or implied. See the License for the 17 | * specific language governing permissions and limitations 18 | * under the License. 19 | */ 20 | 21 | var argscheck = require('cordova/argscheck'), 22 | utils = require('cordova/utils'), 23 | exec = require('cordova/exec'), 24 | platform = require('cordova/platform'); 25 | 26 | var Fields = { 27 | ANDROID_APP_UID: 'AppUID', 28 | ANONYMIZE_IP: '&aip', 29 | APP_ID: '&aid', 30 | APP_INSTALLER_ID: '&aiid', 31 | APP_NAME: '&an', 32 | APP_VERSION: '&av', 33 | CAMPAIGN_CONTENT: '&cc', 34 | CAMPAIGN_ID: '&ci', 35 | CAMPAIGN_KEYWORD: '&ck', 36 | CAMPAIGN_MEDIUM: '&cm', 37 | CAMPAIGN_NAME: '&cn', 38 | CAMPAIGN_SOURCE: '&cs', 39 | CLIENT_ID: '&cid', 40 | CURRENCY_CODE: '&cu', 41 | DESCRIPTION: '&cd', 42 | ENCODING: '&de', 43 | EVENT_ACTION: '&ea', 44 | EVENT_CATEGORY: '&ec', 45 | EVENT_LABEL: '&el', 46 | EVENT_VALUE: '&ev', 47 | EX_DESCRIPTION: '&exd', 48 | EX_FATAL: '&exf', 49 | FLASH_VERSION: '&fl', 50 | HIT_TYPE: '&t', 51 | HOSTNAME: '&dh', 52 | ITEM_CATEGORY: '&iv', 53 | ITEM_NAME: '&in', 54 | ITEM_PRICE: '&ip', 55 | ITEM_QUANTITY: '&iq', 56 | ITEM_SKU: '&ic', 57 | JAVA_ENABLED: '&je', 58 | LANGUAGE: '&ul', 59 | LOCATION: '&dl', 60 | NON_INTERACTION: '&ni', 61 | PAGE: '&dp', 62 | REFERRER: '&dr', 63 | SAMPLE_RATE: '&sf', 64 | SCREEN_COLORS: '&sd', 65 | SCREEN_NAME: '&cd', 66 | SCREEN_RESOLUTION: '&sr', 67 | SESSION_CONTROL: '&sc', 68 | SOCIAL_ACTION: '&sa', 69 | SOCIAL_NETWORK: '&sn', 70 | SOCIAL_TARGET: '&st', 71 | TIMING_CATEGORY: '&utc', 72 | TIMING_LABEL: '&utl', 73 | TIMING_VALUE: '&utt', 74 | TIMING_VAR: '&utv', 75 | TITLE: '&dt', 76 | TRACKING_ID: '&tid', 77 | TRANSACTION_AFFILIATION: '&ta', 78 | TRANSACTION_ID: '&ti', 79 | TRANSACTION_REVENUE: '&tr', 80 | TRANSACTION_SHIPPING: '&ts', 81 | TRANSACTION_TAX: '&tt', 82 | USE_SECURE: 'useSecure', 83 | USER_ID: '&uid', 84 | VIEWPORT_SIZE: '&vp' 85 | }; 86 | 87 | var HitTypes = { 88 | APP_VIEW: 'appview', 89 | EVENT: 'event', 90 | EXCEPTION: 'exception', 91 | ITEM: 'item', 92 | SOCIAL: 'social', 93 | TIMING: 'timing', 94 | TRANSACTION: 'transaction' 95 | }; 96 | 97 | var LogLevel = { 98 | VERBOSE: 0, 99 | INFO: 1, 100 | WARNING: 2, 101 | ERROR: 3 102 | }; 103 | 104 | var logLevelCount = 0, key; 105 | for (key in LogLevel) { 106 | if (LogLevel.hasOwnProperty(key)) { 107 | logLevelCount++; 108 | } 109 | } 110 | 111 | /** 112 | * @module 113 | */ 114 | module.exports = { 115 | 116 | /** 117 | * GA Field Types 118 | */ 119 | Fields: Fields, 120 | 121 | /** 122 | * GA Hit Types 123 | */ 124 | HitTypes: HitTypes, 125 | 126 | /** 127 | * Log Levels 128 | */ 129 | LogLevel: LogLevel, 130 | 131 | /** 132 | * Sets the tracking id 133 | * 134 | * @param {string} trackingId - the trackingId 135 | * @param {function} [success] - the success callback 136 | * @param {function} [error] - the error callback 137 | */ 138 | setTrackingId: function (trackingId, success, error) { 139 | argscheck.checkArgs('sFF', 'analytics.setTrackingId', arguments); 140 | exec(success, error, 'GoogleAnalytics', 'setTrackingId', [trackingId]); 141 | }, 142 | 143 | /** 144 | * Sets multiple tracking ids. 145 | * This will override any tracking id previously set. 146 | * 147 | * @param {array} trackingIds - array of trackingId parameters 148 | * @param {function} [success] - the success callback 149 | * @param {function} [error] - the error callback 150 | */ 151 | setMultipleTrackingIds: function (trackingIds, success, error) { 152 | argscheck.checkArgs('aFF', 'analytics.setTrackingId', arguments); 153 | exec(success, error, 'GoogleAnalytics', 'setTrackingId', trackingIds); 154 | }, 155 | 156 | /** 157 | * Sets the dispatch Interval 158 | * 159 | * @param {number} seconds - the interval in seconds 160 | * @param {function} [success] - the success callback 161 | * @param {function} [error] - the error callback 162 | */ 163 | setDispatchInterval: function (seconds, success, error) { 164 | argscheck.checkArgs('nFF', 'analytics.setDispatchInterval', arguments); 165 | exec(success, error, 'GoogleAnalytics', 'setDispatchInterval', [seconds]); 166 | }, 167 | 168 | /** 169 | * Get app-level opt out flag that will disable Google Analytics 170 | * 171 | * @param {function} [success] - the success callback (value is passed to callback) 172 | */ 173 | getAppOptOut: function (success) { 174 | argscheck.checkArgs('F', 'analytics.getAppOptOut', arguments); 175 | exec(success, null, 'GoogleAnalytics', 'getAppOptOut', []); 176 | }, 177 | 178 | /** 179 | * Set app-level opt out flag that will disable Google Analytics 180 | * 181 | * @param {boolean} [enabled=true] - true for opt out or false to opt in 182 | * @param {function} [success] - the success callback 183 | * @param {function} [error] - the error callback 184 | */ 185 | setAppOptOut: function (enabled, success, error) { 186 | argscheck.checkArgs('*FF', 'analytics.setAppOptOut', arguments); 187 | exec(success, error, 'GoogleAnalytics', 'setAppOptOut', [enabled]); 188 | }, 189 | 190 | /** 191 | * Sets the log level 192 | * 193 | * @param {number} logLevel - the log level (refer to LogLevel for values) 194 | * @param {function} [success] - the success callback 195 | * @param {function} [error] - the error callback 196 | */ 197 | setLogLevel: function (logLevel, success, error) { 198 | argscheck.checkArgs('nFF', 'analytics.setLogLevel', arguments); 199 | if (platform.id === 'ios') { 200 | // the log levels for android are 0,1,2,3 and for ios are 4,3,2,1 201 | logLevel = logLevelCount - logLevel; 202 | } 203 | exec(success, error, 'GoogleAnalytics', 'setLogLevel', [logLevel]); 204 | }, 205 | 206 | enableAdvertisingIdCollection: function (success, error) { 207 | argscheck.checkArgs('FF', 'analytics.enableAdvertisingIdCollection', arguments); 208 | exec(success, error, 'GoogleAnalytics', 'setIDFAEnabled', []); 209 | }, 210 | 211 | /** 212 | * Manually dispatches hits 213 | * 214 | * @param {function} [success] - the success callback 215 | * @param {function} [error] - the error callback 216 | */ 217 | dispatchHits: function (success, error) { 218 | argscheck.checkArgs('FF', 'analytics.dispatchHits', arguments); 219 | exec(success, error, 'GoogleAnalytics', 'dispatchHits', []); 220 | }, 221 | 222 | /** 223 | * Gets a field value. Returned as argument to success callback. 224 | * If multiple trackers are being used, this returns an array of trackerId and 225 | * field value pairs, e.g., 226 | * [{ "UA-XXXXX-1" : "field_value1" }, { "UA-XXXXX-2" : "field_value2" }] 227 | * 228 | * @param {string} key - the key 229 | * @param {function} success - the success callback 230 | * @param {function} [error] - the error callback 231 | */ 232 | get: function (key, success, error) { 233 | argscheck.checkArgs('sfF', 'analytics.get', arguments); 234 | exec(success, error, 'GoogleAnalytics', 'get', [key]); 235 | }, 236 | 237 | /** 238 | * Sets a field value 239 | * 240 | * @param {string} key - the key 241 | * @param value - the value 242 | * @param {function} [success] - the success callback 243 | * @param {function} [error] - the error callback 244 | */ 245 | set: function (key, value, success, error) { 246 | argscheck.checkArgs('s*FF', 'analytics.set', arguments); 247 | exec(success, error, 'GoogleAnalytics', 'set', [key, value]); 248 | }, 249 | 250 | /** 251 | * Generates a hit to be sent with the specified params and current field values 252 | * 253 | * @param {object} params - the params 254 | * @param {function} [success] - the success callback 255 | * @param {function} [error] - the error callback 256 | */ 257 | send: function (params, success, error) { 258 | argscheck.checkArgs('oFF', 'analytics.send', arguments); 259 | exec(success, error, 'GoogleAnalytics', 'send', [params]); 260 | }, 261 | 262 | /** 263 | * Closes the tracker 264 | * 265 | * @param {function} [success] - the success callback 266 | * @param {function} [error] - the error callback 267 | */ 268 | close: function (success, error) { 269 | argscheck.checkArgs('FF', 'analytics.close', arguments); 270 | exec(success, error, 'GoogleAnalytics', 'close', []); 271 | }, 272 | 273 | /** 274 | * Sets a custom dimension 275 | * 276 | * @param {number} id - the id 277 | * @param {string} [value] - the value 278 | * @param {function} [success] - the success callback 279 | * @param {function} [error] - the error callback 280 | */ 281 | customDimension: function (id, value, success, error) { 282 | argscheck.checkArgs('n*FF', 'analytics.customDimension', arguments); 283 | this.set('&cd' + id, value, success, error); 284 | }, 285 | 286 | /** 287 | * Sets a custom metric 288 | * 289 | * @param {number} id - the id 290 | * @param {number} [value] - the value 291 | * @param {function} [success] - the success callback 292 | * @param {function} [error] - the error callback 293 | */ 294 | customMetric: function (id, value, success, error) { 295 | argscheck.checkArgs('n*FF', 'analytics.customMetric', arguments); 296 | this.set('&cm' + id, value, success, error); 297 | }, 298 | 299 | /** 300 | * Sends an event 301 | * 302 | * @param {string} category - the category 303 | * @param {string} action - the action 304 | * @param {string} [label=''] - the label 305 | * @param {number} [value=0] - the value 306 | * @param {function} [success] - the success callback 307 | * @param {function} [error] - the error callback 308 | */ 309 | sendEvent: function (category, action, label, value, success, error) { 310 | this.sendEventWithParams(category, action, label, value, {}, success, error); 311 | }, 312 | 313 | /** 314 | * Sends an event with additional params 315 | * 316 | * @param {string} category - the category 317 | * @param {string} action - the action 318 | * @param {string} [label=''] - the label 319 | * @param {number} [value=0] - the value 320 | * @param {object} params - the params 321 | * @param {function} [success] - the success callback 322 | * @param {function} [error] - the error callback 323 | */ 324 | sendEventWithParams: function (category, action, label, value, params, success, error) { 325 | argscheck.checkArgs('ssSNoFF', 'analytics.sendEvent', arguments); 326 | if (params === undefined || params === null) { 327 | params = {}; 328 | } 329 | params[Fields.HIT_TYPE] = HitTypes.EVENT; 330 | params[Fields.EVENT_CATEGORY] = category; 331 | params[Fields.EVENT_ACTION] = action; 332 | params[Fields.EVENT_LABEL] = label || ''; 333 | params[Fields.EVENT_VALUE] = value || 0; 334 | this.send(params, success, error); 335 | }, 336 | 337 | /** 338 | * Sends a screen view 339 | * 340 | * @param {string} screenName - the screenName 341 | * @param {function} [success] - the success callback 342 | * @param {function} [error] - the error callback 343 | */ 344 | sendAppView: function (screenName, success, error) { 345 | this.sendAppViewWithParams(screenName, {}, success, error); 346 | }, 347 | 348 | /** 349 | * Sends a screen view with additional params 350 | * 351 | * @param {string} screenName - the screenName 352 | * @param {object} params - the params 353 | * @param {function} [success] - the success callback 354 | * @param {function} [error] - the error callback 355 | */ 356 | sendAppViewWithParams: function (screenName, params, success, error) { 357 | argscheck.checkArgs('soFF', 'analytics.sendAppView', arguments); 358 | if (params === undefined || params === null) { 359 | params = {}; 360 | } 361 | params[Fields.HIT_TYPE] = HitTypes.APP_VIEW; 362 | params[Fields.SCREEN_NAME] = screenName; 363 | this.send(params, success, error); 364 | }, 365 | 366 | /** 367 | * Sends a user timing 368 | * 369 | * @param {string} category - the category 370 | * @param {string} variable - the variable 371 | * @param {string} label - the label 372 | * @param {number} time - the time 373 | * @param {function} [success] - the success callback 374 | * @param {function} [error] - the error callback 375 | */ 376 | sendTiming: function (category, variable, label, time, success, error) { 377 | argscheck.checkArgs('sssnFF', 'analytics.sendException', arguments); 378 | var params = {}; 379 | params[Fields.HIT_TYPE] = HitTypes.TIMING; 380 | params[Fields.TIMING_CATEGORY] = category; 381 | params[Fields.TIMING_VAR] = variable; 382 | params[Fields.TIMING_VALUE] = time; 383 | params[Fields.TIMING_LABEL] = label; 384 | this.send(params, success, error); 385 | }, 386 | 387 | /** 388 | * Sends an exception 389 | * 390 | * @param {string} description - the exception description 391 | * @param {boolean} [fatal] - marks the exception as fatal 392 | * @param {function} [success] - the success callback 393 | * @param {function} [error] - the error callback 394 | */ 395 | sendException: function (description, fatal, success, error) { 396 | argscheck.checkArgs('s*FF', 'analytics.sendException', arguments); 397 | var params = {}; 398 | params[Fields.HIT_TYPE] = HitTypes.EXCEPTION; 399 | params[Fields.EX_DESCRIPTION] = description; 400 | params[Fields.EX_FATAL] = fatal ? 1 : 0; 401 | this.send(params, success, error); 402 | }, 403 | 404 | /** 405 | * Tracks unhandled scripts errors (window.onerror) and then calls sendException. 406 | * This function optionally can be passed an object containing a formmatter function 407 | * which takes in all the args to window.onError and should return a String with 408 | * the formatted error description to be sent to Google Analytics. Also the object 409 | * can provide a fatal property which will be passed to sendException (defaults 410 | * to true). 411 | * 412 | * @param {object} [opts] - the options { formatter: Function, fatal: Boolean } 413 | * @param {function} [success] - the success callback 414 | * @param {function} [error] - the error callback 415 | */ 416 | trackUnhandledScriptErrors: function (opts, success, error) { 417 | argscheck.checkArgs('OFF', 'analytics.trackUnhandledScriptErrors', arguments); 418 | var self = this, 419 | fatal = true, 420 | formatter; 421 | if (opts && utils.typeName(opts.formatter) === 'Function') { 422 | formatter = opts.formatter; 423 | } 424 | if (opts && utils.typeName(opts.fatal) === 'Boolean') { 425 | fatal = opts.fatal; 426 | } 427 | window.onError = function (message, file, line, col, error) { 428 | var description; 429 | try { 430 | if (formatter) { 431 | description = formatter(message, file, line, col, error); 432 | } 433 | } catch (e) { 434 | utils.alert( 435 | 'analytics.trackUnhandledScriptErrors invalid formatter. error:' + e); 436 | } finally { 437 | // if there is an error formatting or no formatter use default 438 | if (description === undefined) { 439 | description = (file || ''); 440 | if (line || col) { 441 | description += ' (' + (line || '') + (col && ',' + col) + ')'; 442 | } 443 | description += (description.length > 0 ? ':' : '') + message; 444 | } 445 | } 446 | self.sendException(description, fatal, success, error); 447 | }; 448 | } 449 | 450 | }; 451 | --------------------------------------------------------------------------------