[MAPSME-6783] [ios] Updated network policy.

This commit is contained in:
Ilya Grechuhin 2018-02-12 12:32:34 +03:00 committed by Vlad Mihaylenko
parent 8c08668bed
commit e9ddb58a66
18 changed files with 240 additions and 287 deletions

View file

@ -4,3 +4,15 @@ extension String {
self.init(format: format, arguments: arguments.map { "\($0)" })
}
}
extension NSString {
@objc
static func string(coreFormat: String, arguments: [AnyObject]) -> NSString {
return NSString(coreFormat: coreFormat, arguments: arguments)
}
@objc
convenience init(coreFormat: String, arguments: [AnyObject]) {
self.init(string: String(coreFormat: coreFormat, arguments: arguments as! [CVarArg]))
}
}

View file

@ -30,21 +30,21 @@ NSString * const kStatisticsEvent = @"Mobile Internet Settings Alert";
- (IBAction)alwaysTap
{
[Statistics logEvent:kStatMobileInternet withParameters:@{kStatValue : kStatAlways}];
SetStage(np::Stage::Always);
SetStage(Stage::Always);
[self close:self.completionBlock];
}
- (IBAction)askTap
{
[Statistics logEvent:kStatMobileInternet withParameters:@{kStatValue : kStatAsk}];
SetStage(np::Stage::Session);
[Statistics logEvent:kStatMobileInternet withParameters:@{kStatValue: kStatToday}];
SetStage(Stage::Today);
[self close:self.completionBlock];
}
- (IBAction)neverTap
{
[Statistics logEvent:kStatisticsEvent withParameters:@{kStatAction : kStatNever}];
SetStage(np::Stage::Never);
[Statistics logEvent:kStatisticsEvent withParameters:@{kStatAction: kStatNotToday}];
SetStage(Stage::NotToday);
[self close:self.completionBlock];
}

View file

@ -101,7 +101,7 @@
</state>
<state key="highlighted" backgroundImage="dialog_btn_press"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="string" keyPath="localizedText" value="mobile_data_option_never"/>
<userDefinedRuntimeAttribute type="string" keyPath="localizedText" value="mobile_data_option_not_today"/>
<userDefinedRuntimeAttribute type="string" keyPath="textColorName" value="linkBlue"/>
<userDefinedRuntimeAttribute type="string" keyPath="fontName" value="medium17"/>
</userDefinedRuntimeAttributes>

View file

@ -118,22 +118,10 @@ extern NSString * const kAlohalyticsTapEventKey;
- (void)showPlacePage:(place_page::Info const &)info
{
auto show = ^(place_page::Info const & info) {
network_policy::CallPartnersApi([self, info](auto const & /* canUseNetwork */) {
self.trafficButtonHidden = YES;
[self.placePageManager show:info];
};
using namespace network_policy;
if (GetPlatform().ConnectionStatus() == Platform::EConnectionType::CONNECTION_WWAN &&
!CanUseNetwork() && GetStage() == platform::NetworkPolicy::Stage::Session)
{
[[MWMAlertViewController activeAlertController]
presentMobileInternetAlertWithBlock:[show, info] { show(info); }];
}
else
{
show(info);
}
});
}
- (void)searchTextOnMap:(NSString *)text forInputLocale:(NSString *)locale

View file

