diff --git a/iphone/Maps/Bookmarks/BookmarksRootVC.mm b/iphone/Maps/Bookmarks/BookmarksRootVC.mm index 785b1317de..a445c6e7e4 100644 --- a/iphone/Maps/Bookmarks/BookmarksRootVC.mm +++ b/iphone/Maps/Bookmarks/BookmarksRootVC.mm @@ -1,5 +1,6 @@ #import "BookmarksRootVC.h" #import "BookmarksVC.h" +#import "MWMBookmarksManager.h" #import "Statistics.h" #import "UIImageView+Coloring.h" @@ -10,6 +11,8 @@ extern NSString * const kBookmarkCategoryDeletedNotification = @"BookmarkCategoryDeletedNotification"; +@interface BookmarksRootVC () +@end @implementation BookmarksRootVC @@ -21,10 +24,7 @@ extern NSString * const kBookmarkCategoryDeletedNotification = self.title = L(@"bookmarks"); self.tableView.allowsSelectionDuringEditing = YES; - [NSNotificationCenter.defaultCenter addObserver:self - selector:@selector(newCategoryAdded) - name:@"KML file added" - object:nil]; + [MWMBookmarksManager addObserver:self]; } return self; } @@ -302,14 +302,9 @@ extern NSString * const kBookmarkCategoryDeletedNotification = return NO; } --(void)newCategoryAdded -{ - [self.tableView reloadData]; -} +#pragma mark : - MWMBookmarksObserver +- (void)onBookmarksLoadFinished { [self.tableView reloadData]; } --(void)dealloc -{ - [NSNotificationCenter.defaultCenter removeObserver:self]; -} +- (void)onBookmarksFileLoadSuccess { [self.tableView reloadData]; } @end diff --git a/iphone/Maps/Classes/MapViewController.mm b/iphone/Maps/Classes/MapViewController.mm index 0037d57a53..df5f66e44d 100644 --- a/iphone/Maps/Classes/MapViewController.mm +++ b/iphone/Maps/Classes/MapViewController.mm @@ -6,6 +6,7 @@ #import "MWMAuthorizationCommon.h" #import "MWMAuthorizationWebViewLoginViewController.h" #import "MWMAutoupdateController.h" +#import "MWMBookmarksManager.h" #import "MWMCommon.h" #import "MWMEditBookmarkController.h" #import "MWMEditorViewController.h" @@ -354,26 +355,9 @@ BOOL gIsFirstMyPositionMode = YES; // May be better solution would be multiobservers support in the C++ core. [self processMyPositionStateModeEvent:location_helpers::mwmMyPositionMode(mode)]; }); - - // TODO(@igrechuhin): Move it to appropriate place. - BookmarkManager::AsyncLoadingCallbacks bookmarkCallbacks; - //bookmarkCallbacks.m_onStarted = ; - //bookmarkCallbacks.m_onFinished = ; - bookmarkCallbacks.m_onFileSuccess = [](std::string const & filePath, bool isTemporaryFile) - { - //[NSNotificationCenter.defaultCenter postNotificationName:@"KML file added" object:nil]; - //[self showLoadFileAlertIsSuccessful:YES]; - //[Statistics logEvent:kStatEventName(kStatApplication, kStatImport) - // withParameters:@{kStatValue : kStatKML}]; - }; - bookmarkCallbacks.m_onFileError = [](std::string const & filePath, bool isTemporaryFile) - { - //[self showLoadFileAlertIsSuccessful:NO]; - }; self.userTouchesAction = UserTouchesActionNone; - GetFramework().GetBookmarkManager().SetAsyncLoadingCallbacks(std::move(bookmarkCallbacks)); - GetFramework().LoadBookmarks(); + [MWMBookmarksManager loadBookmarks]; [MWMFrameworkListener addObserver:self]; } diff --git a/iphone/Maps/Classes/MapsAppDelegate.h b/iphone/Maps/Classes/MapsAppDelegate.h index dfccdab6cb..17ba59338a 100644 --- a/iphone/Maps/Classes/MapsAppDelegate.h +++ b/iphone/Maps/Classes/MapsAppDelegate.h @@ -4,14 +4,12 @@ @class MapViewController; -@interface MapsAppDelegate - : UIResponder +@interface MapsAppDelegate : UIResponder { NSInteger m_activeDownloadsCounter; UIBackgroundTaskIdentifier m_backgroundTask; UIBackgroundTaskIdentifier m_editorUploadBackgroundTask; UIBackgroundTaskIdentifier m_ugcUploadBackgroundTask; - UIAlertView * m_loadingAlertView; } @property(nonatomic) UIWindow * window; diff --git a/iphone/Maps/Classes/MapsAppDelegate.mm b/iphone/Maps/Classes/MapsAppDelegate.mm index f47e57c211..3eb20dccf5 100644 --- a/iphone/Maps/Classes/MapsAppDelegate.mm +++ b/iphone/Maps/Classes/MapsAppDelegate.mm @@ -539,7 +539,7 @@ using namespace osm_auth_ios; }]; [[Crashlytics sharedInstance] recordError:err]; #endif - + // Global cleanup DeleteFramework(); } @@ -862,23 +862,6 @@ using namespace osm_auth_ios; annotation:annotation]; } -- (void)showLoadFileAlertIsSuccessful:(BOOL)successful -{ - m_loadingAlertView = [[UIAlertView alloc] - initWithTitle:L(@"load_kmz_title") - message:(successful ? L(@"load_kmz_successful") : L(@"load_kmz_failed")) - delegate:nil - cancelButtonTitle:L(@"ok") - otherButtonTitles:nil]; - m_loadingAlertView.delegate = self; - [m_loadingAlertView show]; - [NSTimer scheduledTimerWithTimeInterval:5.0 - target:self - selector:@selector(dismissAlert) - userInfo:nil - repeats:NO]; -} - - (BOOL)checkLaunchURL:(NSURL *)url { NSString * scheme = url.scheme; @@ -903,17 +886,6 @@ using namespace osm_auth_ios; return NO; } -- (void)dismissAlert -{ - if (m_loadingAlertView) - [m_loadingAlertView dismissWithClickedButtonIndex:0 animated:YES]; -} - -- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex -{ - m_loadingAlertView = nil; -} - - (void)showMap { [(UINavigationController *)self.window.rootViewController popToRootViewControllerAnimated:YES]; diff --git a/iphone/Maps/Core/Bookmarks/MWMBookmarksManager.h b/iphone/Maps/Core/Bookmarks/MWMBookmarksManager.h new file mode 100644 index 0000000000..f2ab4f3b88 --- /dev/null +++ b/iphone/Maps/Core/Bookmarks/MWMBookmarksManager.h @@ -0,0 +1,21 @@ +#import "MWMBookmarksObserver.h" + +@interface MWMBookmarksManager : NSObject + ++ (instancetype)manager; + ++ (void)addObserver:(id)observer; ++ (void)removeObserver:(id)observer; + ++ (BOOL)areBookmarksLoaded; ++ (void)loadBookmarks; + +- (instancetype)init __attribute__((unavailable("call +manager instead"))); +- (instancetype)copy __attribute__((unavailable("call +manager instead"))); +- (instancetype)copyWithZone:(NSZone *)zone __attribute__((unavailable("call +manager instead"))); ++ (instancetype)alloc __attribute__((unavailable("call +manager instead"))); ++ (instancetype)allocWithZone:(struct _NSZone *)zone + __attribute__((unavailable("call +manager instead"))); ++ (instancetype) new __attribute__((unavailable("call +manager instead"))); + +@end diff --git a/iphone/Maps/Core/Bookmarks/MWMBookmarksManager.mm b/iphone/Maps/Core/Bookmarks/MWMBookmarksManager.mm new file mode 100644 index 0000000000..a563467bf0 --- /dev/null +++ b/iphone/Maps/Core/Bookmarks/MWMBookmarksManager.mm @@ -0,0 +1,139 @@ +#import "MWMBookmarksManager.h" +#import "Statistics.h" +#import "SwiftBridge.h" + +#include "Framework.h" + +namespace +{ +using Observer = id; +using Observers = NSHashTable; + +using TLoopBlock = void (^)(Observer observer); +} // namespace + +@interface MWMBookmarksManager () + +@property(nonatomic) Observers * observers; +@property(nonatomic) BOOL areBookmarksLoaded; + +@end + +@implementation MWMBookmarksManager + ++ (instancetype)manager +{ + static MWMBookmarksManager * manager; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + manager = [[super alloc] initManager]; + }); + return manager; +} + ++ (void)addObserver:(Observer)observer +{ + dispatch_async(dispatch_get_main_queue(), ^{ + [[MWMBookmarksManager manager].observers addObject:observer]; + }); +} + ++ (void)removeObserver:(Observer)observer +{ + dispatch_async(dispatch_get_main_queue(), ^{ + [[MWMBookmarksManager manager].observers removeObject:observer]; + }); +} + +- (instancetype)initManager +{ + self = [super init]; + if (self) + { + _observers = [Observers weakObjectsHashTable]; + [self registerBookmarksObserver]; + } + return self; +} + +- (void)registerBookmarksObserver +{ + BookmarkManager::AsyncLoadingCallbacks bookmarkCallbacks; + { + __weak auto wSelf = self; + bookmarkCallbacks.m_onStarted = [wSelf]() { + __strong auto self = wSelf; + if (!self) + return; + self.areBookmarksLoaded = NO; + }; + } + { + __weak auto wSelf = self; + bookmarkCallbacks.m_onFinished = [wSelf]() { + __strong auto self = wSelf; + if (!self) + return; + self.areBookmarksLoaded = YES; + [self loopObservers:^(Observer observer) { + if ([observer respondsToSelector:@selector(onBookmarksLoadFinished)]) + [observer onBookmarksLoadFinished]; + }]; + }; + } + { + __weak auto wSelf = self; + bookmarkCallbacks.m_onFileSuccess = [wSelf](std::string const & filePath, + bool isTemporaryFile) { + __strong auto self = wSelf; + if (!self) + return; + [self processFileEvent:YES]; + [self loopObservers:^(Observer observer) { + if ([observer respondsToSelector:@selector(onBookmarksFileLoadSuccess)]) + [observer onBookmarksFileLoadSuccess]; + }]; + [Statistics logEvent:kStatEventName(kStatApplication, kStatImport) + withParameters:@{kStatValue: kStatKML}]; + }; + } + { + __weak auto wSelf = self; + bookmarkCallbacks.m_onFileError = [wSelf](std::string const & filePath, bool isTemporaryFile) { + [wSelf processFileEvent:NO]; + }; + } + GetFramework().GetBookmarkManager().SetAsyncLoadingCallbacks(std::move(bookmarkCallbacks)); +} + ++ (BOOL)areBookmarksLoaded { return [MWMBookmarksManager manager].areBookmarksLoaded; } + ++ (void)loadBookmarks +{ + [MWMBookmarksManager manager]; + GetFramework().LoadBookmarks(); +} + +- (void)loopObservers:(TLoopBlock)block +{ + for (Observer observer in self.observers) + { + if (observer) + block(observer); + } +} + +- (void)processFileEvent:(BOOL)success +{ + UIAlertController * alert = [UIAlertController + alertControllerWithTitle:L(@"load_kmz_title") + message:success ? L(@"load_kmz_successful") : L(@"load_kmz_failed") + preferredStyle:UIAlertControllerStyleAlert]; + UIAlertAction * action = + [UIAlertAction actionWithTitle:L(@"ok") style:UIAlertActionStyleDefault handler:nil]; + [alert addAction:action]; + alert.preferredAction = action; + [[UIViewController topViewController] presentViewController:alert animated:YES completion:nil]; +} + +@end diff --git a/iphone/Maps/Core/Bookmarks/MWMBookmarksObserver.h b/iphone/Maps/Core/Bookmarks/MWMBookmarksObserver.h new file mode 100644 index 0000000000..4c1ce6371a --- /dev/null +++ b/iphone/Maps/Core/Bookmarks/MWMBookmarksObserver.h @@ -0,0 +1,7 @@ +@protocol MWMBookmarksObserver + +@optional +- (void)onBookmarksLoadFinished; +- (void)onBookmarksFileLoadSuccess; + +@end diff --git a/iphone/Maps/Maps.xcodeproj/project.pbxproj b/iphone/Maps/Maps.xcodeproj/project.pbxproj index 52f8ab4b9d..921183b381 100644 --- a/iphone/Maps/Maps.xcodeproj/project.pbxproj +++ b/iphone/Maps/Maps.xcodeproj/project.pbxproj @@ -390,6 +390,9 @@ 346DB83D1E5C4F6700E3123E /* GalleryModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 346DB8261E5C4F6700E3123E /* GalleryModel.swift */; }; 346DB83E1E5C4F6700E3123E /* GalleryModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 346DB8261E5C4F6700E3123E /* GalleryModel.swift */; }; 346EDADB1B9F0E35004F8DB5 /* MWMMultilineLabel.mm in Sources */ = {isa = PBXBuildFile; fileRef = 346EDADA1B9F0E35004F8DB5 /* MWMMultilineLabel.mm */; }; + 347039A81FB9A5CF00E47496 /* MWMBookmarksManager.mm in Sources */ = {isa = PBXBuildFile; fileRef = 347039A71FB9A5CF00E47496 /* MWMBookmarksManager.mm */; }; + 347039A91FB9A5CF00E47496 /* MWMBookmarksManager.mm in Sources */ = {isa = PBXBuildFile; fileRef = 347039A71FB9A5CF00E47496 /* MWMBookmarksManager.mm */; }; + 347039AA1FB9A5CF00E47496 /* MWMBookmarksManager.mm in Sources */ = {isa = PBXBuildFile; fileRef = 347039A71FB9A5CF00E47496 /* MWMBookmarksManager.mm */; }; 3470402F1EA6470700038379 /* BorderedButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3470402E1EA6470700038379 /* BorderedButton.swift */; }; 347040301EA6470700038379 /* BorderedButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3470402E1EA6470700038379 /* BorderedButton.swift */; }; 347040311EA6470700038379 /* BorderedButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3470402E1EA6470700038379 /* BorderedButton.swift */; }; @@ -2065,6 +2068,9 @@ 346DB8261E5C4F6700E3123E /* GalleryModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GalleryModel.swift; sourceTree = ""; }; 346EDAD91B9F0E35004F8DB5 /* MWMMultilineLabel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMMultilineLabel.h; sourceTree = ""; }; 346EDADA1B9F0E35004F8DB5 /* MWMMultilineLabel.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMMultilineLabel.mm; sourceTree = ""; }; + 347039A61FB9A5CF00E47496 /* MWMBookmarksManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MWMBookmarksManager.h; sourceTree = ""; }; + 347039A71FB9A5CF00E47496 /* MWMBookmarksManager.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMBookmarksManager.mm; sourceTree = ""; }; + 347039AB1FB9A97E00E47496 /* MWMBookmarksObserver.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MWMBookmarksObserver.h; sourceTree = ""; }; 3470402E1EA6470700038379 /* BorderedButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BorderedButton.swift; sourceTree = ""; }; 347526FA1DC0B00F00918CF5 /* common-debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "common-debug.xcconfig"; path = "../../xcode/common-debug.xcconfig"; sourceTree = ""; }; 347526FB1DC0B00F00918CF5 /* common-release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "common-release.xcconfig"; path = "../../xcode/common-release.xcconfig"; sourceTree = ""; }; @@ -3204,6 +3210,7 @@ isa = PBXGroup; children = ( 34F4071C1E9E1AFF00E57AC0 /* Ads */, + 347039A51FB9A5B400E47496 /* Bookmarks */, 3486B50F1E27AD3B0069C126 /* Framework */, 340475291E081A4600C92850 /* Location */, 340475301E081A4600C92850 /* NetworkPolicy */, @@ -3616,6 +3623,16 @@ path = Components; sourceTree = ""; }; + 347039A51FB9A5B400E47496 /* Bookmarks */ = { + isa = PBXGroup; + children = ( + 347039A61FB9A5CF00E47496 /* MWMBookmarksManager.h */, + 347039A71FB9A5CF00E47496 /* MWMBookmarksManager.mm */, + 347039AB1FB9A97E00E47496 /* MWMBookmarksObserver.h */, + ); + path = Bookmarks; + sourceTree = ""; + }; 34763EE31F2F392300F4D2D3 /* TextToSpeech */ = { isa = PBXGroup; children = ( @@ -5947,6 +5964,7 @@ 34D3B0351E389D05004100F9 /* MWMEditorSelectTableViewCell.mm in Sources */, F6E2FD8B1E097BA00083EBEC /* MWMNoMapsView.mm in Sources */, F6E2FD701E097BA00083EBEC /* MWMMapDownloaderTableViewCell.mm in Sources */, + 347039A81FB9A5CF00E47496 /* MWMBookmarksManager.mm in Sources */, F6E2FE4E1E097BA00083EBEC /* MWMActionBarButton.mm in Sources */, 34BF0CC61C31304A00D097EB /* MWMAuthorizationCommon.mm in Sources */, 349D1CE31E3F836900A878FD /* UIViewController+Hierarchy.swift in Sources */, @@ -6310,6 +6328,7 @@ F6E2FE4F1E097BA00083EBEC /* MWMActionBarButton.mm in Sources */, 340475531E081A4600C92850 /* MWMCustomFacebookEvents.mm in Sources */, 349D1CE41E3F836900A878FD /* UIViewController+Hierarchy.swift in Sources */, + 347039A91FB9A5CF00E47496 /* MWMBookmarksManager.mm in Sources */, F692F3831EA0FAF5001E82EB /* MWMAutoupdateController.mm in Sources */, 34574A671E3B85F80061E839 /* ThemeManager.swift in Sources */, 34BF0CC71C31304A00D097EB /* MWMAuthorizationCommon.mm in Sources */, @@ -6673,6 +6692,7 @@ 34D3B0371E389D05004100F9 /* MWMEditorSelectTableViewCell.mm in Sources */, 849CF6D51DE842290024A8A5 /* MWMTableViewController.mm in Sources */, F6E2FD8D1E097BA00083EBEC /* MWMNoMapsView.mm in Sources */, + 347039AA1FB9A5CF00E47496 /* MWMBookmarksManager.mm in Sources */, 849CF6D81DE842290024A8A5 /* MWMSegue.mm in Sources */, F6E2FD721E097BA00083EBEC /* MWMMapDownloaderTableViewCell.mm in Sources */, F6E2FE501E097BA00083EBEC /* MWMActionBarButton.mm in Sources */,