Merge lp:~rockstar/ubuntuone-ios-music/flurry-analytics into lp:ubuntuone-ios-music

Proposed by Paul Hummer
Status: Merged
Approved by: Paul Hummer
Approved revision: 294
Merged at revision: 250
Proposed branch: lp:~rockstar/ubuntuone-ios-music/flurry-analytics
Merge into: lp:ubuntuone-ios-music
Prerequisite: lp:~rockstar/ubuntuone-ios-music/polish-list-views
Diff against target: 982 lines (+737/-3)
13 files modified
Dependencies/Flurry/Flurry.h (+611/-0)
Music/UOAppDelegate.m (+1/-0)
Music/View Controllers/AlbumViewController.m (+9/-0)
Music/View Controllers/AlbumsViewController.m (+12/-0)
Music/View Controllers/ArtistViewController.m (+9/-0)
Music/View Controllers/ArtistsViewController.m (+12/-0)
Music/View Controllers/PlayerViewController.m (+3/-0)
Music/View Controllers/PlaylistsViewController.m (+12/-0)
Music/View Controllers/SettingsAuthenticationViewController.m (+12/-0)
Music/View Controllers/SettingsViewController.m (+12/-0)
Music/View Controllers/SongsViewController.m (+12/-0)
U1Music.xcodeproj/project.pbxproj (+20/-3)
U1Music_Prefix.pch (+12/-0)
To merge this branch: bzr merge lp:~rockstar/ubuntuone-ios-music/flurry-analytics
Reviewer Review Type Date Requested Status
Roberto Alsina (community) Approve
Review via email: mp+147592@code.launchpad.net

Commit message

Add Flurry analytics

Description of the change

This branch adds Flurry analytics to the U1 Music app. I added the base analytics, and timed event logging for each of the view controllers.

To post a comment you must log in.
294. By Paul Hummer

Fix copy and paste errors

