<commit_before>
#import "AppInfo.h"
#import <CoreTelephony/CTCarrier.h>
#import <CoreTelephony/CTTelephonyNetworkInfo.h>
#import <sys/utsname.h>
#import <AdSupport/ASIdentifierManager.h>
#include "../../../platform/settings.hpp"

NSString * const AppFeatureInterstitial = @"AppFeatureInterstitial";
NSString * const AppFeatureBanner = @"AppFeatureBanner";
NSString * const AppFeatureProButtonOnMap = @"AppFeatureProButtonOnMap";
NSString * const AppFeatureMoreAppsBanner = @"AppFeatureMoreAppsBanner";

@interface AppInfo ()

@property (nonatomic) NSDictionary * features;
@property (nonatomic) NSDictionary * featuresByDefault;

@property (nonatomic) NSString * countryCode;
@property (nonatomic) NSString * uniqueId;
@property (nonatomic) Reachability * reachability;
@property (nonatomic) NSInteger launchCount;
@property (nonatomic) NSDate * firstLaunchDate;

@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.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];
      [self.reachability stopNotifier];
    }
    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, ^{
    appInfo = [[self alloc] init];
  });
  return appInfo;
}

- (instancetype)init
{
  self = [super init];

  [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidBecomeActive:) name:UIApplicationDidBecomeActiveNotification object:nil];

  self.featuresByDefault = @{AppFeatureInterstitial : @NO,
                             AppFeatureBanner : @NO,
                             AppFeatureProButtonOnMap : @NO,
                             AppFeatureMoreAppsBanner : @YES,
                            };

  [self update];<commit_msg>[ios] Pro button on map is enabled by default<commit_after>
#import "AppInfo.h"
#import <CoreTelephony/CTCarrier.h>
#import <CoreTelephony/CTTelephonyNetworkInfo.h>
#import <sys/utsname.h>
#import <AdSupport/ASIdentifierManager.h>
#include "../../../platform/settings.hpp"

NSString * const AppFeatureInterstitial = @"AppFeatureInterstitial";
NSString * const AppFeatureBanner = @"AppFeatureBanner";
NSString * const AppFeatureProButtonOnMap = @"AppFeatureProButtonOnMap";
NSString * const AppFeatureMoreAppsBanner = @"AppFeatureMoreAppsBanner";

@interface AppInfo ()

@property (nonatomic) NSDictionary * features;
@property (nonatomic) NSDictionary * featuresByDefault;

@property (nonatomic) NSString * countryCode;
@property (nonatomic) NSString * uniqueId;
@property (nonatomic) Reachability * reachability;
@property (nonatomic) NSInteger launchCount;
@property (nonatomic) NSDate * firstLaunchDate;

@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.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];
      [self.reachability stopNotifier];
    }
    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, ^{
    appInfo = [[self alloc] init];
  });
  return appInfo;
}

- (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];
{'fraction_non_alphanumeric': 0.11008855704115297, 'fraction_numerical': 0.0017364125716270186, 'mean_word_length': 4.501432664756447, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6794405', 'n_tokens_mistral': 1758, 'n_tokens_neox': 1655, 'n_words': 343}