diff --git a/iphone/Maps/Classes/LocalNotificationManager.mm b/iphone/Maps/Classes/LocalNotificationManager.mm index a8c036ebc9..536bb5d3da 100644 --- a/iphone/Maps/Classes/LocalNotificationManager.mm +++ b/iphone/Maps/Classes/LocalNotificationManager.mm @@ -6,6 +6,7 @@ #import "LocationManager.h" #import "MapsAppDelegate.h" #import "MapViewController.h" +#import "Reachability.h" #import "Statistics.h" #import "TimeUtils.h" #import "UIKitCategories.h" @@ -321,7 +322,7 @@ typedef void (^CompletionHandler)(UIBackgroundFetchResult); UIBackgroundFetchResult result = UIBackgroundFetchResultNoData; BOOL const inBackground = [UIApplication sharedApplication].applicationState == UIApplicationStateBackground; - BOOL const onWiFi = [[AppInfo sharedInfo].reachability isReachableViaWiFi]; + BOOL const onWiFi = Reachability.reachabilityForInternetConnection.isReachableViaWiFi; if (inBackground && onWiFi) { Framework & f = GetFramework(); diff --git a/iphone/Maps/Statistics/AppInfo.h b/iphone/Maps/Statistics/AppInfo.h index 7241fd228b..a78d7faa91 100644 --- a/iphone/Maps/Statistics/AppInfo.h +++ b/iphone/Maps/Statistics/AppInfo.h @@ -1,32 +1,17 @@ - #import -#import "Reachability.h" - -extern NSString * const AppFeatureInterstitial; -extern NSString * const AppFeatureBanner; -extern NSString * const AppFeatureProButtonOnMap; -extern NSString * const AppFeatureMoreAppsBanner; -extern NSString * const AppFeatureBottomMenuItems; - -extern NSString * const AppInfoSyncedNotification; @interface AppInfo : NSObject + (instancetype)sharedInfo; +- (instancetype)init __attribute__((unavailable("init is not available"))); -- (BOOL)featureAvailable:(NSString *)featureName; -- (id)featureValue:(NSString *)featureName forKey:(NSString *)key; - -- (NSString *)snapshot; - +@property (nonatomic, readonly) NSString * snapshot; @property (nonatomic, readonly) NSString * countryCode; @property (nonatomic, readonly) NSString * uniqueId; -@property (nonatomic, readonly) Reachability * reachability; @property (nonatomic, readonly) NSInteger launchCount; @property (nonatomic, readonly) NSDate * firstLaunchDate; -- (NSString *)bundleVersion; -- (NSString *)deviceInfo; -- (NSString *)firmwareVersion; -- (NSUUID *)advertisingId; +@property (nonatomic, readonly) NSString * bundleVersion; +@property (nonatomic, readonly) NSString * deviceInfo; +@property (nonatomic, readonly) NSUUID * advertisingId; @end diff --git a/iphone/Maps/Statistics/AppInfo.mm b/iphone/Maps/Statistics/AppInfo.mm index b05107bee1..cd88a840b7 100644 --- a/iphone/Maps/Statistics/AppInfo.mm +++ b/iphone/Maps/Statistics/AppInfo.mm @@ -6,77 +6,32 @@ #import #include "../../../platform/settings.hpp" -NSString * const AppFeatureInterstitial = @"AppFeatureInterstitial"; -NSString * const AppFeatureBanner = @"AppFeatureBanner"; -NSString * const AppFeatureProButtonOnMap = @"AppFeatureProButtonOnMap"; -NSString * const AppFeatureMoreAppsBanner = @"AppFeatureMoreAppsBanner"; -NSString * const AppFeatureBottomMenuItems = @"AppFeatureBottomMenuItems"; +static string const kCountryCodeKey = "CountryCode"; +static string const kUniqueIdKey = "UniqueId"; +static string const kLaunchCountKey = "LaunchCount"; +static NSString * const kAppInfoFirstLaunchDateKey = @"AppInfoFirstLaunchDate"; -NSString * const AppInfoSyncedNotification = @"AppInfoSyncedNotification"; - -@interface AppInfo () - -@property (nonatomic) NSDictionary * features; -@property (nonatomic) NSDictionary * featuresByDefault; +@interface AppInfo() +@property (nonatomic) NSString * snapshot; @property (nonatomic) NSString * countryCode; @property (nonatomic) NSString * uniqueId; -@property (nonatomic) Reachability * reachability; @property (nonatomic) NSInteger launchCount; @property (nonatomic) NSDate * firstLaunchDate; +@property (nonatomic) NSString * bundleVersion; +@property (nonatomic) NSString * deviceInfo; +@property (nonatomic) NSUUID * advertisingId; @end @implementation AppInfo -- (void)dealloc -{ - [self.reachability stopNotifier]; - [[NSNotificationCenter defaultCenter] removeObserver:self]; -} - -- (void)applicationDidBecomeActive:(NSNotification *)notification -{ - self.launchCount++; -} - -- (void)update -{ - NSString * urlString = @"http://application.server/ios/features_v2.json"; - NSURLRequest * request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlString] cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:20]; - [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * r, NSData * d, NSError * e){ - if ([(NSHTTPURLResponse *)r statusCode] == 200) - { - [d writeToFile:[self featuresPath] atomically:YES]; - _features = nil; - [self.reachability stopNotifier]; - [[NSNotificationCenter defaultCenter] postNotificationName:AppInfoSyncedNotification object:nil]; - } - else - { - __weak id weakSelf = self; - self.reachability.reachableBlock = ^(Reachability * r){ - if ([r isReachable]) - [weakSelf update]; - }; - [self.reachability startNotifier]; - } - }]; -} - -- (NSString *)featuresPath -{ - NSString * libraryPath = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) firstObject]; - return [libraryPath stringByAppendingPathComponent:@"AvailableFeatures.json"]; -} - -#pragma mark - Public methods - + (instancetype)sharedInfo { static AppInfo * appInfo; static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ + dispatch_once(&onceToken, ^ + { appInfo = [[self alloc] init]; }); return appInfo; @@ -85,107 +40,35 @@ NSString * const AppInfoSyncedNotification = @"AppInfoSyncedNotification"; - (instancetype)init { self = [super init]; - - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidBecomeActive:) name:UIApplicationDidBecomeActiveNotification object:nil]; - - self.featuresByDefault = @{AppFeatureInterstitial : @NO, - AppFeatureBanner : @NO, - AppFeatureProButtonOnMap : @YES, - AppFeatureMoreAppsBanner : @YES}; - - [self update]; - - if (!self.firstLaunchDate) - self.firstLaunchDate = [NSDate date]; - + [self setup]; return self; } -- (BOOL)featureAvailable:(NSString *)featureName +- (void)setup { - if (!self.features) // features haven't been downloaded yet - return [self.featuresByDefault[featureName] boolValue]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidBecomeActive:) name:UIApplicationDidBecomeActiveNotification object:nil]; - return [self featureParameters:featureName] != nil; + if (!self.firstLaunchDate) + self.firstLaunchDate = [NSDate date]; } -- (id)featureValue:(NSString *)featureName forKey:(NSString *)key +- (void)dealloc { - NSDictionary *parameters = [self featureParameters:featureName]; - if (parameters && parameters[key]) - return parameters[key]; - - return nil; + [[NSNotificationCenter defaultCenter] removeObserver:self]; } -- (NSDictionary *)findValueForKey:(NSString *)key inDictionary:(NSDictionary *)parameters +- (void)applicationDidBecomeActive:(NSNotification *)notification { - for (NSString * aKey in [parameters allKeys]) - if ([aKey rangeOfString:key].location != NSNotFound) - return parameters[aKey]; - return nil; + self.launchCount++; } -- (NSDictionary *)featureParameters:(NSString *)featureName -{ - NSDictionary * parameters = [self findValueForKey:[NSString stringWithFormat:@"Country=%@", self.countryCode] inDictionary:self.features[featureName]]; - if (!parameters) - parameters = [self findValueForKey:[NSString stringWithFormat:@"Lang=%@", [[NSLocale preferredLanguages] firstObject]] inDictionary:self.features[featureName]]; - - if (!parameters) - parameters = [self findValueForKey:@"*" inDictionary:self.features[featureName]]; - - return parameters; -} +#pragma mark - Properties - (NSString *)snapshot { - return [NSString stringWithFormat:@"maps.me ver. %@, %@ (iOS %@) %@", self.bundleVersion, self.deviceInfo, self.firmwareVersion, self.countryCode]; -} - -#pragma mark - Public properties - -- (void)setLaunchCount:(NSInteger)launchCount -{ - Settings::Set("LaunchCount", (int)launchCount); -} - -- (NSInteger)launchCount -{ - int count = 0; - Settings::Get("LaunchCount", count); - return count; -} - -- (NSString *)uniqueId -{ - if (!_uniqueId) - { - string uniqueString; - if (Settings::Get("UniqueId", uniqueString)) // if id stored in settings - { - _uniqueId = [NSString stringWithUTF8String:uniqueString.c_str()]; - } - else // if id not stored in settings - { - _uniqueId = [[UIDevice currentDevice].identifierForVendor UUIDString]; - if (_uniqueId) // then saving in settings - Settings::Set("UniqueId", std::string([_uniqueId UTF8String])); - } - } - return _uniqueId; -} - -- (NSUUID *)advertisingId -{ - if (NSClassFromString(@"ASIdentifierManager")) - { - ASIdentifierManager * m = [ASIdentifierManager sharedManager]; - if (m.isAdvertisingTrackingEnabled) - return m.advertisingIdentifier; - } - - return nil; + if (!_snapshot) + _snapshot = [NSString stringWithFormat:@"maps.me ver. %@, %@ (iOS %@) %@", self.bundleVersion, self.deviceInfo, [UIDevice currentDevice].systemVersion, self.countryCode]; + return _snapshot; } - (NSString *)countryCode @@ -200,17 +83,17 @@ NSString * const AppInfoSyncedNotification = @"AppInfoSyncedNotification"; _countryCode = [[[NSLocale currentLocale] objectForKey:NSLocaleCountryCode] uppercaseString]; std::string codeString; - if (Settings::Get("CountryCode", codeString)) // if country code stored in settings + if (Settings::Get(kCountryCodeKey, codeString)) // if country code stored in settings { if (carrier.isoCountryCode) // if device can access sim card info - Settings::Set("CountryCode", std::string([_countryCode UTF8String])); // then save new code instead + Settings::Set(kCountryCodeKey, std::string([_countryCode UTF8String])); // then save new code instead else _countryCode = [NSString stringWithUTF8String:codeString.c_str()]; // if device can NOT access sim card info then using saved code } else { if (_countryCode) - Settings::Set("CountryCode", std::string([_countryCode UTF8String])); // saving code first time + Settings::Set(kCountryCodeKey, std::string([_countryCode UTF8String])); // saving code first time else _countryCode = @""; } @@ -218,52 +101,75 @@ NSString * const AppInfoSyncedNotification = @"AppInfoSyncedNotification"; return _countryCode; } -- (NSString *)bundleVersion +- (NSString *)uniqueId { - return [[NSBundle mainBundle] infoDictionary][@"CFBundleVersion"]; + if (!_uniqueId) + { + string uniqueString; + if (Settings::Get(kUniqueIdKey, uniqueString)) // if id stored in settings + { + _uniqueId = [NSString stringWithUTF8String:uniqueString.c_str()]; + } + else // if id not stored in settings + { + _uniqueId = [[UIDevice currentDevice].identifierForVendor UUIDString]; + if (_uniqueId) // then saving in settings + Settings::Set(kUniqueIdKey, std::string([_uniqueId UTF8String])); + } + } + return _uniqueId; } -- (NSString *)deviceInfo +- (void)setLaunchCount:(NSInteger)launchCount { - struct utsname systemInfo; - uname(&systemInfo); - return [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding]; + Settings::Set(kLaunchCountKey, (int)launchCount); } -- (NSString *)firmwareVersion +- (NSInteger)launchCount { - return [UIDevice currentDevice].systemVersion; -} - -- (Reachability *)reachability -{ - if (!_reachability) - _reachability = [Reachability reachabilityForInternetConnection]; - return _reachability; -} - -- (NSDate *)firstLaunchDate -{ - return [[NSUserDefaults standardUserDefaults] objectForKey:@"AppInfoFirstLaunchDate"]; + int count = 0; + Settings::Get(kLaunchCountKey, count); + return count; } - (void)setFirstLaunchDate:(NSDate *)firstLaunchDate { - [[NSUserDefaults standardUserDefaults] setObject:firstLaunchDate forKey:@"AppInfoFirstLaunchDate"]; + [[NSUserDefaults standardUserDefaults] setObject:firstLaunchDate forKey:kAppInfoFirstLaunchDateKey]; [[NSUserDefaults standardUserDefaults] synchronize]; } -#pragma mark - Private properties - -- (NSDictionary *)features +- (NSDate *)firstLaunchDate { - if (!_features) + return [[NSUserDefaults standardUserDefaults] objectForKey:kAppInfoFirstLaunchDateKey]; +} + +- (NSString *)bundleVersion +{ + if (!_bundleVersion) + _bundleVersion = [[NSBundle mainBundle] infoDictionary][@"CFBundleVersion"]; + return _bundleVersion; +} + +- (NSString *)deviceInfo +{ + if (!_deviceInfo) { - NSData * data = [NSData dataWithContentsOfFile:[self featuresPath]]; - if (data) - _features = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil]; + struct utsname systemInfo; + uname(&systemInfo); + _deviceInfo = [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding]; } - return _features; + return _deviceInfo; +} + +- (NSUUID *)advertisingId +{ + if (!_advertisingId) + { + ASIdentifierManager * m = [ASIdentifierManager sharedManager]; + if (m.isAdvertisingTrackingEnabled) + _advertisingId = m.advertisingIdentifier; + } + return _advertisingId; } @end