@ -94,101 +94,91 @@ using namespace taxi;
cv.hidden = YES;
cv.pageControl.hidden = YES;
network_policy::CallPartnersApi(
[self, completion, failure](platform::NetworkPolicy const & canUseNetwork) {
auto const engine = GetFramework().GetTaxiEngine(canUseNetwork);
if (!engine) {
failure(L(@"dialog_taxi_error"));
return;
}
network_policy::CallPartnersApi([self, completion, failure](auto const & canUseNetwork) {
auto const engine = GetFramework().GetTaxiEngine(canUseNetwork);
if (!engine)
{
failure(L(@"dialog_taxi_error"));
return;
}
auto success = [self, completion, failure](taxi::ProvidersContainer const & providers,
uint64_t const requestId) {
dispatch_async(dispatch_get_main_queue(), [self, completion, failure, providers,
requestId] {
if (self->m_requestId != requestId)
return;
if (providers.empty())
{
failure(L(@"taxi_no_providers"));
[Statistics logEvent:kStatRoutingBuildTaxi
withParameters:@{
@"error" : @"No providers (Taxi isn't in the city)"
}];
return;
}
auto const & provider = providers.front();
auto const & products = provider.GetProducts();
auto const type = provider.GetType();
self->m_products = products;
NSString * providerName = nil;
switch (type)
{
case taxi::Provider::Type::Uber:
self.type = MWMRoutePreviewTaxiCellTypeUber;
providerName = kStatUber;
break;
case taxi::Provider::Type::Yandex:
self.type = MWMRoutePreviewTaxiCellTypeYandex;
providerName = kStatYandex;
break;
}
[Statistics logEvent:kStatRoutingBuildTaxi
withParameters:@{
@"provider" : providerName
}];
auto cv = self.collectionView;
cv.hidden = NO;
cv.pageControl.hidden = products.size() == 1;
cv.numberOfPages = products.size();
cv.contentOffset = {};
cv.currentPage = 0;
[cv reloadData];
completion();
});
};
auto success = [self, completion, failure](taxi::ProvidersContainer const & providers,
uint64_t const requestId) {
dispatch_async(dispatch_get_main_queue(), [self, completion, failure, providers, requestId] {
if (self->m_requestId != requestId)
return;
if (providers.empty())
{
failure(L(@"taxi_no_providers"));
[Statistics logEvent:kStatRoutingBuildTaxi
withParameters:@{@"error": @"No providers (Taxi isn't in the city)"}];
return;
}
auto const & provider = providers.front();
auto const & products = provider.GetProducts();
auto const type = provider.GetType();
self->m_products = products;
NSString * providerName = nil;
switch (type)
{
case taxi::Provider::Type::Uber:
self.type = MWMRoutePreviewTaxiCellTypeUber;
providerName = kStatUber;
break;
case taxi::Provider::Type::Yandex:
self.type = MWMRoutePreviewTaxiCellTypeYandex;
providerName = kStatYandex;
break;
}
[Statistics logEvent:kStatRoutingBuildTaxi withParameters:@{@"provider": providerName}];
auto cv = self.collectionView;
cv.hidden = NO;
cv.pageControl.hidden = products.size() == 1;
cv.numberOfPages = products.size();
cv.contentOffset = {};
cv.currentPage = 0;
[cv reloadData];
completion();
});
};
auto error = [self, failure](taxi::ErrorsContainer const & errors,
uint64_t const requestId) {
dispatch_async(dispatch_get_main_queue(), [self, failure, errors, requestId] {
if (self->m_requestId != requestId)
return;
if (errors.empty())
{
NSCAssert(false, @"Errors container is empty");
return;
}
auto const & error = errors.front();
auto const errorCode = error.m_code;
auto const type = error.m_type;
NSString * provider = nil;
switch (type)
{
case taxi::Provider::Type::Uber: provider = kStatUber; break;
case taxi::Provider::Type::Yandex: provider = kStatYandex; break;
}
NSString * errorValue = nil;
switch (errorCode)
{
case taxi::ErrorCode::NoProducts:
errorValue = @"No products (Taxi is in the city, but no offers)";
failure(L(@"taxi_not_found"));
break;
case taxi::ErrorCode::RemoteError:
errorValue = @"Server error (The taxi server responded with an error)";
failure(L(@"dialog_taxi_error"));
break;
}
[Statistics logEvent:kStatRoutingBuildTaxi
withParameters:@{
@"provider" : provider,
@"error" : errorValue
}];
});
};
auto error = [self, failure](taxi::ErrorsContainer const & errors, uint64_t const requestId) {
dispatch_async(dispatch_get_main_queue(), [self, failure, errors, requestId] {
if (self->m_requestId != requestId)
return;
if (errors.empty())
{
NSCAssert(false, @"Errors container is empty");
return;
}
auto const & error = errors.front();
auto const errorCode = error.m_code;
auto const type = error.m_type;
NSString * provider = nil;
switch (type)
{
case taxi::Provider::Type::Uber: provider = kStatUber; break;
case taxi::Provider::Type::Yandex: provider = kStatYandex; break;
}
NSString * errorValue = nil;
switch (errorCode)
{
case taxi::ErrorCode::NoProducts:
errorValue = @"No products (Taxi is in the city, but no offers)";
failure(L(@"taxi_not_found"));
break;
case taxi::ErrorCode::RemoteError:
errorValue = @"Server error (The taxi server responded with an error)";
failure(L(@"dialog_taxi_error"));
break;
}
[Statistics logEvent:kStatRoutingBuildTaxi
withParameters:@{@"provider": provider, @"error": errorValue}];
});
};
m_requestId = engine->GetAvailableProducts(m_from, m_to, success, error);
});
m_requestId = engine->GetAvailableProducts(m_from, m_to, success, error);
});
}
- (BOOL)isTaxiInstalled
@ -210,25 +200,23 @@ using namespace taxi;
auto const index = [self.collectionView indexPathsForVisibleItems].firstObject.row;
auto const productId = m_products[index].m_productId;
network_policy::CallPartnersApi(
[self, productId, block](platform::NetworkPolicy const & canUseNetwork)
network_policy::CallPartnersApi([self, productId, block](auto const & canUseNetwork) {
auto const engine = GetFramework().GetTaxiEngine(canUseNetwork);
if (!engine)
return;
Provider::Type type;
switch (self.type)
{
auto const engine = GetFramework().GetTaxiEngine(canUseNetwork);
if (!engine)
return;
Provider::Type type;
switch (self.type)
{
case MWMRoutePreviewTaxiCellTypeTaxi: return;
case MWMRoutePreviewTaxiCellTypeUber: type = Provider::Type::Uber; break;
case MWMRoutePreviewTaxiCellTypeYandex: type = Provider::Type::Yandex; break;
}
case MWMRoutePreviewTaxiCellTypeTaxi: return;
case MWMRoutePreviewTaxiCellTypeUber: type = Provider::Type::Uber; break;
case MWMRoutePreviewTaxiCellTypeYandex: type = Provider::Type::Yandex; break;
}
auto links = engine->GetRideRequestLinks(type, productId, m_from, m_to);
auto url = [NSURL URLWithString:self.isTaxiInstalled ? @(links.m_deepLink.c_str()) :
@(links.m_universalLink.c_str())];
block(url);
});
auto links = engine->GetRideRequestLinks(type, productId, m_from, m_to);
auto url = [NSURL URLWithString:self.isTaxiInstalled ? @(links.m_deepLink.c_str())
: @(links.m_universalLink.c_str())];
block(url);
});
}
#pragma mark - UICollectionViewDataSource

