forked from organicmaps/organicmaps
[ios] Disabled search in the free version - it displays banner instead.
Search button appears only when it is activated on the server ("redbutton" is pressed)
This commit is contained in:
parent
b64242131d
commit
9714829931
8 changed files with 187 additions and 66 deletions
|
@ -39,5 +39,7 @@
|
|||
- (IBAction)OnSearchClicked:(id)sender;
|
||||
|
||||
@property (nonatomic, retain) IBOutlet UIButton * m_myPositionButton;
|
||||
@property (nonatomic, retain) IBOutlet UIButton * m_searchButton;
|
||||
@property (nonatomic, retain) IBOutlet UIButton * m_downloadButton;
|
||||
|
||||
@end
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
@implementation MapViewController
|
||||
|
||||
@synthesize m_myPositionButton;
|
||||
@synthesize m_searchButton;
|
||||
@synthesize m_downloadButton;
|
||||
|
||||
// @TODO Make m_framework and m_storage MapsAppDelegate properties instead of global variables.
|
||||
Framework * m_framework = NULL;
|
||||
|
@ -328,12 +330,13 @@ NSInteger compareAddress(id l, id r, void * context)
|
|||
m_framework->EnterForeground();
|
||||
if (self.isViewLoaded && self.view.window)
|
||||
[self Invalidate]; // only invalidate when map is displayed on the screen
|
||||
// Perform redbutton check
|
||||
[m_searchBannerChecker checkForBannerAndEnableButton:m_myPositionButton];
|
||||
}
|
||||
|
||||
- (void)viewWillAppear:(BOOL)animated
|
||||
{
|
||||
// Perform redbutton check
|
||||
[m_searchBannerChecker checkForBannerAndFixSearchButton:m_searchButton andDownloadButton:m_downloadButton];
|
||||
|
||||
[self Invalidate];
|
||||
[self.navigationController setNavigationBarHidden:YES animated:YES];
|
||||
[super viewWillAppear:animated];
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
@interface SearchBannerChecker : NSObject
|
||||
{
|
||||
id m_searchButton;
|
||||
id m_downloadButton;
|
||||
}
|
||||
-(void) checkForBannerAndEnableButton:(id)searchButton;
|
||||
-(void) checkForBannerAndFixSearchButton:(id)searchButton
|
||||
andDownloadButton:(id)downloadButton;
|
||||
@end
|
|
@ -1,4 +1,6 @@
|
|||
#import <UIKit/UIButton.h>
|
||||
#import <UIKit/UIAlertView.h>
|
||||
#import <UIKit/UIApplication.h>
|
||||
#import "SearchBannerChecker.h"
|
||||
#import "../../Common/GetActiveConnectionType.h"
|
||||
|
||||
|
@ -41,46 +43,78 @@ static bool ShouldCheckAgain()
|
|||
|
||||
@implementation SearchBannerChecker
|
||||
|
||||
-(void) enableSearchButton:(id)searchButton andDownloadButton:(id)downloadButton
|
||||
{
|
||||
UIButton * sb = (UIButton *)searchButton;
|
||||
UIButton * db = (UIButton *)downloadButton;
|
||||
if (sb.hidden == YES)
|
||||
{
|
||||
// Show Search button and swap them
|
||||
CGRect const sbFrame = sb.frame;
|
||||
CGRect const dbFrame = db.frame;
|
||||
sb.frame = dbFrame;
|
||||
db.frame = sbFrame;
|
||||
sb.hidden = NO;
|
||||
}
|
||||
}
|
||||
|
||||
// Banner dialog handler
|
||||
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
|
||||
{
|
||||
if (buttonIndex != alertView.cancelButtonIndex)
|
||||
{
|
||||
// Launch appstore
|
||||
string bannerUrl;
|
||||
Settings::Get(SETTINGS_REDBUTTON_URL_KEY, bannerUrl);
|
||||
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:[NSString stringWithUTF8String:bannerUrl.c_str()]]];
|
||||
}
|
||||
}
|
||||
|
||||
-(void) onRedbuttonServerReply:(downloader::HttpRequest &) r
|
||||
{
|
||||
if (r.Status() == downloader::HttpRequest::ECompleted
|
||||
&& r.Data().find("http") == 0)
|
||||
&& (r.Data().find("itms") == 0 || r.Data().find("http") == 0))
|
||||
{
|
||||
// Redbutton is activated!!!
|
||||
// 1. Always enable search button
|
||||
// 2. Search button click displays banner
|
||||
// 3. Stop all future requests
|
||||
Settings::Set(SETTINGS_REDBUTTON_URL_KEY, r.Data());
|
||||
UIButton * searchButton = (UIButton *)m_searchButton;
|
||||
if (searchButton.hidden == YES)
|
||||
{
|
||||
searchButton.hidden = NO;
|
||||
// Display banner
|
||||
// @TODO Paid version is available one-time banner dialog for free version
|
||||
// NSLocalizedString(@"A paid version of MapsWithMe, featuring search, is available for download. Would you like to get it now?", @"Paid version has become available one-time dialog title in the free version")
|
||||
// NSLocalizedString(@"Get it now", @"Paid version has become available one-time dialog Positive button in the free version")
|
||||
// NSLocalizedString(@"Cancel", @"Paid version has become available one-time dialog Negative button in the free version")
|
||||
}
|
||||
// Display banner
|
||||
UIAlertView * alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"A paid version of MapsWithMe, featuring search, is available for download. Would you like to get it now?", @"Paid version has become available one-time dialog title in the free version")
|
||||
message:nil
|
||||
delegate:self
|
||||
cancelButtonTitle:NSLocalizedString(@"Cancel", @"Paid version has become available one-time dialog Negative button in the free version")
|
||||
otherButtonTitles:NSLocalizedString(@"Get it now", @"Paid version has become available one-time dialog Positive button in the free version"), nil];
|
||||
[alert show];
|
||||
[alert release];
|
||||
// Display search button
|
||||
[self enableSearchButton:m_searchButton andDownloadButton:m_downloadButton];
|
||||
}
|
||||
|
||||
delete &r;
|
||||
// Save timestamp of the last check
|
||||
uint64_t const secondsNow = (uint64_t)[[NSDate date] timeIntervalSince1970];
|
||||
Settings::Set(SETTINGS_REDBUTTON_LAST_CHECK_TIME, strings::to_string(secondsNow));
|
||||
|
||||
[m_searchButton release];
|
||||
[m_downloadButton release];
|
||||
}
|
||||
|
||||
-(void) checkForBannerAndEnableButton:(id)searchButton
|
||||
-(void) checkForBannerAndFixSearchButton:(id)searchButton
|
||||
andDownloadButton:(id)downloadButton
|
||||
{
|
||||
m_searchButton = searchButton;
|
||||
// Avoid all checks if we already enabled search button
|
||||
if (((UIButton *)searchButton).hidden == NO)
|
||||
return;
|
||||
|
||||
// Check if we alredy should display the button
|
||||
// Check if redbutton was alredy activated and we should display the button
|
||||
string bannerUrl;
|
||||
if (Settings::Get(SETTINGS_REDBUTTON_URL_KEY, bannerUrl)
|
||||
&& bannerUrl.find("http") == 0)
|
||||
&& (bannerUrl.find("itms") == 0 || bannerUrl.find("http") == 0))
|
||||
{
|
||||
// Redbutton is activated. Enable Search button in the UI
|
||||
UIButton * button = (UIButton *)searchButton;
|
||||
button.hidden = NO;
|
||||
[self enableSearchButton:searchButton andDownloadButton:downloadButton];
|
||||
}
|
||||
else // Redbutton still is not activated.
|
||||
{
|
||||
|
@ -88,6 +122,10 @@ static bool ShouldCheckAgain()
|
|||
// and check if WiFi connection is active
|
||||
if (ShouldCheckAgain() && GetActiveConnectionType() == EConnectedByWiFi)
|
||||
{
|
||||
// Save buttons until we get server reply
|
||||
m_searchButton = [searchButton retain];
|
||||
m_downloadButton = [downloadButton retain];
|
||||
|
||||
// Send request to the server
|
||||
// tricky boost::bind for objC class methods
|
||||
typedef void (*OnResultFuncT)(id, SEL, downloader::HttpRequest &);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#import "SearchVC.h"
|
||||
#import "CompassView.h"
|
||||
#import "LocationManager.h"
|
||||
#import "SearchBannerChecker.h"
|
||||
|
||||
#include "../../geometry/angles.hpp"
|
||||
#include "../../geometry/distance_on_sphere.hpp"
|
||||
|
@ -228,18 +229,50 @@ static void OnSearchResultCallback(search::Result const & res, int queryId)
|
|||
[super viewDidUnload];
|
||||
}
|
||||
|
||||
// Banner dialog handler
|
||||
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
|
||||
{
|
||||
if (buttonIndex != alertView.cancelButtonIndex)
|
||||
{
|
||||
// Launch appstore
|
||||
string bannerUrl;
|
||||
Settings::Get(SETTINGS_REDBUTTON_URL_KEY, bannerUrl);
|
||||
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:[NSString stringWithUTF8String:bannerUrl.c_str()]]];
|
||||
}
|
||||
// Close Search view
|
||||
[self dismissModalViewControllerAnimated:YES];
|
||||
}
|
||||
|
||||
- (void)viewWillAppear:(BOOL)animated
|
||||
{
|
||||
// load previously saved search mode
|
||||
string searchMode;
|
||||
if (!Settings::Get(SEARCH_MODE_SETTING, searchMode))
|
||||
searchMode = SEARCH_MODE_DEFAULT;
|
||||
[self setSearchMode:searchMode];
|
||||
{
|
||||
// Disable search for free version
|
||||
NSString * appID = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleIdentifier"];
|
||||
if ([appID compare:@"com.mapswithme.travelguide"] == NSOrderedSame)
|
||||
{
|
||||
// Hide scope bar
|
||||
m_searchBar.showsScopeBar = NO;
|
||||
// Display banner for paid version
|
||||
UIAlertView * alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Search is only available in the full version of MapsWithMe. Would you like to get it now?", @"Search button pressed dialog title in the free version")
|
||||
message:nil
|
||||
delegate:self
|
||||
cancelButtonTitle:NSLocalizedString(@"Cancel", @"Search button pressed dialog Negative button in the free version")
|
||||
otherButtonTitles:NSLocalizedString(@"Get it now", @"Search button pressed dialog Positive button in the free version"), nil];
|
||||
[alert show];
|
||||
[alert release];
|
||||
}
|
||||
else
|
||||
{
|
||||
// load previously saved search mode
|
||||
string searchMode;
|
||||
if (!Settings::Get(SEARCH_MODE_SETTING, searchMode))
|
||||
searchMode = SEARCH_MODE_DEFAULT;
|
||||
[self setSearchMode:searchMode];
|
||||
|
||||
[m_locationManager start:self];
|
||||
[m_locationManager start:self];
|
||||
|
||||
// show keyboard
|
||||
[m_searchBar becomeFirstResponder];
|
||||
// show keyboard
|
||||
[m_searchBar becomeFirstResponder];
|
||||
}
|
||||
|
||||
[super viewWillAppear:animated];
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@
|
|||
<string key="NSFrame">{{10, 435}, {40, 40}}</string>
|
||||
<reference key="NSSuperview" ref="53915144"/>
|
||||
<reference key="NSWindow"/>
|
||||
<reference key="NSNextKeyView" ref="23888313"/>
|
||||
<reference key="NSNextKeyView" ref="773974234"/>
|
||||
<string key="NSReuseIdentifierKey">_NS:222</string>
|
||||
<bool key="IBUIOpaque">NO</bool>
|
||||
<bool key="IBUIClearsContextBeforeDrawing">NO</bool>
|
||||
|
@ -94,11 +94,11 @@
|
|||
</object>
|
||||
<object class="IBUIButton" id="23888313">
|
||||
<reference key="NSNextResponder" ref="53915144"/>
|
||||
<int key="NSvFlags">268</int>
|
||||
<string key="NSFrame">{{60, 435}, {40, 40}}</string>
|
||||
<int key="NSvFlags">-2147483380</int>
|
||||
<string key="NSFrame">{{110, 435}, {40, 40}}</string>
|
||||
<reference key="NSSuperview" ref="53915144"/>
|
||||
<reference key="NSWindow"/>
|
||||
<reference key="NSNextKeyView" ref="773974234"/>
|
||||
<reference key="NSNextKeyView"/>
|
||||
<string key="NSReuseIdentifierKey">_NS:222</string>
|
||||
<bool key="IBUIOpaque">NO</bool>
|
||||
<bool key="IBUIClearsContextBeforeDrawing">NO</bool>
|
||||
|
@ -125,10 +125,10 @@
|
|||
<object class="IBUIButton" id="773974234">
|
||||
<reference key="NSNextResponder" ref="53915144"/>
|
||||
<int key="NSvFlags">268</int>
|
||||
<string key="NSFrame">{{110, 435}, {40, 40}}</string>
|
||||
<string key="NSFrame">{{60, 435}, {40, 40}}</string>
|
||||
<reference key="NSSuperview" ref="53915144"/>
|
||||
<reference key="NSWindow"/>
|
||||
<reference key="NSNextKeyView"/>
|
||||
<reference key="NSNextKeyView" ref="23888313"/>
|
||||
<string key="NSReuseIdentifierKey">_NS:222</string>
|
||||
<bool key="IBUIOpaque">NO</bool>
|
||||
<bool key="IBUIClearsContextBeforeDrawing">NO</bool>
|
||||
|
@ -237,6 +237,22 @@
|
|||
</object>
|
||||
<int key="connectionID">209</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBCocoaTouchOutletConnection" key="connection">
|
||||
<string key="label">m_searchButton</string>
|
||||
<reference key="source" ref="963277495"/>
|
||||
<reference key="destination" ref="23888313"/>
|
||||
</object>
|
||||
<int key="connectionID">214</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBCocoaTouchOutletConnection" key="connection">
|
||||
<string key="label">m_downloadButton</string>
|
||||
<reference key="source" ref="963277495"/>
|
||||
<reference key="destination" ref="773974234"/>
|
||||
</object>
|
||||
<int key="connectionID">215</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBCocoaTouchEventConnection" key="connection">
|
||||
<string key="label">OnMyPositionClicked:</string>
|
||||
|
@ -358,7 +374,7 @@
|
|||
<nil key="activeLocalization"/>
|
||||
<dictionary class="NSMutableDictionary" key="localizations"/>
|
||||
<nil key="sourceID"/>
|
||||
<int key="maxID">213</int>
|
||||
<int key="maxID">215</int>
|
||||
</object>
|
||||
<object class="IBClassDescriber" key="IBDocument.Classes">
|
||||
<array class="NSMutableArray" key="referencedPartialClassDescriptions">
|
||||
|
@ -418,17 +434,25 @@
|
|||
<string key="candidateClassName">id</string>
|
||||
</object>
|
||||
</dictionary>
|
||||
<object class="NSMutableDictionary" key="outlets">
|
||||
<string key="NS.key.0">m_myPositionButton</string>
|
||||
<string key="NS.object.0">UIButton</string>
|
||||
</object>
|
||||
<object class="NSMutableDictionary" key="toOneOutletInfosByName">
|
||||
<string key="NS.key.0">m_myPositionButton</string>
|
||||
<object class="IBToOneOutletInfo" key="NS.object.0">
|
||||
<dictionary class="NSMutableDictionary" key="outlets">
|
||||
<string key="m_downloadButton">UIButton</string>
|
||||
<string key="m_myPositionButton">UIButton</string>
|
||||
<string key="m_searchButton">UIButton</string>
|
||||
</dictionary>
|
||||
<dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
|
||||
<object class="IBToOneOutletInfo" key="m_downloadButton">
|
||||
<string key="name">m_downloadButton</string>
|
||||
<string key="candidateClassName">UIButton</string>
|
||||
</object>
|
||||
<object class="IBToOneOutletInfo" key="m_myPositionButton">
|
||||
<string key="name">m_myPositionButton</string>
|
||||
<string key="candidateClassName">UIButton</string>
|
||||
</object>
|
||||
</object>
|
||||
<object class="IBToOneOutletInfo" key="m_searchButton">
|
||||
<string key="name">m_searchButton</string>
|
||||
<string key="candidateClassName">UIButton</string>
|
||||
</object>
|
||||
</dictionary>
|
||||
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
||||
<string key="majorKey">IBProjectSource</string>
|
||||
<string key="minorKey">./Classes/MapViewController.h</string>
|
||||
|
|
|
@ -65,10 +65,10 @@
|
|||
<object class="IBUIButton" id="68084817">
|
||||
<reference key="NSNextResponder" ref="53915144"/>
|
||||
<int key="NSvFlags">268</int>
|
||||
<string key="NSFrame">{{20, 899}, {44, 44}}</string>
|
||||
<string key="NSFrame">{{22, 899}, {44, 44}}</string>
|
||||
<reference key="NSSuperview" ref="53915144"/>
|
||||
<reference key="NSWindow"/>
|
||||
<reference key="NSNextKeyView" ref="312081333"/>
|
||||
<reference key="NSNextKeyView" ref="832785650"/>
|
||||
<string key="NSReuseIdentifierKey">_NS:237</string>
|
||||
<bool key="IBUIOpaque">NO</bool>
|
||||
<string key="targetRuntimeIdentifier">IBIPadFramework</string>
|
||||
|
@ -112,11 +112,11 @@
|
|||
</object>
|
||||
<object class="IBUIButton" id="312081333">
|
||||
<reference key="NSNextResponder" ref="53915144"/>
|
||||
<int key="NSvFlags">268</int>
|
||||
<string key="NSFrame">{{85, 899}, {44, 44}}</string>
|
||||
<int key="NSvFlags">-2147483380</int>
|
||||
<string key="NSFrame">{{150, 899}, {44, 44}}</string>
|
||||
<reference key="NSSuperview" ref="53915144"/>
|
||||
<reference key="NSWindow"/>
|
||||
<reference key="NSNextKeyView" ref="832785650"/>
|
||||
<reference key="NSNextKeyView"/>
|
||||
<string key="NSReuseIdentifierKey">_NS:237</string>
|
||||
<bool key="IBUIOpaque">NO</bool>
|
||||
<string key="targetRuntimeIdentifier">IBIPadFramework</string>
|
||||
|
@ -142,10 +142,10 @@
|
|||
<object class="IBUIButton" id="832785650">
|
||||
<reference key="NSNextResponder" ref="53915144"/>
|
||||
<int key="NSvFlags">268</int>
|
||||
<string key="NSFrame">{{150, 899}, {44, 44}}</string>
|
||||
<string key="NSFrame">{{86, 899}, {44, 44}}</string>
|
||||
<reference key="NSSuperview" ref="53915144"/>
|
||||
<reference key="NSWindow"/>
|
||||
<reference key="NSNextKeyView"/>
|
||||
<reference key="NSNextKeyView" ref="312081333"/>
|
||||
<string key="NSReuseIdentifierKey">_NS:237</string>
|
||||
<bool key="IBUIOpaque">NO</bool>
|
||||
<string key="targetRuntimeIdentifier">IBIPadFramework</string>
|
||||
|
@ -235,6 +235,22 @@
|
|||
</object>
|
||||
<int key="connectionID">196</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBCocoaTouchOutletConnection" key="connection">
|
||||
<string key="label">m_searchButton</string>
|
||||
<reference key="source" ref="963277495"/>
|
||||
<reference key="destination" ref="312081333"/>
|
||||
</object>
|
||||
<int key="connectionID">198</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBCocoaTouchOutletConnection" key="connection">
|
||||
<string key="label">m_downloadButton</string>
|
||||
<reference key="source" ref="963277495"/>
|
||||
<reference key="destination" ref="832785650"/>
|
||||
</object>
|
||||
<int key="connectionID">199</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBCocoaTouchEventConnection" key="connection">
|
||||
<string key="label">OnMyPositionClicked:</string>
|
||||
|
@ -307,8 +323,8 @@
|
|||
<reference key="object" ref="53915144"/>
|
||||
<array class="NSMutableArray" key="children">
|
||||
<reference ref="68084817"/>
|
||||
<reference ref="832785650"/>
|
||||
<reference ref="312081333"/>
|
||||
<reference ref="832785650"/>
|
||||
</array>
|
||||
<reference key="parent" ref="963277495"/>
|
||||
</object>
|
||||
|
@ -357,7 +373,7 @@
|
|||
<nil key="activeLocalization"/>
|
||||
<dictionary class="NSMutableDictionary" key="localizations"/>
|
||||
<nil key="sourceID"/>
|
||||
<int key="maxID">197</int>
|
||||
<int key="maxID">199</int>
|
||||
</object>
|
||||
<object class="IBClassDescriber" key="IBDocument.Classes">
|
||||
<array class="NSMutableArray" key="referencedPartialClassDescriptions">
|
||||
|
@ -417,17 +433,25 @@
|
|||
<string key="candidateClassName">id</string>
|
||||
</object>
|
||||
</dictionary>
|
||||
<object class="NSMutableDictionary" key="outlets">
|
||||
<string key="NS.key.0">m_myPositionButton</string>
|
||||
<string key="NS.object.0">UIButton</string>
|
||||
</object>
|
||||
<object class="NSMutableDictionary" key="toOneOutletInfosByName">
|
||||
<string key="NS.key.0">m_myPositionButton</string>
|
||||
<object class="IBToOneOutletInfo" key="NS.object.0">
|
||||
<dictionary class="NSMutableDictionary" key="outlets">
|
||||
<string key="m_downloadButton">UIButton</string>
|
||||
<string key="m_myPositionButton">UIButton</string>
|
||||
<string key="m_searchButton">UIButton</string>
|
||||
</dictionary>
|
||||
<dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
|
||||
<object class="IBToOneOutletInfo" key="m_downloadButton">
|
||||
<string key="name">m_downloadButton</string>
|
||||
<string key="candidateClassName">UIButton</string>
|
||||
</object>
|
||||
<object class="IBToOneOutletInfo" key="m_myPositionButton">
|
||||
<string key="name">m_myPositionButton</string>
|
||||
<string key="candidateClassName">UIButton</string>
|
||||
</object>
|
||||
</object>
|
||||
<object class="IBToOneOutletInfo" key="m_searchButton">
|
||||
<string key="name">m_searchButton</string>
|
||||
<string key="candidateClassName">UIButton</string>
|
||||
</object>
|
||||
</dictionary>
|
||||
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
||||
<string key="majorKey">IBProjectSource</string>
|
||||
<string key="minorKey">./Classes/MapViewController.h</string>
|
||||
|
|
|
@ -25,11 +25,6 @@ using namespace storage;
|
|||
// NSLocalizedString(@"Back", @"View and button titles for accessibility")
|
||||
// NSLocalizedString(@"Zoom to the country", @"View and button titles for accessibility")
|
||||
|
||||
// @TODO Search button banner dialog for free version
|
||||
// NSLocalizedString(@"Search is only available in the full version of MapsWithMe. Would you like to get it now?", @"Search button pressed dialog title in the free version")
|
||||
// NSLocalizedString(@"Get it now", @"Search button pressed dialog Positive button in the free version")
|
||||
// NSLocalizedString(@"Cancel", @"Search button pressed dialog Negative button in the free version")
|
||||
|
||||
// Settings are always present globally
|
||||
@implementation SettingsManager
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue