[ios] Custom Facebook events for better marketing campaigns.
This commit is contained in:
parent
ffefd63197
commit
ef1d8632b0
4 changed files with 121 additions and 0 deletions
|
@ -12,6 +12,7 @@
|
|||
#import "RouteState.h"
|
||||
#import "Statistics.h"
|
||||
#import "UIKitCategories.h"
|
||||
#import "MWMCustomFacebookEvents.h"
|
||||
#import <FBSDKCoreKit/FBSDKCoreKit.h>
|
||||
#import <Parse/Parse.h>
|
||||
#import <ParseFacebookUtilsV4/PFFacebookUtils.h>
|
||||
|
@ -324,6 +325,8 @@ void InitLocalizedStrings()
|
|||
|
||||
[FBSDKAppEvents activateApp];
|
||||
[self restoreRouteState];
|
||||
// Special FB events to improve marketing campaigns quality.
|
||||
[MWMCustomFacebookEvents optimizeExpenses];
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
|
|
|
@ -112,6 +112,7 @@
|
|||
4A7D89C81B2EBF3B00AC843E /* resources-xxhdpi_dark in Resources */ = {isa = PBXBuildFile; fileRef = 4A7D89C41B2EBF3B00AC843E /* resources-xxhdpi_dark */; };
|
||||
5605022F1B6211E100169CAD /* sound-strings in Resources */ = {isa = PBXBuildFile; fileRef = 5605022E1B6211E100169CAD /* sound-strings */; };
|
||||
6B8A738A1B2616E90085EFE6 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA87151A12B1518F00592DAF /* SystemConfiguration.framework */; };
|
||||
6BA0BCD11B74DDBA00CC9969 /* MWMCustomFacebookEvents.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6BA0BCD01B74DDBA00CC9969 /* MWMCustomFacebookEvents.mm */; };
|
||||
6C24A3AD1AD7CA1000A47B99 /* MWMNoMapInterfaceController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6C47C8C81AD6C825000C52C1 /* MWMNoMapInterfaceController.mm */; };
|
||||
6C24A3B21AD7D65500A47B99 /* MWMWatchEventInfo.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6C24A3B11AD7D65500A47B99 /* MWMWatchEventInfo.mm */; };
|
||||
6C24A3B31AD7D65500A47B99 /* MWMWatchEventInfo.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6C24A3B11AD7D65500A47B99 /* MWMWatchEventInfo.mm */; };
|
||||
|
@ -448,6 +449,8 @@
|
|||
4A7D89C31B2EBF3B00AC843E /* resources-xhdpi_dark */ = {isa = PBXFileReference; lastKnownFileType = folder; name = "resources-xhdpi_dark"; path = "../../data/resources-xhdpi_dark"; sourceTree = "<group>"; };
|
||||
4A7D89C41B2EBF3B00AC843E /* resources-xxhdpi_dark */ = {isa = PBXFileReference; lastKnownFileType = folder; name = "resources-xxhdpi_dark"; path = "../../data/resources-xxhdpi_dark"; sourceTree = "<group>"; };
|
||||
5605022E1B6211E100169CAD /* sound-strings */ = {isa = PBXFileReference; lastKnownFileType = folder; name = "sound-strings"; path = "../../data/sound-strings"; sourceTree = "<group>"; };
|
||||
6BA0BCCF1B74DDBA00CC9969 /* MWMCustomFacebookEvents.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMCustomFacebookEvents.h; sourceTree = "<group>"; };
|
||||
6BA0BCD01B74DDBA00CC9969 /* MWMCustomFacebookEvents.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMCustomFacebookEvents.mm; sourceTree = "<group>"; };
|
||||
6C24A3B01AD7D65500A47B99 /* MWMWatchEventInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMWatchEventInfo.h; sourceTree = "<group>"; };
|
||||
6C24A3B11AD7D65500A47B99 /* MWMWatchEventInfo.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMWatchEventInfo.mm; sourceTree = "<group>"; };
|
||||
6C47C8C31AD6C78A000C52C1 /* MWMNoLocationInterfaceController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMNoLocationInterfaceController.h; sourceTree = "<group>"; };
|
||||
|
@ -1355,6 +1358,8 @@
|
|||
CB252D6816FF82C8001E41E9 /* Statistics */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
6BA0BCCF1B74DDBA00CC9969 /* MWMCustomFacebookEvents.h */,
|
||||
6BA0BCD01B74DDBA00CC9969 /* MWMCustomFacebookEvents.mm */,
|
||||
97C98521186AE3CF00AF7E9E /* AppInfo.h */,
|
||||
97C98520186AE3CF00AF7E9E /* AppInfo.mm */,
|
||||
CB252D6B16FF82C8001E41E9 /* Statistics.h */,
|
||||
|
@ -2275,6 +2280,7 @@
|
|||
34BC722A1B0DECAE0012A34B /* MWMZoomButtonsView.m in Sources */,
|
||||
F6F533A31B3C248900C1940B /* UIColor+MapsMeColor.mm in Sources */,
|
||||
CB252D6F16FF82C9001E41E9 /* Statistics.mm in Sources */,
|
||||
6BA0BCD11B74DDBA00CC9969 /* MWMCustomFacebookEvents.mm in Sources */,
|
||||
978F9244183B660F000D6C7C /* SwitchCell.m in Sources */,
|
||||
342AD7721B53D32F00E0B997 /* UIView+RuntimeAttributes.m in Sources */,
|
||||
F64F4B6D1B46A51F0081A24A /* MWMDownloaderDialogCell.mm in Sources */,
|
||||
|
|
16
iphone/Maps/Statistics/MWMCustomFacebookEvents.h
Normal file
16
iphone/Maps/Statistics/MWMCustomFacebookEvents.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
//
|
||||
// MWMCustomFacebookEvents.h
|
||||
// Maps
|
||||
//
|
||||
// Created by Alex Zolotarev on 8/7/15.
|
||||
// Copyright (c) 2015 MAPS.ME. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
// Special logic for custom Facebook events to optimize marketing campaigns.
|
||||
@interface MWMCustomFacebookEvents : NSObject
|
||||
|
||||
+ (void)optimizeExpenses;
|
||||
|
||||
@end
|
96
iphone/Maps/Statistics/MWMCustomFacebookEvents.mm
Normal file
96
iphone/Maps/Statistics/MWMCustomFacebookEvents.mm
Normal file
|
@ -0,0 +1,96 @@
|
|||
#import "MWMCustomFacebookEvents.h"
|
||||
#import "3party/Alohalytics/src/alohalytics_objc.h"
|
||||
|
||||
#import <FBSDKCoreKit/FBSDKCoreKit.h>
|
||||
|
||||
#include "Framework.h"
|
||||
|
||||
@implementation MWMCustomFacebookEvents
|
||||
|
||||
// Used to filter out old users and to track only new installs.
|
||||
static NSString * const kEnableCustomFBEventsForNewUsers = @"FBEnableCustomEventsForNewUsers";
|
||||
// Special one-time events to improve marketing targeting.
|
||||
static NSString * const kFirstSessionIsLongerThanXMinutesEvent = @"FBLongFirstSession";
|
||||
static NSInteger const kFirstSessionLengthInSeconds = 5 * 60;
|
||||
static NSString * const kNextLaunchAfterHoursInterval = @"FBLaunchedAgainInAFewHoursAfterInstall";
|
||||
static NSInteger const kNextLaunchMinHoursInterval = 6;
|
||||
static NSString * const kDownloadedSecondMapEvent = @"FBDownloadedSecondMap";
|
||||
|
||||
static constexpr int kNotSubscribed = -1;
|
||||
static int gStorageSubscriptionId = kNotSubscribed;
|
||||
|
||||
+ (void)markEventAsAlreadyFired:(NSString *)event
|
||||
{
|
||||
NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults];
|
||||
[defaults setBool:YES forKey:event];
|
||||
[defaults synchronize];
|
||||
}
|
||||
|
||||
// This notification is called exactly once upon a whole life time of the app.
|
||||
+ (void)applicationDidEnterBackgroundOnlyOnceInAnAppLifeTimeAtTheEndOfVeryFirstSession:(NSNotification *)notification
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:[MWMCustomFacebookEvents class]];
|
||||
NSInteger const seconds = [Alohalytics totalSecondsSpentInTheApp];
|
||||
if (seconds >= kFirstSessionLengthInSeconds)
|
||||
[FBSDKAppEvents logEvent:kFirstSessionIsLongerThanXMinutesEvent parameters:@{@"Minutes" : [NSNumber numberWithInteger:(seconds / 60)]}];
|
||||
[MWMCustomFacebookEvents markEventAsAlreadyFired:kFirstSessionIsLongerThanXMinutesEvent];
|
||||
}
|
||||
|
||||
+ (void)optimizeExpenses
|
||||
{
|
||||
NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults];
|
||||
BOOL const isFirstSession = [Alohalytics isFirstSession];
|
||||
if (isFirstSession)
|
||||
{
|
||||
[defaults setBool:YES forKey:kEnableCustomFBEventsForNewUsers];
|
||||
[defaults synchronize];
|
||||
}
|
||||
// All these events should be fired only for new users who installed the app.
|
||||
if ([defaults boolForKey:kEnableCustomFBEventsForNewUsers])
|
||||
{
|
||||
// Skip already fired events.
|
||||
// This one is fired when user spent more than kFirstSessionLengthInSeconds in the first session.
|
||||
if (isFirstSession && ![defaults boolForKey:kFirstSessionIsLongerThanXMinutesEvent])
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] addObserver:[MWMCustomFacebookEvents class]
|
||||
selector:@selector(applicationDidEnterBackgroundOnlyOnceInAnAppLifeTimeAtTheEndOfVeryFirstSession:)
|
||||
name:UIApplicationDidEnterBackgroundNotification
|
||||
object:nil];
|
||||
[MWMCustomFacebookEvents markEventAsAlreadyFired:kFirstSessionIsLongerThanXMinutesEvent];
|
||||
}
|
||||
// This event is fired when user launched app again in between kNextLaunchMinHoursInterval and kNextLaunchMaxHoursInterval.
|
||||
if (![defaults boolForKey:kNextLaunchAfterHoursInterval])
|
||||
{
|
||||
NSInteger const hoursFromFirstLaunch = (-[[Alohalytics firstLaunchDate] timeIntervalSinceNow]) / 3600;
|
||||
if (hoursFromFirstLaunch >= kNextLaunchMinHoursInterval)
|
||||
{
|
||||
[FBSDKAppEvents logEvent:kNextLaunchAfterHoursInterval];
|
||||
[MWMCustomFacebookEvents markEventAsAlreadyFired:kNextLaunchAfterHoursInterval];
|
||||
}
|
||||
}
|
||||
// Fired when user downloads second (or more) map.
|
||||
if (![defaults boolForKey:kDownloadedSecondMapEvent])
|
||||
{
|
||||
if (gStorageSubscriptionId == kNotSubscribed)
|
||||
{
|
||||
gStorageSubscriptionId = GetFramework().Storage().Subscribe([](storage::TIndex const &)
|
||||
{
|
||||
if (GetFramework().Storage().GetDownloadedFilesCount() >= 2)
|
||||
{
|
||||
[FBSDKAppEvents logEvent:kDownloadedSecondMapEvent];
|
||||
[MWMCustomFacebookEvents markEventAsAlreadyFired:kDownloadedSecondMapEvent];
|
||||
// We can't unsubscribe from this callback immediately now, it will crash Storage's observers notification.
|
||||
dispatch_async(dispatch_get_main_queue(),
|
||||
^{
|
||||
GetFramework().Storage().Unsubscribe(gStorageSubscriptionId);
|
||||
gStorageSubscriptionId = kNotSubscribed;
|
||||
});
|
||||
[Alohalytics logEvent:kDownloadedSecondMapEvent];
|
||||
}
|
||||
}, [](storage::TIndex const &, storage::LocalAndRemoteSizeT const &){});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
Reference in a new issue