View file

@ -52,8 +52,7 @@ final class RoutePreviewTaxiCell: UICollectionViewCell {
let timeString = { () -> String in
let timeValue = DateComponentsFormatter.etaString(from: TimeInterval(eta)!)!
let format = L("taxi_wait").replacingOccurrences(of: "%s", with: "%@")
return String(format: format, arguments: [timeValue])
return String(coreFormat: L("taxi_wait"), arguments: [timeValue])
}
icon.image = iconImage()

View file

@ -190,6 +190,7 @@ static NSString * const kStatNo = @"No";
static NSString * const kStatNoConnection = @"no_connection";
static NSString * const kStatNoSpace = @"no_space";
static NSString * const kStatNone = @"none";
static NSString * const kStatNotToday = @"NotToday";
static NSString * const kStatOSM = @"OSM";
static NSString * const kStatOSMUserName = @"osm_username";
static NSString * const kStatObjectLat = @"object_lat";
@ -318,6 +319,7 @@ static NSString * const kStatTaxi = @"Taxi";
static NSString * const kStatThingsToDo = @"Things to do";
static NSString * const kStatToLocation = @"to_location";
static NSString * const kStatToMyPosition = @"To my position";
static NSString * const kStatToday = @"Today";
static NSString * const kStatToggleBookmark = @"Toggle bookmark";
static NSString * const kStatToggleCompassCalibration = @"Toggle compass calibration";
static NSString * const kStatToggleCoordinates = @"Toggle coordinates";

View file

@ -4,10 +4,19 @@
namespace network_policy
{
enum Stage
{
Ask,
Always,
Never,
Today,
NotToday
};
void CallPartnersApi(platform::PartnersApiFn fn, bool force = false);
void SetStage(platform::NetworkPolicy::Stage state);
platform::NetworkPolicy::Stage GetStage();
void SetStage(Stage state);
Stage const GetStage();
bool CanUseNetwork();
} // namespace network_policy

View file

@ -3,16 +3,34 @@
#include "platform/platform.hpp"
using np = platform::NetworkPolicy;
namespace
{
NSString * const kNetworkingPolicyTimeStamp = @"NetworkingPolicyTimeStamp";
NSString * const kNetworkingPolicyStage = @"NetworkingPolicyStage";
NSTimeInterval const kSessionDurationSeconds = 24 * 60 * 60;
} // namespace
namespace network_policy
{
void SetStage(Stage stage)
{
NSUserDefaults * ud = NSUserDefaults.standardUserDefaults;
[ud setInteger:static_cast<NSInteger>(stage) forKey:kNetworkingPolicyStage];
[ud setObject:[NSDate dateWithTimeIntervalSinceNow:kSessionDurationSeconds]
forKey:kNetworkingPolicyTimeStamp];
}
Stage const GetStage()
{
return static_cast<Stage>(
[NSUserDefaults.standardUserDefaults integerForKey:kNetworkingPolicyStage]);
}
NSDate * GetPolicyDate()
{
return [NSUserDefaults.standardUserDefaults objectForKey:kNetworkingPolicyTimeStamp];
}
void CallPartnersApi(platform::PartnersApiFn fn, bool force)
{
auto const connectionType = GetPlatform().ConnectionStatus();
@ -28,19 +46,26 @@ void CallPartnersApi(platform::PartnersApiFn fn, bool force)
}
auto checkAndApply = ^bool {
NSUserDefaults * ud = NSUserDefaults.standardUserDefaults;
NSDate * policyDate = [ud objectForKey:kNetworkingPolicyTimeStamp];
if ([policyDate compare:[NSDate date]] == NSOrderedDescending)
switch (GetStage())
{
fn(true);
return true;
case Stage::Ask: return false;
case Stage::Always: fn(true); return true;
case Stage::Never: fn(false); return true;
case Stage::Today:
if ([GetPolicyDate() compare:[NSDate date]] == NSOrderedDescending)
{
fn(true);
return true;
}
return false;
case Stage::NotToday:
if ([GetPolicyDate() compare:[NSDate date]] == NSOrderedDescending)
{
fn(false);
return true;
}
return false;
}
if ([policyDate isEqualToDate:NSDate.distantPast])
{
fn(false);
return true;
}
return false;
};
if (checkAndApply())
@ -55,32 +80,6 @@ void CallPartnersApi(platform::PartnersApiFn fn, bool force)
});
}
void SetStage(np::Stage state)
{
NSUserDefaults * ud = NSUserDefaults.standardUserDefaults;
NSDate * policyDate = nil;
switch (state)
{
case np::Stage::Always: policyDate = NSDate.distantFuture; break;
case np::Stage::Session:
policyDate = [NSDate dateWithTimeIntervalSinceNow:kSessionDurationSeconds];
break;
case np::Stage::Never: policyDate = NSDate.distantPast; break;
}
[ud setObject:policyDate forKey:kNetworkingPolicyTimeStamp];
}
np::Stage GetStage()
{
NSUserDefaults * ud = NSUserDefaults.standardUserDefaults;
NSDate * policyDate = [ud objectForKey:kNetworkingPolicyTimeStamp];
if ([policyDate isEqualToDate:NSDate.distantFuture])
return np::Stage::Always;
if ([policyDate isEqualToDate:NSDate.distantPast])
return np::Stage::Never;
return np::Stage::Session;
}
bool CanUseNetwork()
{
using ct = Platform::EConnectionType;
@ -89,11 +88,14 @@ bool CanUseNetwork()
case ct::CONNECTION_NONE: return false;
case ct::CONNECTION_WIFI: return true;
case ct::CONNECTION_WWAN:
{
NSUserDefaults * ud = NSUserDefaults.standardUserDefaults;
NSDate * policyDate = [ud objectForKey:kNetworkingPolicyTimeStamp];
return [policyDate compare:[NSDate date]] == NSOrderedDescending;
}
switch (GetStage())
{
case Stage::Ask: return false;
case Stage::Always: return true;
case Stage::Never: return false;
case Stage::Today: return [GetPolicyDate() compare:[NSDate date]] == NSOrderedDescending;
case Stage::NotToday: return false;
}
}
}
} // namespace network_policy