Revision history for this message
Roberto Alsina (ralsina) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added directory 'Dependencies/Flurry'
2=== added file 'Dependencies/Flurry/Flurry.h'
3--- Dependencies/Flurry/Flurry.h 1970-01-01 00:00:00 +0000
4+++ Dependencies/Flurry/Flurry.h 2013-02-11 04:20:26 +0000
5@@ -0,0 +1,611 @@
6+//
7+// Flurry.h
8+// Flurry iOS Analytics Agent
9+//
10+// Copyright 2009-2012 Flurry, Inc. All rights reserved.
11+//
12+// Methods in this header file are for use with Flurry Analytics
13+
14+#import <UIKit/UIKit.h>
15+
16+/*!
17+ * @brief Provides all available methods for defining and reporting Analytics from use
18+ * of your app.
19+ *
20+ * Set of methods that allow developers to capture detailed, aggregate information
21+ * regarding the use of their app by end users.
22+ *
23+ * @note This class provides methods necessary for correct function of FlurryAds.h.
24+ * For information on how to use Flurry's Ads SDK to
25+ * attract high-quality users and monetize your user base see <a href="http://support.flurry.com/index.php?title=Publishers">Support Center - Publishers</a>.
26+ *
27+ * @author 2009 - 2012 Flurry, Inc. All Rights Reserved.
28+ * @version 4.0.0
29+ *
30+ */
31+@interface Flurry : NSObject {
32+}
33+
34+/** @name Pre-Session Calls
35+ * Optional sdk settings that should be called before start session.
36+ */
37+//@{
38+
39+/*!
40+ * @brief Explicitly specifies the App Version that Flurry will use to group Analytics data.
41+ * @since 2.7
42+ *
43+ * This is an optional method that overrides the App Version Flurry uses for reporting. Flurry will
44+ * use the CFBundleVersion in your info.plist file when this method is not invoked.
45+ *
46+ * @note There is a maximum of 605 versions allowed for a single app. \n
47+ * This method must be called prior to invoking #startSession:.
48+ *
49+ * @param version The custom version name.
50+ */
51+
52++ (void)setAppVersion:(NSString *)version;
53+
54+/*!
55+ * @brief Retrieves the Flurry Agent Build Version.
56+ * @since 2.7
57+ *
58+ * This is an optional method that retrieves the Flurry Agent Version the app is running under.
59+ * It is most often used if reporting an unexpected behavior of the SDK to <a href="mailto:iphonesupport@flurry.com">
60+ * Flurry Support</a>
61+ *
62+ * @note This method must be called prior to invoking #startSession:. \n
63+ * FAQ for the iPhone SDK is located at <a href="http://wiki.flurry.com/index.php?title=IPhone_FAQ">
64+ * Support Center - iPhone FAQ</a>.
65+ *
66+ * @see #setDebugLogEnabled: for information on how to view debugging information on your console.
67+ *
68+ * @return The agent version of the Flurry SDK.
69+ *
70+ */
71++ (NSString *)getFlurryAgentVersion;
72+
73+/*!
74+ * @brief Displays an exception in the debug log if thrown during a Session.
75+ * @since 2.7
76+ *
77+ * This is an optional method that augments the debug logs with exceptions that occur during the session.
78+ * You must both capture exceptions to Flurry and set debug logging to enabled for this method to
79+ * display information to the console. The default setting for this method is @c NO.
80+ *
81+ * @note This method must be called prior to invoking #startSession:.
82+ *
83+ * @see #setDebugLogEnabled: for information on how to view debugging information on your console. \n
84+ * #logError:message:exception: for details on logging exceptions. \n
85+ * #logError:message:error: for details on logging errors.
86+ *
87+ * @param value @c YES to show errors in debug logs, @c NO to omit errors in debug logs.
88+ */
89++ (void)setShowErrorInLogEnabled:(BOOL)value;
90+
91+/*!
92+ * @brief Generates debug logs to console.
93+ * @since 2.7
94+ *
95+ * This is an optional method that displays debug information related to the Flurry SDK.
96+ * display information to the console. The default setting for this method is @c NO.
97+ *
98+ * @note This method must be called prior to invoking #startSession:.
99+ *
100+ * @param value @c YES to show debug logs, @c NO to omit debug logs.
101+ *
102+ */
103++ (void)setDebugLogEnabled:(BOOL)value;
104+
105+/*!
106+ * @brief Set the timeout for expiring a Flurry session.
107+ * @since 2.7
108+ *
109+ * This is an optional method that sets the time the app may be in the background before
110+ * starting a new session upon resume. The default value for the session timeout is 10
111+ * seconds in the background.
112+ *
113+ * @note This method must be called prior to invoking #startSession:.
114+ *
115+ * @param seconds The time in seconds to set the session timeout to.
116+ */
117++ (void)setSessionContinueSeconds:(int)seconds;
118+
119+/*!
120+ * @brief Send data over a secure transport.
121+ * @since 3.0
122+ *
123+ * This is an optional method that sends data over an SSL connection when enabled. The
124+ * default value is @c NO.
125+ *
126+ * @note This method must be called prior to invoking #startSession:.
127+ *
128+ * @param value @c YES to send data over secure connection.
129+ */
130++ (void)setSecureTransportEnabled:(BOOL)value;
131+
132+//@}
133+
134+/*!
135+ * @brief Start a Flurry session for the project denoted by @c apiKey.
136+ * @since 2.6
137+ *
138+ * This method serves as the entry point to Flurry Analytics collection. It must be
139+ * called in the scope of @c applicationDidFinishLaunching. The session will continue
140+ * for the period the app is in the foreground until your app is backgrounded for the
141+ * time specified in #setSessionContinueSeconds:. If the app is resumed in that period
142+ * the session will continue, otherwise a new session will begin.
143+ *
144+ * @note If testing on a simulator, please be sure to send App to background via home
145+ * button. Flurry depends on the iOS lifecycle to be complete for full reporting.
146+ *
147+ * @see #setSessionContinueSeconds: for details on setting a custom session timeout.
148+ *
149+ * @code
150+ * - (void)applicationDidFinishLaunching:(UIApplication *)application
151+ {
152+ // Optional Flurry startup methods
153+ [Flurry startSession:@"YOUR_API_KEY"];
154+ // ....
155+ }
156+ * @endcode
157+ *
158+ * @param apiKey The API key for this project.
159+ */
160+
161++ (void)startSession:(NSString *)apiKey;
162+
163+/** @name Event and Error Logging
164+ * Methods for reporting custom events and errors during the session.
165+ */
166+//@{
167+
168+/*!
169+ * @brief Records a custom event specified by @c eventName.
170+ * @since 2.8.4
171+ *
172+ * This method allows you to specify custom events within your app. As a general rule
173+ * you should capture events related to user navigation within your app, any action
174+ * around monetization, and other events as they are applicable to tracking progress
175+ * towards your business goals.
176+ *
177+ * @note You should not pass private or confidential information about your users in a
178+ * custom event. \n
179+ * Where applicable, you should make a concerted effort to use timed events with
180+ * parameters (#logEvent:withParameters:timed:) or events with parameters
181+ * (#logEvent:withParameters:). This provides valuable information around the time the user
182+ * spends within an action (e.g. - time spent on a level or viewing a page) or characteristics
183+ * of an action (e.g. - Buy Event that has a Parameter of Widget with Value Golden Sword).
184+ *
185+ * @see #logEvent:withParameters: for details on storing events with parameters. \n
186+ * #logEvent:timed: for details on storing timed events. \n
187+ * #logEvent:withParameters:timed: for details on storing timed events with parameters. \n
188+ * #endTimedEvent:withParameters: for details on stopping a timed event and (optionally) updating
189+ * parameters.
190+ *
191+ * @code
192+ * - (void)interestingAppAction
193+ {
194+ [Flurry logEvent:@"Interesting_Action"];
195+ // Perform interesting action
196+ }
197+ * @endcode
198+ *
199+ * @param eventName Name of the event. For maximum effectiveness, we recommend using a naming scheme
200+ * that can be easily understood by non-technical people in your business domain.
201+ */
202++ (void)logEvent:(NSString *)eventName;
203+
204+/*!
205+ * @brief Records a custom parameterized event specified by @c eventName with @c parameters.
206+ * @since 2.8.4
207+ *
208+ * This method overrides #logEvent to allow you to associate parameters with an event. Parameters
209+ * are extremely valuable as they allow you to store characteristics of an action. For example,
210+ * if a user purchased an item it may be helpful to know what level that user was on.
211+ * By setting this parameter you will be able to view a distribution of levels for the purcahsed
212+ * event on the <a href="http://dev.flurry.com">Flurrly Dev Portal</a>.
213+ *
214+ * @note You should not pass private or confidential information about your users in a
215+ * custom event. \n
216+ * A maximum of 10 parameter names may be associated with any event. Sending
217+ * over 10 parameter names with a single event will result in no parameters being logged
218+ * for that event. You may specify an infinite number of Parameter values. For example,
219+ * a Search Box would have 1 parameter name (e.g. - Search Box) and many values, which would
220+ * allow you to see what values users look for the most in your app. \n
221+ * Where applicable, you should make a concerted effort to use timed events with
222+ * parameters (#logEvent:withParameters:timed:). This provides valuable information
223+ * around the time the user spends within an action (e.g. - time spent on a level or
224+ * viewing a page).
225+ *
226+ * @see #logEvent:withParameters:timed: for details on storing timed events with parameters. \n
227+ * #endTimedEvent:withParameters: for details on stopping a timed event and (optionally) updating
228+ * parameters.
229+ *
230+ * @code
231+ * - (void)userPurchasedSomethingCool
232+ {
233+ NSDictionary *params =
234+ [NSDictionary dictionaryWithObjectsAndKeys:@"Cool Item", // Parameter Value
235+ @"Item Purchased", // Parameter Name
236+ nil];
237+ [Flurry logEvent:@"Something Cool Purchased" withParameters:params];
238+ // Give user cool item
239+ }
240+ * @endcode
241+ *
242+ * @param eventName Name of the event. For maximum effectiveness, we recommend using a naming scheme
243+ * that can be easily understood by non-technical people in your business domain.
244+ * @param parameters A map containing Name-Value pairs of parameters.
245+ */
246++ (void)logEvent:(NSString *)eventName withParameters:(NSDictionary *)parameters;
247+
248+/*!
249+ * @brief Records an app exception. Commonly used to catch unhandled exceptions.
250+ * @since 2.7
251+ *
252+ * This method captures an exception for reporting to Flurry. We recommend adding an uncaught
253+ * exception listener to capture any exceptions that occur during usage that is not
254+ * anticipated by your app.
255+ *
256+ * @see #logError:message:error: for details on capturing errors.
257+ *
258+ * @code
259+ * - (void) uncaughtExceptionHandler(NSException *exception)
260+ {
261+ [Flurry logError:@"Uncaught" message:@"Crash!" exception:exception];
262+ }
263+
264+ - (void)applicationDidFinishLaunching:(UIApplication *)application
265+ {
266+ NSSetUncaughtExceptionHandler(&uncaughtExceptionHandler);
267+ [Flurry startSession:@"YOUR_API_KEY"];
268+ // ....
269+ }
270+ * @endcode
271+ *
272+ * @param errorID Name of the error.
273+ * @param message The message to associate with the error.
274+ * @param exception The exception object to report.
275+ */
276++ (void)logError:(NSString *)errorID message:(NSString *)message exception:(NSException *)exception;
277+
278+/*!
279+ * @brief Records an app error.
280+ * @since 2.7
281+ *
282+ * This method captures an error for reporting to Flurry.
283+ *
284+ * @see #logError:message:exception: for details on capturing exceptions.
285+ *
286+ * @code
287+ * - (void) webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
288+ {
289+ [Flurry logError:@"WebView No Load" message:[error localizedDescription] error:error];
290+ }
291+ * @endcode
292+ *
293+ * @param errorID Name of the error.
294+ * @param message The message to associate with the error.
295+ * @param error The error object to report.
296+ */
297++ (void)logError:(NSString *)errorID message:(NSString *)message error:(NSError *)error;
298+
299+/*!
300+ * @brief Records a timed event specified by @c eventName.
301+ * @since 2.8.4
302+ *
303+ * This method overrides #logEvent to allow you to capture the length of an event. This can
304+ * be extremely valuable to understand the level of engagement with a particular action. For
305+ * example, you can capture how long a user spends on a level or reading an article.
306+ *
307+ * @note You should not pass private or confidential information about your users in a
308+ * custom event. \n
309+ * Where applicable, you should make a concerted effort to use parameters with your timed
310+ * events (#logEvent:withParameters:timed:). This provides valuable information
311+ * around the characteristics of an action (e.g. - Buy Event that has a Parameter of Widget with
312+ * Value Golden Sword).
313+ *
314+ * @see #logEvent:withParameters:timed: for details on storing timed events with parameters. \n
315+ * #endTimedEvent:withParameters: for details on stopping a timed event and (optionally) updating
316+ * parameters.
317+ *
318+ * @code
319+ * - (void)startLevel
320+ {
321+ [Flurry logEvent:@"Level Played" timed:YES];
322+ // Start user on level
323+ }
324+
325+ - (void)endLevel
326+ {
327+ [Flurry endTimedEvent:@"Level Played" withParameters:nil];
328+ // User done with level
329+ }
330+ * @endcode
331+ *
332+ * @param eventName Name of the event. For maximum effectiveness, we recommend using a naming scheme
333+ * that can be easily understood by non-technical people in your business domain.
334+ * @param timed Specifies the event will be timed.
335+ */
336++ (void)logEvent:(NSString *)eventName timed:(BOOL)timed;
337+
338+/*!
339+ * @brief Records a custom parameterized timed event specified by @c eventName with @c parameters.
340+ * @since 2.8.4
341+ *
342+ * This method overrides #logEvent to allow you to capture the length of an event with parameters.
343+ * This can be extremely valuable to understand the level of engagement with a particular action
344+ * and the characteristics associated with that action. For example, you can capture how long a user
345+ * spends on a level or reading an article. Parameters can be used to capture, for example, the
346+ * author of an article or if something was purchased while on the level.
347+ *
348+ * @note You should not pass private or confidential information about your users in a
349+ * custom event.
350+ *
351+ * @see #endTimedEvent:withParameters: for details on stopping a timed event and (optionally) updating
352+ * parameters.
353+ *
354+ * @code
355+ * - (void)startLevel
356+ {
357+ NSDictionary *params =
358+ [NSDictionary dictionaryWithObjectsAndKeys:@"100", // Parameter Value
359+ @"Current Points", // Parameter Name
360+ nil];
361+
362+ [Flurry logEvent:@"Level Played" withParameters:params timed:YES];
363+ // Start user on level
364+ }
365+
366+ - (void)endLevel
367+ {
368+ // User gained additional 100 points in Level
369+ NSDictionary *params =
370+ [NSDictionary dictionaryWithObjectsAndKeys:@"200", // Parameter Value
371+ @"Current Points", // Parameter Name
372+ nil];
373+ [Flurry endTimedEvent:@"Level Played" withParameters:params];
374+ // User done with level
375+ }
376+ * @endcode
377+ *
378+ * @param eventName Name of the event. For maximum effectiveness, we recommend using a naming scheme
379+ * that can be easily understood by non-technical people in your business domain.
380+ * @param parameters A map containing Name-Value pairs of parameters.
381+ * @param timed Specifies the event will be timed.
382+ */
383++ (void)logEvent:(NSString *)eventName withParameters:(NSDictionary *)parameters timed:(BOOL)timed;
384+
385+/*!
386+ * @brief Ends a timed event specified by @c eventName and optionally updates parameters with @c parameters.
387+ * @since 2.8.4
388+ *
389+ * This method ends an existing timed event. If parameters are provided, this will overwrite existing
390+ * parameters with the same name or create new parameters if the name does not exist in the parameter
391+ * map set by #logEvent:withParameters:timed:.
392+ *
393+ * @note You should not pass private or confidential information about your users in a
394+ * custom event. \n
395+ * If the app is backgrounded prior to ending a timed event, the Flurry SDK will automatically
396+ * end the timer on the event. \n
397+ * #endTimedEvent:withParameters: is ignored if called on a previously
398+ * terminated event.
399+ *
400+ * @see #logEvent:withParameters:timed: for details on starting a timed event with parameters.
401+ *
402+ * @code
403+ * - (void)startLevel
404+ {
405+ NSDictionary *params =
406+ [NSDictionary dictionaryWithObjectsAndKeys:@"100", // Parameter Value
407+ @"Current Points", // Parameter Name
408+ nil];
409+
410+ [Flurry logEvent:@"Level Played" withParameters:params timed:YES];
411+ // Start user on level
412+ }
413+
414+ - (void)endLevel
415+ {
416+ // User gained additional 100 points in Level
417+ NSDictionary *params =
418+ [NSDictionary dictionaryWithObjectsAndKeys:@"200", // Parameter Value
419+ @"Current Points", // Parameter Name
420+ nil];
421+ [Flurry endTimedEvent:@"Level Played" withParameters:params];
422+ // User done with level
423+ }
424+ * @endcode
425+ *
426+ * @param eventName Name of the event. For maximum effectiveness, we recommend using a naming scheme
427+ * that can be easily understood by non-technical people in your business domain.
428+ * @param parameters A map containing Name-Value pairs of parameters.
429+ */
430++ (void)endTimedEvent:(NSString *)eventName withParameters:(NSDictionary *)parameters; // non-nil parameters will update the parameters
431+
432+//@}
433+
434+
435+/** @name Page View Methods
436+ * Count page views.
437+ */
438+//@{
439+
440+/*!
441+ * @brief Automatically track page views on a @c UINavigationController or @c UITabBarController.
442+ * @since 2.7
443+ *
444+ * This method increments the page view count for a session based on traversing a UINavigationController
445+ * or UITabBarController. The page view count is only a counter for the number of transitions in your
446+ * app. It does not associate a name with the page count. To associate a name with a count of occurences
447+ * see #logEvent:.
448+ *
449+ * @note Please make sure you assign the Tab and Navigation controllers to the view controllers before
450+ * passing them to this method.
451+ *
452+ * @see #logPageView for details on explictly incrementing page view count.
453+ *
454+ * @code
455+ * -(void) trackViewsFromTabBar:(UITabBarController*) tabBar
456+ {
457+ [Flurry logAllPageViews:tabBar];
458+ }
459+ * @endcode
460+ *
461+ * @param target The navigation or tab bar controller.
462+ */
463++ (void)logAllPageViews:(id)target;
464+
465+/*!
466+ * @brief Explicitly track a page view during a session.
467+ * @since 2.7
468+ *
469+ * This method increments the page view count for a session when invoked. It does not associate a name
470+ * with the page count. To associate a name with a count of occurences see #logEvent:.
471+ *
472+ * @see #logAllPageViews for details on automatically incrementing page view count based on user
473+ * traversing navigation or tab bar controller.
474+ *
475+ * @code
476+ * -(void) trackView
477+ {
478+ [Flurry logPageView];
479+ }
480+ * @endcode
481+ *
482+ */
483++ (void)logPageView;
484+
485+//@}
486+
487+/** @name User Info
488+ * Methods to set user information.
489+ */
490+//@{
491+
492+/*!
493+ * @brief Assign a unique id for a user in your app.
494+ * @since 2.7
495+ *
496+ * @note Please be sure not to use this method to pass any private or confidential information
497+ * about the user.
498+ *
499+ * @param userID The app id for a user.
500+ */
501++ (void)setUserID:(NSString *)userID;
502+
503+/*!
504+ * @brief Set your user's age in years.
505+ * @since 2.7
506+ *
507+ * Use this method to capture the age of your user. Only use this method if you collect this
508+ * information explictly from your user (i.e. - there is no need to set a default value).
509+ *
510+ * @note The age is aggregated across all users of your app and not available on a per user
511+ * basis.
512+ *
513+ * @param age Reported age of user.
514+ *
515+ */
516++ (void)setAge:(int)age;
517+
518+/*!
519+ * @brief Set your user's gender.
520+ * @since 2.7
521+ *
522+ * Use this method to capture the gender of your user. Only use this method if you collect this
523+ * information explictly from your user (i.e. - there is no need to set a default value). Allowable
524+ * values are @c @"M" or @c @"F"
525+ *
526+ * @note The gender is aggregated across all users of your app and not available on a per user
527+ * basis.
528+ *
529+ * @param gender Reported gender of user.
530+ *
531+ */
532++ (void)setGender:(NSString *)gender; // user's gender m or f
533+
534+//@}
535+
536+/** @name Location Reporting
537+ * Methods for setting location information.
538+ */
539+//@{
540+/*!
541+ * @brief Set the location of the session.
542+ * @since 2.7
543+ *
544+ * Use information from the CLLocationManager to specify the location of the session. Flurry does not
545+ * automatically track this information or include the CLLocation framework.
546+ *
547+ * @note Only the last location entered is captured per session. \n
548+ * Regardless of accuracy specified, the Flurry SDK will only report location at city level or higher. \n
549+ * Location is aggregated across all users of your app and not available on a per user basis. \n
550+ * This information should only be captured if it is germaine to the use of your app.
551+ *
552+ * @code
553+ CLLocationManager *locationManager = [[CLLocationManager alloc] init];
554+ [locationManager startUpdatingLocation];
555+
556+ CLLocation *location = locationManager.location;
557+ [Flurry setLatitude:location.coordinate.latitude
558+ longitude:location.coordinate.longitude
559+ horizontalAccuracy:location.horizontalAccuracy
560+ verticalAccuracy:location.verticalAccuracy];
561+ * @endcode
562+ * @param latitude The latitude.
563+ * @param longitude The longitude.
564+ * @param horizontalAccuracy The radius of uncertainty for the location in meters.
565+ * @param verticalAccuracy The accuracy of the altitude value in meters.
566+ *
567+ */
568++ (void)setLatitude:(double)latitude longitude:(double)longitude horizontalAccuracy:(float)horizontalAccuracy verticalAccuracy:(float)verticalAccuracy;
569+
570+//@}
571+
572+/** @name Session Reporting Calls
573+ * Optional methods that can be called at any point to control session reporting.
574+ */
575+//@{
576+
577+/*!
578+ * @brief Set session to report when app closes.
579+ * @since 2.7
580+ *
581+ * Use this method report session data when the app is closed. The default value is @c YES.
582+ *
583+ * @note This method is rarely invoked in iOS >= 3.2 due to the updated iOS lifecycle.
584+ *
585+ * @see #setSessionReportsOnPauseEnabled:
586+ *
587+ * @param sendSessionReportsOnClose YES to send on close, NO to omit reporting on close.
588+ *
589+ */
590++ (void)setSessionReportsOnCloseEnabled:(BOOL)sendSessionReportsOnClose;
591+
592+/*!
593+ * @brief Set session to report when app is sent to the background.
594+ * @since 2.7
595+ *
596+ * Use this method report session data when the app is paused. The default value is @c NO.
597+ *
598+ * @param setSessionReportsOnPauseEnabled YES to send on pause, NO to omit reporting on pause.
599+ *
600+ */
601++ (void)setSessionReportsOnPauseEnabled:(BOOL)setSessionReportsOnPauseEnabled;
602+
603+/*!
604+ * @brief Enable custom event logging.
605+ * @since 2.7
606+ *
607+ * Use this method to allow the capture of custom events. The default value is @c YES.
608+ *
609+ * @param value YES to enable event logging, NO to stop custom logging.
610+ *
611+ */
612++ (void)setEventLoggingEnabled:(BOOL)value;
613+
614+//@}
615+
616+@end
617
618=== added file 'Dependencies/Flurry/libFlurry.a'
619Binary files Dependencies/Flurry/libFlurry.a 1970-01-01 00:00:00 +0000 and Dependencies/Flurry/libFlurry.a 2013-02-11 04:20:26 +0000 differ
620=== modified file 'Music/UOAppDelegate.m'
621--- Music/UOAppDelegate.m 2013-02-08 17:05:40 +0000
622+++ Music/UOAppDelegate.m 2013-02-11 04:20:26 +0000
623@@ -56,6 +56,7 @@
624
625 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions: (NSDictionary *)launchOptions {
626 [Crashlytics startWithAPIKey:@"0606692bafe724ed1413548f6211a8557140eade"];
627+ [Flurry startSession:@"BTQGJ5ZF8C7SMQG3GC5F"];
628
629 self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds ]];
630
631
632=== modified file 'Music/View Controllers/AlbumViewController.m'
633--- Music/View Controllers/AlbumViewController.m 2013-02-11 04:20:26 +0000
634+++ Music/View Controllers/AlbumViewController.m 2013-02-11 04:20:26 +0000
635@@ -34,10 +34,12 @@
636 @synthesize artistId = _artistId;
637
638 - (void)viewDidLoad {
639+ [super viewDidLoad];
640 [self.tableView setDataSource:self];
641 }
642
643 - (void)viewWillAppear:(BOOL)animated {
644+ [super viewWillAppear:animated];
645 [self fetchAlbum];
646
647 if ([[UOPlayer player] currentSong]) {
648@@ -69,6 +71,13 @@
649 } else {
650 [[UOWebServiceController controller] updateSongs:self];
651 }
652+
653+ [Flurry logEvent:EVENT_ALBUM_VIEW timed:YES];
654+}
655+
656+- (void)viewDidDisappear:(BOOL)animated {
657+ [super viewDidDisappear:animated];
658+ [Flurry endTimedEvent:EVENT_ALBUM_VIEW withParameters:nil];
659 }
660
661 - (void)viewDidUnload {
662
663=== modified file 'Music/View Controllers/AlbumsViewController.m'
664--- Music/View Controllers/AlbumsViewController.m 2013-02-11 04:20:26 +0000
665+++ Music/View Controllers/AlbumsViewController.m 2013-02-11 04:20:26 +0000
666@@ -50,6 +50,18 @@
667 [[UOWebServiceController controller] updateAlbums:self clearCache:YES];
668 }
669
670+#pragma mark - View controller lifecycle
671+
672+- (void)viewWillAppear:(BOOL)animated {
673+ [super viewWillAppear:animated];
674+ [Flurry logEvent:EVENT_ALBUMS_VIEW timed:YES];
675+}
676+
677+- (void)viewDidDisappear:(BOOL)animated {
678+ [super viewDidDisappear:animated];
679+ [Flurry endTimedEvent:EVENT_ALBUMS_VIEW withParameters:nil];
680+}
681+
682 #pragma mark - Storyboard methods
683
684 - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
685
686=== modified file 'Music/View Controllers/ArtistViewController.m'
687--- Music/View Controllers/ArtistViewController.m 2013-02-11 04:20:26 +0000
688+++ Music/View Controllers/ArtistViewController.m 2013-02-11 04:20:26 +0000
689@@ -35,6 +35,7 @@
690 @synthesize artistId = _artistId;
691
692 - (void)viewDidLoad {
693+ [super viewDidLoad];
694 [self.tableView setDataSource:self];
695 }
696
697@@ -63,6 +64,14 @@
698 NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"year" ascending:NO];
699 tableData = [artist.albums sortedArrayUsingDescriptors:@[sortDescriptor]];
700 [self.tableView reloadData];
701+
702+ [super viewWillAppear:animated];
703+ [Flurry logEvent:EVENT_ARTIST_VIEW timed:YES];
704+}
705+
706+- (void)viewDidDisappear:(BOOL)animated {
707+ [super viewDidDisappear:animated];
708+ [Flurry endTimedEvent:EVENT_ARTIST_VIEW withParameters:nil];
709 }
710
711 - (void)viewDidUnload {
712
713=== modified file 'Music/View Controllers/ArtistsViewController.m'
714--- Music/View Controllers/ArtistsViewController.m 2013-02-11 04:20:26 +0000
715+++ Music/View Controllers/ArtistsViewController.m 2013-02-11 04:20:26 +0000
716@@ -53,6 +53,18 @@
717 [[UOWebServiceController controller] updateArtists:self clearCache:YES];
718 }
719
720+#pragma mark - View controller lifecycle
721+
722+- (void)viewWillAppear:(BOOL)animated {
723+ [super viewWillAppear:animated];
724+ [Flurry logEvent:EVENT_ARTISTS_VIEW timed:YES];
725+}
726+
727+- (void)viewDidDisappear:(BOOL)animated {
728+ [super viewDidDisappear:animated];
729+ [Flurry endTimedEvent:EVENT_ARTISTS_VIEW withParameters:nil];
730+}
731+
732 #pragma mark - Storyboard methods
733
734 - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
735
736=== modified file 'Music/View Controllers/PlayerViewController.m'
737--- Music/View Controllers/PlayerViewController.m 2013-02-11 04:20:26 +0000
738+++ Music/View Controllers/PlayerViewController.m 2013-02-11 04:20:26 +0000
739@@ -41,6 +41,7 @@
740 [self updateCurrentSong];
741
742 heartbeat = [NSTimer scheduledTimerWithTimeInterval:0.5f target:self selector:@selector(heartbeat:) userInfo:nil repeats:YES];
743+ [Flurry logEvent:EVENT_PLAYER_VIEW timed:YES];
744 }
745
746 - (void)viewDidDisappear:(BOOL)animated {
747@@ -51,6 +52,8 @@
748
749 [heartbeat invalidate];
750 heartbeat = nil;
751+
752+ [Flurry endTimedEvent:EVENT_PLAYER_VIEW withParameters:nil];
753 }
754
755 - (void)viewDidUnload {
756
757=== modified file 'Music/View Controllers/PlaylistsViewController.m'
758--- Music/View Controllers/PlaylistsViewController.m 2013-02-11 04:20:26 +0000
759+++ Music/View Controllers/PlaylistsViewController.m 2013-02-11 04:20:26 +0000
760@@ -49,4 +49,16 @@
761 [[UOWebServiceController controller] updatePlaylists:self clearCache:YES];
762 }
763
764+#pragma mark - View controller lifecycle
765+
766+- (void)viewWillAppear:(BOOL)animated {
767+ [super viewWillAppear:animated];
768+ [Flurry logEvent:EVENT_PLAYLISTS_VIEW timed:YES];
769+}
770+
771+- (void)viewDidDisappear:(BOOL)animated {
772+ [super viewDidDisappear:animated];
773+ [Flurry endTimedEvent:EVENT_PLAYLISTS_VIEW withParameters:nil];
774+}
775+
776 @end
777
778=== modified file 'Music/View Controllers/SettingsAuthenticationViewController.m'
779--- Music/View Controllers/SettingsAuthenticationViewController.m 2013-01-26 02:37:04 +0000
780+++ Music/View Controllers/SettingsAuthenticationViewController.m 2013-02-11 04:20:26 +0000
781@@ -92,6 +92,18 @@
782 [self.spinner setHidden:YES];
783 }
784
785+#pragma mark - View controller lifecycle
786+
787+- (void)viewWillAppear:(BOOL)animated {
788+ [super viewWillAppear:animated];
789+ [Flurry logEvent:EVENT_AUTHENTICATION_VIEW timed:YES];
790+}
791+
792+- (void)viewDidDisappear:(BOOL)animated {
793+ [super viewDidDisappear:animated];
794+ [Flurry endTimedEvent:EVENT_AUTHENTICATION_VIEW withParameters:nil];
795+}
796+
797 #pragma mark - Private methods
798
799 - (void)showAlert:(NSString *)message {
800
801=== modified file 'Music/View Controllers/SettingsViewController.m'
802--- Music/View Controllers/SettingsViewController.m 2013-01-28 17:21:44 +0000
803+++ Music/View Controllers/SettingsViewController.m 2013-02-11 04:20:26 +0000
804@@ -23,6 +23,18 @@
805
806 @implementation SettingsViewController
807
808+#pragma mark - View controller lifecycle
809+
810+- (void)viewWillAppear:(BOOL)animated {
811+ [super viewWillAppear:animated];
812+ [Flurry logEvent:EVENT_SETTINGS_VIEW timed:YES];
813+}
814+
815+- (void)viewDidDisappear:(BOOL)animated {
816+ [super viewDidDisappear:animated];
817+ [Flurry endTimedEvent:EVENT_SETTINGS_VIEW withParameters:nil];
818+}
819+
820 - (void)viewDidAppear:(BOOL)animated {
821 [super viewDidAppear:animated];
822
823
824=== modified file 'Music/View Controllers/SongsViewController.m'
825--- Music/View Controllers/SongsViewController.m 2013-02-11 04:20:26 +0000
826+++ Music/View Controllers/SongsViewController.m 2013-02-11 04:20:26 +0000
827@@ -50,6 +50,18 @@
828 [[UOWebServiceController controller] updateSongs:self clearCache:YES];
829 }
830
831+#pragma mark - View controller lifecycle
832+
833+- (void)viewWillAppear:(BOOL)animated {
834+ [super viewWillAppear:animated];
835+ [Flurry logEvent:EVENT_SONGS_VIEW timed:YES];
836+}
837+
838+- (void)viewDidDisappear:(BOOL)animated {
839+ [super viewDidDisappear:animated];
840+ [Flurry endTimedEvent:EVENT_SONGS_VIEW withParameters:nil];
841+}
842+
843 #pragma mark - UIStoryboard methods
844
845 - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
846
847=== modified file 'U1Music.xcodeproj/project.pbxproj'
848--- U1Music.xcodeproj/project.pbxproj 2013-02-11 04:20:26 +0000
849+++ U1Music.xcodeproj/project.pbxproj 2013-02-11 04:20:26 +0000
850@@ -10,6 +10,7 @@
851 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; };
852 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; };
853 2892E4100DC94CBA00A64D0F /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2892E40F0DC94CBA00A64D0F /* CoreGraphics.framework */; };
854+ 5207A4C216C89B140006A4E6 /* libFlurry.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5207A4C116C89B140006A4E6 /* libFlurry.a */; };
855 520BBF2416B51F2A00307F32 /* UODownloader.m in Sources */ = {isa = PBXBuildFile; fileRef = 520BBF2316B51F2A00307F32 /* UODownloader.m */; };
856 52169C9815D95DD100ED366D /* cancel-grey.png in Resources */ = {isa = PBXBuildFile; fileRef = 52169C9415D95DD100ED366D /* cancel-grey.png */; };
857 52169C9915D95DD100ED366D /* cancel-grey@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 52169C9515D95DD100ED366D /* cancel-grey@2x.png */; };
858@@ -32,9 +33,9 @@
859 5257415416C37E1A00530CCC /* SSPullToRefreshDefaultContentView.m in Sources */ = {isa = PBXBuildFile; fileRef = 5257414F16C37E1A00530CCC /* SSPullToRefreshDefaultContentView.m */; };
860 5257415516C37E1A00530CCC /* SSPullToRefreshSimpleContentView.m in Sources */ = {isa = PBXBuildFile; fileRef = 5257415116C37E1A00530CCC /* SSPullToRefreshSimpleContentView.m */; };
861 5257415616C37E1A00530CCC /* SSPullToRefreshView.m in Sources */ = {isa = PBXBuildFile; fileRef = 5257415316C37E1A00530CCC /* SSPullToRefreshView.m */; };
862+ 5257416D16C5653100530CCC /* Crashlytics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5257416C16C5653100530CCC /* Crashlytics.framework */; };
863 5257417716C5CC5D00530CCC /* NSString+UbuntuOne.m in Sources */ = {isa = PBXBuildFile; fileRef = 5257417616C5CC5D00530CCC /* NSString+UbuntuOne.m */; };
864 5257417A16C5CDA900530CCC /* UIImageView+UbuntuOne.m in Sources */ = {isa = PBXBuildFile; fileRef = 5257417916C5CDA900530CCC /* UIImageView+UbuntuOne.m */; };
865- 5257416D16C5653100530CCC /* Crashlytics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5257416C16C5653100530CCC /* Crashlytics.framework */; };
866 5268509716AE5267001F65A6 /* libRestKit.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5268509016AE516C001F65A6 /* libRestKit.a */; };
867 526850A816AEE4E1001F65A6 /* Storyboard_iPhone.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 526850A516AEE4E1001F65A6 /* Storyboard_iPhone.storyboard */; };
868 526850A916AEE4E1001F65A6 /* UOAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 526850A716AEE4E1001F65A6 /* UOAppDelegate.m */; };
869@@ -256,6 +257,8 @@
870 1D6058910D05DD3D006BFB54 /* U1 Music.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "U1 Music.app"; sourceTree = BUILT_PRODUCTS_DIR; };
871 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
872 2892E40F0DC94CBA00A64D0F /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
873+ 5207A4C016C89B140006A4E6 /* Flurry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Flurry.h; sourceTree = "<group>"; };
874+ 5207A4C116C89B140006A4E6 /* libFlurry.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libFlurry.a; sourceTree = "<group>"; };
875 520BBF2216B51F2A00307F32 /* UODownloader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UODownloader.h; sourceTree = "<group>"; };
876 520BBF2316B51F2A00307F32 /* UODownloader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UODownloader.m; sourceTree = "<group>"; };
877 52169C9415D95DD100ED366D /* cancel-grey.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "cancel-grey.png"; sourceTree = "<group>"; };
878@@ -287,11 +290,11 @@
879 5257415116C37E1A00530CCC /* SSPullToRefreshSimpleContentView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SSPullToRefreshSimpleContentView.m; sourceTree = "<group>"; };
880 5257415216C37E1A00530CCC /* SSPullToRefreshView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SSPullToRefreshView.h; sourceTree = "<group>"; };
881 5257415316C37E1A00530CCC /* SSPullToRefreshView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SSPullToRefreshView.m; sourceTree = "<group>"; };
882+ 5257416C16C5653100530CCC /* Crashlytics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Crashlytics.framework; sourceTree = "<group>"; };
883 5257417516C5CC5D00530CCC /* NSString+UbuntuOne.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSString+UbuntuOne.h"; path = "Categories/NSString+UbuntuOne.h"; sourceTree = "<group>"; };
884 5257417616C5CC5D00530CCC /* NSString+UbuntuOne.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSString+UbuntuOne.m"; path = "Categories/NSString+UbuntuOne.m"; sourceTree = "<group>"; };
885 5257417816C5CDA900530CCC /* UIImageView+UbuntuOne.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "UIImageView+UbuntuOne.h"; path = "Categories/UIImageView+UbuntuOne.h"; sourceTree = "<group>"; };
886 5257417916C5CDA900530CCC /* UIImageView+UbuntuOne.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "UIImageView+UbuntuOne.m"; path = "Categories/UIImageView+UbuntuOne.m"; sourceTree = "<group>"; };
887- 5257416C16C5653100530CCC /* Crashlytics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Crashlytics.framework; sourceTree = "<group>"; };
888 5268508516AE516B001F65A6 /* RestKit.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RestKit.xcodeproj; path = ../RestKit/RestKit.xcodeproj; sourceTree = "<group>"; };
889 526850A516AEE4E1001F65A6 /* Storyboard_iPhone.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Storyboard_iPhone.storyboard; sourceTree = "<group>"; };
890 526850A616AEE4E1001F65A6 /* UOAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UOAppDelegate.h; sourceTree = "<group>"; };
891@@ -640,6 +643,7 @@
892 5268509716AE5267001F65A6 /* libRestKit.a in Frameworks */,
893 52E7F4A316AF1522003A46DA /* UbuntuOneAuthKit.a in Frameworks */,
894 5257416D16C5653100530CCC /* Crashlytics.framework in Frameworks */,
895+ 5207A4C216C89B140006A4E6 /* libFlurry.a in Frameworks */,
896 );
897 runOnlyForDeploymentPostprocessing = 0;
898 };
899@@ -672,7 +676,6 @@
900 29B97317FDCFA39411CA2CEA /* Resources */,
901 964FA39013CA5BE60018A65B /* Dependencies */,
902 29B97323FDCFA39411CA2CEA /* Frameworks */,
903- 5279764815F00B2600F8435F /* libz.dylib */,
904 19C28FACFE9D520D11CA2CBB /* Products */,
905 );
906 name = CustomTemplate;
907@@ -690,6 +693,7 @@
908 29B97323FDCFA39411CA2CEA /* Frameworks */ = {
909 isa = PBXGroup;
910 children = (
911+ 5279764815F00B2600F8435F /* libz.dylib */,
912 5257416C16C5653100530CCC /* Crashlytics.framework */,
913 5268510716AEFD20001F65A6 /* MobileCoreServices.framework */,
914 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */,
915@@ -707,6 +711,16 @@
916 name = Frameworks;
917 sourceTree = "<group>";
918 };
919+ 5207A4BF16C89B140006A4E6 /* Flurry */ = {
920+ isa = PBXGroup;
921+ children = (
922+ 5207A4C016C89B140006A4E6 /* Flurry.h */,
923+ 5207A4C116C89B140006A4E6 /* libFlurry.a */,
924+ );
925+ name = Flurry;
926+ path = Dependencies/Flurry;
927+ sourceTree = "<group>";
928+ };
929 522B24E716B4BBC30084B023 /* Controls */ = {
930 isa = PBXGroup;
931 children = (
932@@ -1299,6 +1313,7 @@
933 964FA39013CA5BE60018A65B /* Dependencies */ = {
934 isa = PBXGroup;
935 children = (
936+ 5207A4BF16C89B140006A4E6 /* Flurry */,
937 5257414C16C37E1A00530CCC /* SSPullToRefresh */,
938 93BC520A124C187700B7587C /* SynthesizeSingleton.h */,
939 91328278144E07EA00395F40 /* TestFlight SDK */,
940@@ -1714,6 +1729,7 @@
941 "$(inherited)",
942 "\"$(SRCROOT)/TestFlight SDK\"",
943 "$(BUILT_PRODUCTS_DIR)/**",
944+ "\"$(SRCROOT)/Dependencies/Flurry\"",
945 );
946 OTHER_LDFLAGS = "-ObjC";
947 PRODUCT_NAME = "U1 Music";
948@@ -1754,6 +1770,7 @@
949 "$(inherited)",
950 "\"$(SRCROOT)/TestFlight SDK\"",
951 "$(BUILT_PRODUCTS_DIR)/**",
952+ "\"$(SRCROOT)/Dependencies/Flurry\"",
953 );
954 OTHER_LDFLAGS = "-ObjC";
955 PRODUCT_NAME = "U1 Music";
956
957=== modified file 'U1Music_Prefix.pch'
958--- U1Music_Prefix.pch 2013-01-28 22:54:20 +0000
959+++ U1Music_Prefix.pch 2013-02-11 04:20:26 +0000
960@@ -21,10 +21,22 @@
961 #import "NSManagedObjectContext+Additions.h"
962 #import "NSString+Extras.h"
963 #import "TestFlight.h"
964+ #import "Flurry.h"
965 #define RELEASE_SAFELY(__obj) [__obj release], __obj = nil;
966
967 #define UBUNTU_ONE_SERVICE_NAME @"com.ubuntu.one"
968 #define UBUNTU_ONE_DUMMY_USER_NAME @"_UBUNTU_ONE_USER_NAME"
969
970 #define AUTHORIZATION_HEADER_KEY @"Authorization"
971+
972+ #define EVENT_ALBUMS_VIEW @"AlbumsView"
973+ #define EVENT_ARTISTS_VIEW @"ArtistsView"
974+ #define EVENT_SONGS_VIEW @"SongsView"
975+ #define EVENT_PLAYLISTS_VIEW @"PlaylistsView"
976+ #define EVENT_SETTINGS_VIEW @"SettingsView"
977+ #define EVENT_AUTHENTICATION_VIEW @"AuthenticationView"
978+ #define EVENT_ALBUM_VIEW @"AlbumView"
979+ #define EVENT_ARTIST_VIEW @"ArtistView"
980+ #define EVENT_PLAYER_VIEW @"PlayerView"
981+ #define EVENT_PLAYLIST_VIEW @"PlaylistView"
982 #endif

Subscribers

People subscribed via source and target branches