View file

@ -4,6 +4,7 @@
#import "MWMFrameworkListener.h"
#import "MWMStorage.h"
#import "Statistics.h"
#import "SwiftBridge.h"
#import "UIButton+RuntimeAttributes.h"
#include <unordered_set>
@ -44,7 +45,6 @@ enum class State
- (void)startSpinner;
- (void)stopSpinner;
- (void)setProgress:(MapFilesDownloader::TProgress)progress nodeName:(NSString *)nodeName;
- (void)updateForSize:(CGSize)size;
@end
@ -80,9 +80,9 @@ enum class State
[self stopSpinner];
self.primaryButton.hidden = NO;
self.secondaryButton.localizedText = L(@"whats_new_auto_update_button_later");
NSString * pattern = [L(@"whats_new_auto_update_button_size") stringByReplacingOccurrencesOfString:@"%s"
withString:@"%@"];
self.primaryButton.localizedText = [NSString stringWithFormat:pattern, self.updateSize];
self.primaryButton.localizedText =
[NSString stringWithCoreFormat:L(@"whats_new_auto_update_button_size")
arguments:@[self.updateSize]];
}
- (void)startSpinner
@ -108,32 +108,22 @@ enum class State
- (void)setStatusForNodeName:(NSString *)nodeName rootAttributes:(NodeAttrs const &)nodeAttrs
{
auto updatePlaceholder = ^NSString *(NSString * str)
{
return [str stringByReplacingOccurrencesOfString:@"%s" withString:@"%@"];
};
auto const progress = nodeAttrs.m_downloadingProgress;
CGFloat const prog = kMaxProgress * static_cast<CGFloat>(progress.first) / progress.second;
self.spinner.progress = prog;
NSString * percent =
[L(@"downloader_percent") stringByReplacingOccurrencesOfString:@"%s" withString:@"%@"];
NSNumberFormatter * numberFormatter = [[NSNumberFormatter alloc] init];
[numberFormatter setNumberStyle:NSNumberFormatterPercentStyle];
[numberFormatter setMaximumFractionDigits:0];
[numberFormatter setMultiplier:@100];
NSString * percentString = [numberFormatter stringFromNumber:@(prog)];
NSString * sizeString = formattedSize(progress.second);
self.progressLabel.text = [NSString stringWithFormat:percent, percentString, sizeString];
self.progressLabel.text = [NSString stringWithCoreFormat:L(@"downloader_percent")
arguments:@[percentString, sizeString]];
NSString * process = nil;
if (nodeAttrs.m_status == storage::NodeStatus::Applying)
process = L(@"downloader_applying");
else
process = L(@"downloader_process");
process = [process stringByReplacingOccurrencesOfString:@"%s" withString:@"%@"];
self.legendLabel.text = [NSString stringWithFormat:process, nodeName];
BOOL const isApplying = nodeAttrs.m_status == storage::NodeStatus::Applying;
NSString * format = L(isApplying ? @"downloader_applying" : @"downloader_process");
self.legendLabel.text = [NSString stringWithCoreFormat:format arguments:@[nodeName]];
}
@end

View file

@ -293,32 +293,16 @@ typedef NS_ENUM(NSUInteger, MWMBottomMenuViewCell) {
- (IBAction)discoveryTap
{
auto mode = ^MWMDiscoveryMode (BOOL canUseNetwork) {
return canUseNetwork ? MWMDiscoveryModeOnline : MWMDiscoveryModeOffline;
};
auto const connectionType = GetPlatform().ConnectionStatus();
[Statistics logEvent:kStatDiscoveryButtonOpen
withParameters:@{kStatNetwork: [Statistics connectionTypeToString:connectionType]}];
self.state = self.restoreState;
auto discovery = [MWMDiscoveryController instance];
using namespace network_policy;
auto const canUseNetwork = CanUseNetwork();
if (!canUseNetwork && connectionType == Platform::EConnectionType::CONNECTION_WWAN &&
GetStage() == platform::NetworkPolicy::Stage::Session)
{
[[MWMAlertViewController activeAlertController] presentMobileInternetAlertWithBlock:^{
discovery.mode = mode(CanUseNetwork());
[self.controller.navigationController pushViewController:discovery animated:YES];
}];
return;
}
discovery.mode = mode(canUseNetwork);
[self.controller.navigationController pushViewController:discovery animated:YES];
network_policy::CallPartnersApi([self](auto const & canUseNetwork) {
auto discovery = [MWMDiscoveryController instanceWithConnection:canUseNetwork.CanUse()];
[self.controller.navigationController pushViewController:discovery animated:YES];
});
}
- (IBAction)bookmarksButtonTouchUpInside

View file

@ -1,14 +1,7 @@
#import "MWMViewController.h"
typedef NS_ENUM(NSUInteger, MWMDiscoveryMode)
{
MWMDiscoveryModeOnline,
MWMDiscoveryModeOffline
};
@interface MWMDiscoveryController : MWMViewController
+ (instancetype)instance;
- (void)setMode:(MWMDiscoveryMode)mode;
+ (instancetype)instanceWithConnection:(BOOL)connection;
@end

View file

@ -80,16 +80,17 @@ struct Callback
@property(weak, nonatomic) IBOutlet UITableView * tableView;
@property(nonatomic) MWMDiscoveryTableManager * tableManager;
@property(nonatomic) MWMDiscoveryMode mode;
@property(nonatomic) BOOL canUseNetwork;
@end
@implementation MWMDiscoveryController
+ (instancetype)instance
+ (instancetype)instanceWithConnection:(BOOL)canUseNetwork
{
auto instance = [[MWMDiscoveryController alloc] initWithNibName:self.className bundle:nil];
instance.title = L(@"discovery_button_title");
instance.canUseNetwork = canUseNetwork;
return instance;
}
@ -116,14 +117,14 @@ struct Callback
delegate:self
model:move(callback)];
auto getTypes = [](MWMDiscoveryMode m) -> vector<ItemType> {
if (m == MWMDiscoveryModeOnline)
auto getTypes = [](BOOL canUseNetwork) -> vector<ItemType> {
if (canUseNetwork)
return {ItemType::Hotels, ItemType::Viator, ItemType::Attractions, ItemType::Cafes,
ItemType::LocalExperts};
return {ItemType::Hotels, ItemType::Attractions, ItemType::Cafes};
};
vector<ItemType> types = getTypes(self.mode);
vector<ItemType> types = getTypes(self.canUseNetwork);
[self.tableManager loadItems:types];
ClientParams p;
p.m_itemTypes = move(types);

View file

@ -289,10 +289,7 @@ NSString * const kUserDefaultsLatLonAsDMSKey = @"UserDefaultsLatLonAsDMS";
if (!self.isViator)
return;
if (Platform::ConnectionStatus() == Platform::EConnectionType::CONNECTION_NONE)
return;
network_policy::CallPartnersApi([self](platform::NetworkPolicy const & canUseNetwork) {
network_policy::CallPartnersApi([self](auto const & canUseNetwork) {
auto api = GetFramework().GetViatorApi(canUseNetwork);
if (!api)
return;
@ -346,10 +343,7 @@ NSString * const kUserDefaultsLatLonAsDMSKey = @"UserDefaultsLatLonAsDMS";
if (!self.isBooking)
return;
if (Platform::ConnectionStatus() == Platform::EConnectionType::CONNECTION_NONE)
return;
network_policy::CallPartnersApi([self](platform::NetworkPolicy const & canUseNetwork) {
network_policy::CallPartnersApi([self](auto const & canUseNetwork) {
auto api = GetFramework().GetBookingApi(canUseNetwork);
if (!api)
return;
@ -569,42 +563,38 @@ NSString * const kUserDefaultsLatLonAsDMSKey = @"UserDefaultsLatLonAsDMS";
return;
}
if (Platform::ConnectionStatus() == Platform::EConnectionType::CONNECTION_NONE)
return;
std::string const currency = self.currencyFormatter.currencyCode.UTF8String;
auto const func = [self, label, currency](std::string const & hotelId, std::string const & minPrice,
std::string const & priceCurrency) {
if (currency != priceCurrency)
network_policy::CallPartnersApi([self, label](auto const & canUseNetwork) {
auto const api = GetFramework().GetBookingApi(canUseNetwork);
if (!api)
return;
NSNumberFormatter * decimalFormatter = [[NSNumberFormatter alloc] init];
decimalFormatter.numberStyle = NSNumberFormatterDecimalStyle;
std::string const currency = self.currencyFormatter.currencyCode.UTF8String;
NSNumber * currencyNumber = [decimalFormatter
numberFromString:[@(minPrice.c_str())
stringByReplacingOccurrencesOfString:@"."
withString:decimalFormatter
.decimalSeparator]];
NSString * currencyString = [self.currencyFormatter stringFromNumber:currencyNumber];
auto const func = [self, label, currency](std::string const & hotelId,
std::string const & minPrice,
std::string const & priceCurrency) {
if (currency != priceCurrency)
return;
NSString * pattern =
[L(@"place_page_starting_from") stringByReplacingOccurrencesOfString:@"%s"
withString:@"%@"];
NSNumberFormatter * decimalFormatter = [[NSNumberFormatter alloc] init];
decimalFormatter.numberStyle = NSNumberFormatterDecimalStyle;
self.cachedMinPrice = [NSString stringWithFormat:pattern, currencyString];
dispatch_async(dispatch_get_main_queue(), ^{
label.text = self.cachedMinPrice;
});
};
NSNumber * currencyNumber = [decimalFormatter
numberFromString:[@(minPrice.c_str())
stringByReplacingOccurrencesOfString:@"."
withString:decimalFormatter
.decimalSeparator]];
NSString * currencyString = [self.currencyFormatter stringFromNumber:currencyNumber];
network_policy::CallPartnersApi(
[self, currency, func](platform::NetworkPolicy const & canUseNetwork) {
auto const api = GetFramework().GetBookingApi(canUseNetwork);
if (api)
api->GetMinPrice(self.sponsoredId.UTF8String, currency, func);
self.cachedMinPrice = [NSString stringWithCoreFormat:L(@"place_page_starting_from")
arguments:@[currencyString]];
dispatch_async(dispatch_get_main_queue(), ^{
label.text = self.cachedMinPrice;
});
};
api->GetMinPrice(self.sponsoredId.UTF8String, currency, func);
});
}
- (NSNumberFormatter *)currencyFormatter

View file

@ -25,9 +25,11 @@ using np = platform::NetworkPolicy;
SettingsTableViewSelectableCell * selected;
switch (GetStage())
{
case np::Stage::Always: selected = self.always; break;
case np::Stage::Session: selected = self.ask; break;
case np::Stage::Never: selected = self.never; break;
case Always: selected = self.always; break;
case Never: selected = self.never; break;
case Ask:
case Today:
case NotToday: selected = self.ask; break;
}
selected.accessoryType = UITableViewCellAccessoryCheckmark;
self.selected = selected;
@ -43,17 +45,17 @@ using np = platform::NetworkPolicy;
if ([selected isEqual:self.always])
{
statValue = kStatAlways;
SetStage(np::Stage::Always);
SetStage(Always);
}
else if ([selected isEqual:self.ask])
{
statValue = kStatAsk;
SetStage(np::Stage::Session);
SetStage(Ask);
}
else if ([selected isEqual:self.never])
{
statValue = kStatNever;
SetStage(np::Stage::Never);
SetStage(Never);
}
[Statistics logEvent:kStatMobileInternet withParameters:@{kStatValue : statValue}];

View file

@ -89,16 +89,16 @@ extern NSString * const kAlohalyticsTapEventKey;
isOn:![MWMSettings autoDownloadEnabled]];
NSString * mobileInternet = nil;
using stage = platform::NetworkPolicy::Stage;
switch (network_policy::GetStage())
{
case stage::Always: mobileInternet = L(@"mobile_data_option_always"); break;
case stage::Session: mobileInternet = L(@"mobile_data_option_today"); break;
case stage::Never: mobileInternet = L(@"mobile_data_option_never"); break;
case network_policy::Ask:
case network_policy::Today:
case network_policy::NotToday: mobileInternet = L(@"mobile_data_option_ask"); break;
case network_policy::Always: mobileInternet = L(@"mobile_data_option_always"); break;
case network_policy::Never: mobileInternet = L(@"mobile_data_option_never"); break;
}
[self.mobileInternetCell configWithTitle:L(@"mobile_data") info:mobileInternet];
NSString * recentTrack = nil;
if (!GpsTracker::Instance().IsEnabled())
{

View file

@ -446,7 +446,7 @@
<rect key="frame" x="0.0" y="702.5" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="QNt-XC-xma" id="fBV-aJ-Mo8">
<rect key="frame" x="0.0" y="0.0" width="341" height="43.5"/>
<rect key="frame" x="0.0" y="0.0" width="342" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Ночной режим" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="q7P-cj-3tZ">
@ -549,7 +549,7 @@
<rect key="frame" x="0.0" y="834.5" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="nED-2n-gN6" id="2oQ-0g-poj">
<rect key="frame" x="0.0" y="0.0" width="341" height="43.5"/>
<rect key="frame" x="0.0" y="0.0" width="342" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Голосовые инструкции" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="2v2-mU-aWi">
@ -1580,7 +1580,7 @@
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="string" keyPath="colorName" value="blackPrimaryText"/>
<userDefinedRuntimeAttribute type="string" keyPath="fontName" value="regular17"/>
<userDefinedRuntimeAttribute type="string" keyPath="localizedText" value="mobile_data_option_today"/>
<userDefinedRuntimeAttribute type="string" keyPath="localizedText" value="mobile_data_option_ask"/>
</userDefinedRuntimeAttributes>
</label>
</subviews>

View file

@ -30,13 +30,6 @@ class NetworkPolicy
friend void network_policy::CallPartnersApi(platform::PartnersApiFn fn, bool force);
public:
enum class Stage
{
Always,
Session,
Never
};
bool CanUse() const { return m_canUse; }
private: