diff --git a/iphone/Maps/Bridging-Header.h b/iphone/Maps/Bridging-Header.h index df86fd1514..7b2d88c6c9 100644 --- a/iphone/Maps/Bridging-Header.h +++ b/iphone/Maps/Bridging-Header.h @@ -20,6 +20,7 @@ #import "private.h" #import "AppInfo.h" +#import "LocalNotificationManager.h" #import "MWMAuthorizationViewModel.h" #import "MWMAvailableAreaAffectDirection.h" #import "MWMBanner.h" @@ -27,6 +28,7 @@ #import "MWMCollectionViewController.h" #import "MWMConsts.h" #import "MWMController.h" +#import "MWMEditorHelper.h" #import "MWMFrameworkHelper.h" #import "MWMKeyboard.h" #import "MWMLocationManager.h" @@ -57,6 +59,7 @@ #import "MWMTextView.h" #import "MWMTrafficButtonViewController.h" #import "MWMTrafficManager.h" +#import "MWMUGCHelper.h" #import "MWMViewController.h" #import "Statistics.h" #import "UIButton+RuntimeAttributes.h" diff --git a/iphone/Maps/Classes/MapsAppDelegate.h b/iphone/Maps/Classes/MapsAppDelegate.h index 17ba59338a..60d24440c1 100644 --- a/iphone/Maps/Classes/MapsAppDelegate.h +++ b/iphone/Maps/Classes/MapsAppDelegate.h @@ -8,8 +8,6 @@ { NSInteger m_activeDownloadsCounter; UIBackgroundTaskIdentifier m_backgroundTask; - UIBackgroundTaskIdentifier m_editorUploadBackgroundTask; - UIBackgroundTaskIdentifier m_ugcUploadBackgroundTask; } @property(nonatomic) UIWindow * window; diff --git a/iphone/Maps/Classes/MapsAppDelegate.mm b/iphone/Maps/Classes/MapsAppDelegate.mm index c46c06d655..7072f153de 100644 --- a/iphone/Maps/Classes/MapsAppDelegate.mm +++ b/iphone/Maps/Classes/MapsAppDelegate.mm @@ -153,6 +153,7 @@ using namespace osm_auth_ios; @interface MapsAppDelegate () @property(nonatomic) NSInteger standbyCounter; +@property(nonatomic) MWMBackgroundFetchScheduler * backgroundFetchScheduler; @end @@ -409,111 +410,28 @@ using namespace osm_auth_ios; completionHandler(YES); } -// Starts async edits uploading process. -+ (void)uploadLocalMapEdits:(void (^)(osm::Editor::UploadResult))finishCallback - with:(osm::TKeySecret const &)keySecret +- (void)runBackgroundTasks:(NSArray * _Nonnull)tasks + completionHandler:(void (^_Nullable)(UIBackgroundFetchResult))completionHandler { - auto const lambda = [finishCallback](osm::Editor::UploadResult result) { - finishCallback(result); + __weak auto wSelf = self; + auto completion = ^(UIBackgroundFetchResult result) { + wSelf.backgroundFetchScheduler = nil; + if (completionHandler) + completionHandler(result); }; - osm::Editor::Instance().UploadChanges( - keySecret.first, keySecret.second, - {{"created_by", - string("MAPS.ME " OMIM_OS_NAME " ") + AppInfo.sharedInfo.bundleVersion.UTF8String}, - {"bundle_id", NSBundle.mainBundle.bundleIdentifier.UTF8String}}, - lambda); -} - -// Starts async UGC uploading process. -+ (void)uploadUGC:(MWMVoidBlock)finishCallback -{ - GetFramework().UploadUGC([finishCallback](bool /* isSuccessful */) { - finishCallback(); - }); + self.backgroundFetchScheduler = + [[MWMBackgroundFetchScheduler alloc] initWithTasks:tasks completionHandler:completion]; + [self.backgroundFetchScheduler run]; } - (void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { - // At the moment, we need to perform 3 asynchronous background tasks simultaneously. - // We will force complete fetch before backgroundTimeRemaining. - // However if all scheduled tasks complete before backgroundTimeRemaining, fetch completes as soon - // as last task finishes. - // fetchResultPriority is used to determine result we must send to fetch completion block. - // Threads synchronization is made through dispatch_async on the main queue. - static NSUInteger fetchRunningTasks; - static UIBackgroundFetchResult fetchResult; - static NSUInteger fetchStamp = 0; - NSUInteger const taskFetchStamp = fetchStamp; - - fetchRunningTasks = 0; - fetchResult = UIBackgroundFetchResultNewData; - - auto const fetchResultPriority = ^NSUInteger(UIBackgroundFetchResult result) { - switch (result) - { - case UIBackgroundFetchResultNewData: return 2; - case UIBackgroundFetchResultNoData: return 1; - case UIBackgroundFetchResultFailed: return 3; - } - }; - auto const callback = ^(UIBackgroundFetchResult result) { - dispatch_async(dispatch_get_main_queue(), ^{ - if (taskFetchStamp != fetchStamp) - return; - if (fetchResultPriority(fetchResult) < fetchResultPriority(result)) - fetchResult = result; - if (--fetchRunningTasks == 0) - { - fetchStamp++; - completionHandler(fetchResult); - } - }); - }; - auto const runFetchTask = ^(MWMVoidBlock task) { - ++fetchRunningTasks; - task(); - }; - - dispatch_time_t const forceCompleteTime = dispatch_time( - DISPATCH_TIME_NOW, static_cast(application.backgroundTimeRemaining) * NSEC_PER_SEC); - dispatch_after(forceCompleteTime, dispatch_get_main_queue(), ^{ - if (taskFetchStamp != fetchStamp) - return; - fetchRunningTasks = 1; - callback(fetchResult); - }); - - // 1. Try to send collected statistics (if any) to our server. - runFetchTask(^{ - [Alohalytics forceUpload:callback]; - }); - // 2. Upload map edits (if any). - if (osm::Editor::Instance().HaveMapEditsOrNotesToUpload() && AuthorizationHaveCredentials()) - { - runFetchTask(^{ - [MapsAppDelegate uploadLocalMapEdits:^(osm::Editor::UploadResult result) { - using UploadResult = osm::Editor::UploadResult; - switch (result) - { - case UploadResult::Success: callback(UIBackgroundFetchResultNewData); break; - case UploadResult::Error: callback(UIBackgroundFetchResultFailed); break; - case UploadResult::NothingToUpload: callback(UIBackgroundFetchResultNoData); break; - } - } - with:AuthorizationGetCredentials()]; - }); - } - // 3. Upload UGC. - runFetchTask(^{ - // Ignore completion callback for now. - [MapsAppDelegate uploadUGC:^{}]; - }); - // 4. Check if map for current location is already downloaded, and if not - notify user to - // download it. - runFetchTask(^{ - [[LocalNotificationManager sharedManager] showDownloadMapNotificationIfNeeded:callback]; - }); + auto tasks = @[ + [[MWMBackgroundStatisticsUpload alloc] init], [[MWMBackgroundEditsUpload alloc] init], + [[MWMBackgroundUGCUpload alloc] init], [[MWMBackgroundDownloadMapNotification alloc] init] + ]; + [self runBackgroundTasks:tasks completionHandler:completionHandler]; } - (void)applicationDidReceiveMemoryWarning:(UIApplication *)application @@ -555,48 +473,10 @@ using namespace osm_auth_ios; self->m_backgroundTask = UIBackgroundTaskInvalid; }]; } - // Upload map edits if any, but only if we have Internet connection and user has already been - // authorized. - if (osm::Editor::Instance().HaveMapEditsOrNotesToUpload() && AuthorizationHaveCredentials() && - Platform::EConnectionType::CONNECTION_NONE != Platform::ConnectionStatus()) - { - void (^finishEditorUploadTaskBlock)() = ^{ - if (self->m_editorUploadBackgroundTask != UIBackgroundTaskInvalid) - { - [application endBackgroundTask:self->m_editorUploadBackgroundTask]; - self->m_editorUploadBackgroundTask = UIBackgroundTaskInvalid; - } - }; - ::dispatch_after(::dispatch_time(DISPATCH_TIME_NOW, - static_cast(application.backgroundTimeRemaining)), - ::dispatch_get_main_queue(), finishEditorUploadTaskBlock); - m_editorUploadBackgroundTask = - [application beginBackgroundTaskWithExpirationHandler:finishEditorUploadTaskBlock]; - [MapsAppDelegate uploadLocalMapEdits:^(osm::Editor::UploadResult /*ignore it here*/) { - finishEditorUploadTaskBlock(); - } - with:AuthorizationGetCredentials()]; - } - - // Upload UGC. All checks are inside the core part. - { - auto finishUGCUploadTaskBlock = ^{ - if (self->m_ugcUploadBackgroundTask != UIBackgroundTaskInvalid) - { - [application endBackgroundTask:self->m_ugcUploadBackgroundTask]; - self->m_ugcUploadBackgroundTask = UIBackgroundTaskInvalid; - } - }; - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, - static_cast(application.backgroundTimeRemaining)), - dispatch_get_main_queue(), finishUGCUploadTaskBlock); - m_ugcUploadBackgroundTask = - [application beginBackgroundTaskWithExpirationHandler:finishUGCUploadTaskBlock]; - [MapsAppDelegate uploadUGC:^{ - finishUGCUploadTaskBlock(); - }]; - } - + + auto tasks = @[[[MWMBackgroundEditsUpload alloc] init], [[MWMBackgroundUGCUpload alloc] init]]; + [self runBackgroundTasks:tasks completionHandler:nil]; + [MWMRouter saveRouteIfNeeded]; LOG(LINFO, ("applicationDidEnterBackground - end")); } diff --git a/iphone/Maps/Core/BackgroundFetchScheduler/BackgroundFetchScheduler.swift b/iphone/Maps/Core/BackgroundFetchScheduler/BackgroundFetchScheduler.swift new file mode 100644 index 0000000000..3d6dedb4db --- /dev/null +++ b/iphone/Maps/Core/BackgroundFetchScheduler/BackgroundFetchScheduler.swift @@ -0,0 +1,88 @@ +@objc(MWMBackgroundFetchScheduler) +final class BackgroundFetchScheduler: NSObject { + typealias FetchResultHandler = (UIBackgroundFetchResult) -> Void + + enum Const { + static let timeoutSafetyIndent: TimeInterval = 1 + } + + private let completionHandler: FetchResultHandler + private let tasks: [BackgroundFetchTask] + private let tasksGroup = DispatchGroup() + private var fetchResult = UIBackgroundFetchResult.noData + + @objc init(tasks: [BackgroundFetchTask], completionHandler: @escaping FetchResultHandler) { + self.tasks = tasks + self.completionHandler = completionHandler + super.init() + } + + @objc func run() { + DispatchQueue.main.async { + self.fullfillFrameworkRequirements() + self.performTasks() + } + } + + private func fullfillFrameworkRequirements() { + minFrameworkTypeRequired().create() + } + + private func minFrameworkTypeRequired() -> BackgroundFetchTaskFrameworkType { + return tasks.reduce(.none) { max($0, $1.frameworkType) } + } + + private func performTasks() { + DispatchQueue.global().async { + self.setCompletionHandlers() + self.startTasks() + self.waitTasks() + } + } + + private func setCompletionHandlers() { + let completionHandler: FetchResultHandler = { [weak self] result in + self?.finishTask(result: result) + } + tasks.forEach { $0.completionHandler = completionHandler } + } + + private func startTasks() { + tasks.forEach { + tasksGroup.enter() + $0.start() + } + } + + private func finishTask(result: UIBackgroundFetchResult) { + updateFetchResult(result) + tasksGroup.leave() + } + + private func waitTasks() { + let timeout = DispatchTime.now() + UIApplication.shared.backgroundTimeRemaining - Const.timeoutSafetyIndent + let groupCompletion = tasksGroup.wait(timeout: timeout) + DispatchQueue.main.async { + switch groupCompletion { + case .success: self.completionHandler(self.fetchResult) + case .timedOut: self.completionHandler(.failed) + } + } + } + + private func updateFetchResult(_ result: UIBackgroundFetchResult) { + DispatchQueue.main.async { + if self.resultPriority(self.fetchResult) < self.resultPriority(result) { + self.fetchResult = result + } + } + } + + private func resultPriority(_ result: UIBackgroundFetchResult) -> Int { + switch result { + case .newData: return 2 + case .noData: return 1 + case .failed: return 3 + } + } +} diff --git a/iphone/Maps/Core/BackgroundFetchScheduler/BackgroundFetchTask/BackgroundDownloadMapNotification.swift b/iphone/Maps/Core/BackgroundFetchScheduler/BackgroundFetchTask/BackgroundDownloadMapNotification.swift new file mode 100644 index 0000000000..a1a20e21c4 --- /dev/null +++ b/iphone/Maps/Core/BackgroundFetchScheduler/BackgroundFetchTask/BackgroundDownloadMapNotification.swift @@ -0,0 +1,9 @@ +@objc(MWMBackgroundDownloadMapNotification) +final class BackgroundDownloadMapNotification: BackgroundFetchTask { + override var queue: DispatchQueue { return .main } + override var frameworkType: BackgroundFetchTaskFrameworkType { return .full } + + override lazy var block = { + LocalNotificationManager.shared().showDownloadMapNotificationIfNeeded(self.finish) + } +} diff --git a/iphone/Maps/Core/BackgroundFetchScheduler/BackgroundFetchTask/BackgroundEditsUpload.swift b/iphone/Maps/Core/BackgroundFetchScheduler/BackgroundFetchTask/BackgroundEditsUpload.swift new file mode 100644 index 0000000000..8ea48abbf2 --- /dev/null +++ b/iphone/Maps/Core/BackgroundFetchScheduler/BackgroundFetchTask/BackgroundEditsUpload.swift @@ -0,0 +1,6 @@ +@objc(MWMBackgroundEditsUpload) +final class BackgroundEditsUpload: BackgroundFetchTask { + override lazy var block = { + MWMEditorHelper.uploadEdits(self.finish) + } +} diff --git a/iphone/Maps/Core/BackgroundFetchScheduler/BackgroundFetchTask/BackgroundFetchTask.swift b/iphone/Maps/Core/BackgroundFetchScheduler/BackgroundFetchTask/BackgroundFetchTask.swift new file mode 100644 index 0000000000..616004dd5d --- /dev/null +++ b/iphone/Maps/Core/BackgroundFetchScheduler/BackgroundFetchTask/BackgroundFetchTask.swift @@ -0,0 +1,25 @@ +@objc class BackgroundFetchTask: NSObject { + var queue: DispatchQueue { return .global() } + var frameworkType: BackgroundFetchTaskFrameworkType { return .none } + + private var backgroundTaskIdentifier = UIBackgroundTaskInvalid + + lazy var block = { self.finish(.failed) } + var completionHandler: BackgroundFetchScheduler.FetchResultHandler! + + func start() { + backgroundTaskIdentifier = UIApplication.shared.beginBackgroundTask(expirationHandler: { + self.finish(.failed) + }) + if backgroundTaskIdentifier != UIBackgroundTaskInvalid { + queue.async(execute: block) + } + } + + func finish(_ result: UIBackgroundFetchResult) { + guard backgroundTaskIdentifier != UIBackgroundTaskInvalid else { return } + UIApplication.shared.endBackgroundTask(backgroundTaskIdentifier) + backgroundTaskIdentifier = UIBackgroundTaskInvalid + completionHandler(result) + } +} diff --git a/iphone/Maps/Core/BackgroundFetchScheduler/BackgroundFetchTask/BackgroundStatisticsUpload.swift b/iphone/Maps/Core/BackgroundFetchScheduler/BackgroundFetchTask/BackgroundStatisticsUpload.swift new file mode 100644 index 0000000000..42b42994fb --- /dev/null +++ b/iphone/Maps/Core/BackgroundFetchScheduler/BackgroundFetchTask/BackgroundStatisticsUpload.swift @@ -0,0 +1,6 @@ +@objc(MWMBackgroundStatisticsUpload) +final class BackgroundStatisticsUpload: BackgroundFetchTask { + override lazy var block = { + Alohalytics.forceUpload(self.finish) + } +} diff --git a/iphone/Maps/Core/BackgroundFetchScheduler/BackgroundFetchTask/BackgroundUGCUpload.swift b/iphone/Maps/Core/BackgroundFetchScheduler/BackgroundFetchTask/BackgroundUGCUpload.swift new file mode 100644 index 0000000000..c1204c1f6f --- /dev/null +++ b/iphone/Maps/Core/BackgroundFetchScheduler/BackgroundFetchTask/BackgroundUGCUpload.swift @@ -0,0 +1,9 @@ +@objc(MWMBackgroundUGCUpload) +final class BackgroundUGCUpload: BackgroundFetchTask { + override var queue: DispatchQueue { return .main } + override var frameworkType: BackgroundFetchTaskFrameworkType { return .full } + + override lazy var block = { + MWMUGCHelper.uploadEdits(self.finish) + } +} diff --git a/iphone/Maps/Core/BackgroundFetchScheduler/BackgroundFetchTaskFrameworkType.swift b/iphone/Maps/Core/BackgroundFetchScheduler/BackgroundFetchTaskFrameworkType.swift new file mode 100644 index 0000000000..8bdaf036d5 --- /dev/null +++ b/iphone/Maps/Core/BackgroundFetchScheduler/BackgroundFetchTaskFrameworkType.swift @@ -0,0 +1,23 @@ +@objc enum BackgroundFetchTaskFrameworkType: Int { + case none + case full + + func create() { + switch self { + case .none: return + case .full: MWMFrameworkHelper.createFramework() + } + } +} + +extension BackgroundFetchTaskFrameworkType: Equatable { + static func ==(lhs: BackgroundFetchTaskFrameworkType, rhs: BackgroundFetchTaskFrameworkType) -> Bool { + return lhs.rawValue == rhs.rawValue + } +} + +extension BackgroundFetchTaskFrameworkType: Comparable { + static func <(lhs: BackgroundFetchTaskFrameworkType, rhs: BackgroundFetchTaskFrameworkType) -> Bool { + return lhs.rawValue < rhs.rawValue + } +} diff --git a/iphone/Maps/Core/Editor/MWMEditorHelper.h b/iphone/Maps/Core/Editor/MWMEditorHelper.h new file mode 100644 index 0000000000..b1384f2f0d --- /dev/null +++ b/iphone/Maps/Core/Editor/MWMEditorHelper.h @@ -0,0 +1,5 @@ +@interface MWMEditorHelper : NSObject + ++ (void)uploadEdits:(void (^)(UIBackgroundFetchResult))completionHandler; + +@end diff --git a/iphone/Maps/Core/Editor/MWMEditorHelper.mm b/iphone/Maps/Core/Editor/MWMEditorHelper.mm new file mode 100644 index 0000000000..6c57b972ac --- /dev/null +++ b/iphone/Maps/Core/Editor/MWMEditorHelper.mm @@ -0,0 +1,44 @@ +#import "MWMEditorHelper.h" +#import "AppInfo.h" +#import "MWMAuthorizationCommon.h" + +#include "platform/platform.hpp" + +#include "indexer/osm_editor.hpp" + +@implementation MWMEditorHelper + ++ (void)uploadEdits:(void (^)(UIBackgroundFetchResult))completionHandler +{ + if (!osm_auth_ios::AuthorizationHaveCredentials() || + Platform::EConnectionType::CONNECTION_NONE == Platform::ConnectionStatus()) + { + completionHandler(UIBackgroundFetchResultFailed); + } + else + { + auto const lambda = [completionHandler](osm::Editor::UploadResult result) { + switch (result) + { + case osm::Editor::UploadResult::Success: + completionHandler(UIBackgroundFetchResultNewData); + break; + case osm::Editor::UploadResult::Error: + completionHandler(UIBackgroundFetchResultFailed); + break; + case osm::Editor::UploadResult::NothingToUpload: + completionHandler(UIBackgroundFetchResultNoData); + break; + } + }; + osm::TKeySecret const keySecret = osm_auth_ios::AuthorizationGetCredentials(); + osm::Editor::Instance().UploadChanges( + keySecret.first, keySecret.second, + {{"created_by", + string("MAPS.ME " OMIM_OS_NAME " ") + AppInfo.sharedInfo.bundleVersion.UTF8String}, + {"bundle_id", NSBundle.mainBundle.bundleIdentifier.UTF8String}}, + lambda); + } +} + +@end diff --git a/iphone/Maps/Core/Framework/MWMFrameworkHelper.h b/iphone/Maps/Core/Framework/MWMFrameworkHelper.h index 8243875988..9b75ca044d 100644 --- a/iphone/Maps/Core/Framework/MWMFrameworkHelper.h +++ b/iphone/Maps/Core/Framework/MWMFrameworkHelper.h @@ -8,4 +8,6 @@ + (MWMDayTime)daytime; ++ (void)createFramework; + @end diff --git a/iphone/Maps/Core/Framework/MWMFrameworkHelper.mm b/iphone/Maps/Core/Framework/MWMFrameworkHelper.mm index 72b7345eb9..ef62b0754e 100644 --- a/iphone/Maps/Core/Framework/MWMFrameworkHelper.mm +++ b/iphone/Maps/Core/Framework/MWMFrameworkHelper.mm @@ -65,4 +65,5 @@ } } ++ (void)createFramework { UNUSED_VALUE(GetFramework()); } @end diff --git a/iphone/Maps/Core/UGC/MWMUGCHelper.h b/iphone/Maps/Core/UGC/MWMUGCHelper.h new file mode 100644 index 0000000000..d1f03265f8 --- /dev/null +++ b/iphone/Maps/Core/UGC/MWMUGCHelper.h @@ -0,0 +1,5 @@ +@interface MWMUGCHelper : NSObject + ++ (void)uploadEdits:(void (^)(UIBackgroundFetchResult))completionHandler; + +@end diff --git a/iphone/Maps/Core/UGC/MWMUGCHelper.mm b/iphone/Maps/Core/UGC/MWMUGCHelper.mm new file mode 100644 index 0000000000..ab41abefef --- /dev/null +++ b/iphone/Maps/Core/UGC/MWMUGCHelper.mm @@ -0,0 +1,17 @@ +#import "MWMUGCHelper.h" + +#include "Framework.h" + +@implementation MWMUGCHelper + ++ (void)uploadEdits:(void (^)(UIBackgroundFetchResult))completionHandler +{ + auto const lambda = [completionHandler](bool isSuccessful) { + completionHandler(isSuccessful ? UIBackgroundFetchResultNewData + : UIBackgroundFetchResultFailed); + }; + + GetFramework().UploadUGC(lambda); +} + +@end diff --git a/iphone/Maps/Maps.xcodeproj/project.pbxproj b/iphone/Maps/Maps.xcodeproj/project.pbxproj index bf4912f502..4f838df92a 100644 --- a/iphone/Maps/Maps.xcodeproj/project.pbxproj +++ b/iphone/Maps/Maps.xcodeproj/project.pbxproj @@ -348,6 +348,33 @@ 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 */; }; + 3472B5CA200F43EF00DC6CD5 /* BackgroundFetchScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3472B5C9200F43EF00DC6CD5 /* BackgroundFetchScheduler.swift */; }; + 3472B5CB200F43EF00DC6CD5 /* BackgroundFetchScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3472B5C9200F43EF00DC6CD5 /* BackgroundFetchScheduler.swift */; }; + 3472B5CC200F43EF00DC6CD5 /* BackgroundFetchScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3472B5C9200F43EF00DC6CD5 /* BackgroundFetchScheduler.swift */; }; + 3472B5CE200F4A2B00DC6CD5 /* BackgroundFetchTask.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3472B5CD200F4A2B00DC6CD5 /* BackgroundFetchTask.swift */; }; + 3472B5CF200F4A2B00DC6CD5 /* BackgroundFetchTask.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3472B5CD200F4A2B00DC6CD5 /* BackgroundFetchTask.swift */; }; + 3472B5D0200F4A2B00DC6CD5 /* BackgroundFetchTask.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3472B5CD200F4A2B00DC6CD5 /* BackgroundFetchTask.swift */; }; + 3472B5D2200F501500DC6CD5 /* BackgroundFetchTaskFrameworkType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3472B5D1200F501500DC6CD5 /* BackgroundFetchTaskFrameworkType.swift */; }; + 3472B5D3200F501500DC6CD5 /* BackgroundFetchTaskFrameworkType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3472B5D1200F501500DC6CD5 /* BackgroundFetchTaskFrameworkType.swift */; }; + 3472B5D4200F501500DC6CD5 /* BackgroundFetchTaskFrameworkType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3472B5D1200F501500DC6CD5 /* BackgroundFetchTaskFrameworkType.swift */; }; + 3472B5D6200F61E900DC6CD5 /* BackgroundStatisticsUpload.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3472B5D5200F61E900DC6CD5 /* BackgroundStatisticsUpload.swift */; }; + 3472B5D7200F61E900DC6CD5 /* BackgroundStatisticsUpload.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3472B5D5200F61E900DC6CD5 /* BackgroundStatisticsUpload.swift */; }; + 3472B5D8200F61E900DC6CD5 /* BackgroundStatisticsUpload.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3472B5D5200F61E900DC6CD5 /* BackgroundStatisticsUpload.swift */; }; + 3472B5DA200F7C1000DC6CD5 /* BackgroundEditsUpload.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3472B5D9200F7C1000DC6CD5 /* BackgroundEditsUpload.swift */; }; + 3472B5DB200F7C1000DC6CD5 /* BackgroundEditsUpload.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3472B5D9200F7C1000DC6CD5 /* BackgroundEditsUpload.swift */; }; + 3472B5DC200F7C1000DC6CD5 /* BackgroundEditsUpload.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3472B5D9200F7C1000DC6CD5 /* BackgroundEditsUpload.swift */; }; + 3472B5E0200F86C800DC6CD5 /* MWMEditorHelper.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3472B5DF200F86C800DC6CD5 /* MWMEditorHelper.mm */; }; + 3472B5E1200F86C800DC6CD5 /* MWMEditorHelper.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3472B5DF200F86C800DC6CD5 /* MWMEditorHelper.mm */; }; + 3472B5E2200F86C800DC6CD5 /* MWMEditorHelper.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3472B5DF200F86C800DC6CD5 /* MWMEditorHelper.mm */; }; + 3472B5EA200F8CFF00DC6CD5 /* MWMUGCHelper.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3472B5E9200F8CFF00DC6CD5 /* MWMUGCHelper.mm */; }; + 3472B5EB200F8CFF00DC6CD5 /* MWMUGCHelper.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3472B5E9200F8CFF00DC6CD5 /* MWMUGCHelper.mm */; }; + 3472B5EC200F8CFF00DC6CD5 /* MWMUGCHelper.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3472B5E9200F8CFF00DC6CD5 /* MWMUGCHelper.mm */; }; + 3472B5EE200F8F7600DC6CD5 /* BackgroundUGCUpload.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3472B5ED200F8F7600DC6CD5 /* BackgroundUGCUpload.swift */; }; + 3472B5EF200F8F7600DC6CD5 /* BackgroundUGCUpload.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3472B5ED200F8F7600DC6CD5 /* BackgroundUGCUpload.swift */; }; + 3472B5F0200F8F7600DC6CD5 /* BackgroundUGCUpload.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3472B5ED200F8F7600DC6CD5 /* BackgroundUGCUpload.swift */; }; + 3472B5F2200F906800DC6CD5 /* BackgroundDownloadMapNotification.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3472B5F1200F906800DC6CD5 /* BackgroundDownloadMapNotification.swift */; }; + 3472B5F3200F906800DC6CD5 /* BackgroundDownloadMapNotification.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3472B5F1200F906800DC6CD5 /* BackgroundDownloadMapNotification.swift */; }; + 3472B5F4200F906800DC6CD5 /* BackgroundDownloadMapNotification.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3472B5F1200F906800DC6CD5 /* BackgroundDownloadMapNotification.swift */; }; 34763EE61F2F392300F4D2D3 /* MWMTextToSpeech.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34763EE51F2F392300F4D2D3 /* MWMTextToSpeech.mm */; }; 34763EE71F2F392300F4D2D3 /* MWMTextToSpeech.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34763EE51F2F392300F4D2D3 /* MWMTextToSpeech.mm */; }; 34763EE81F2F392300F4D2D3 /* MWMTextToSpeech.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34763EE51F2F392300F4D2D3 /* MWMTextToSpeech.mm */; }; @@ -2150,6 +2177,17 @@ 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 = ""; }; + 3472B5C9200F43EF00DC6CD5 /* BackgroundFetchScheduler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackgroundFetchScheduler.swift; sourceTree = ""; }; + 3472B5CD200F4A2B00DC6CD5 /* BackgroundFetchTask.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackgroundFetchTask.swift; sourceTree = ""; }; + 3472B5D1200F501500DC6CD5 /* BackgroundFetchTaskFrameworkType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackgroundFetchTaskFrameworkType.swift; sourceTree = ""; }; + 3472B5D5200F61E900DC6CD5 /* BackgroundStatisticsUpload.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackgroundStatisticsUpload.swift; sourceTree = ""; }; + 3472B5D9200F7C1000DC6CD5 /* BackgroundEditsUpload.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackgroundEditsUpload.swift; sourceTree = ""; }; + 3472B5DE200F86C800DC6CD5 /* MWMEditorHelper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MWMEditorHelper.h; sourceTree = ""; }; + 3472B5DF200F86C800DC6CD5 /* MWMEditorHelper.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMEditorHelper.mm; sourceTree = ""; }; + 3472B5E8200F8CFF00DC6CD5 /* MWMUGCHelper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MWMUGCHelper.h; sourceTree = ""; }; + 3472B5E9200F8CFF00DC6CD5 /* MWMUGCHelper.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMUGCHelper.mm; sourceTree = ""; }; + 3472B5ED200F8F7600DC6CD5 /* BackgroundUGCUpload.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackgroundUGCUpload.swift; sourceTree = ""; }; + 3472B5F1200F906800DC6CD5 /* BackgroundDownloadMapNotification.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackgroundDownloadMapNotification.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 = ""; }; 34763EE41F2F392300F4D2D3 /* MWMTextToSpeech.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMTextToSpeech.h; sourceTree = ""; }; @@ -3358,6 +3396,9 @@ 340475281E081A4600C92850 /* Core */ = { isa = PBXGroup; children = ( + 3472B5E7200F8CEB00DC6CD5 /* UGC */, + 3472B5DD200F868E00DC6CD5 /* Editor */, + 3472B5C8200F436700DC6CD5 /* BackgroundFetchScheduler */, 34F4071C1E9E1AFF00E57AC0 /* Ads */, 347039A51FB9A5B400E47496 /* Bookmarks */, 3486B50F1E27AD3B0069C126 /* Framework */, @@ -3762,6 +3803,46 @@ path = Bookmarks; sourceTree = ""; }; + 3472B5C8200F436700DC6CD5 /* BackgroundFetchScheduler */ = { + isa = PBXGroup; + children = ( + 3472B5E6200F8CAB00DC6CD5 /* BackgroundFetchTask */, + 3472B5C9200F43EF00DC6CD5 /* BackgroundFetchScheduler.swift */, + 3472B5D1200F501500DC6CD5 /* BackgroundFetchTaskFrameworkType.swift */, + ); + path = BackgroundFetchScheduler; + sourceTree = ""; + }; + 3472B5DD200F868E00DC6CD5 /* Editor */ = { + isa = PBXGroup; + children = ( + 3472B5DE200F86C800DC6CD5 /* MWMEditorHelper.h */, + 3472B5DF200F86C800DC6CD5 /* MWMEditorHelper.mm */, + ); + path = Editor; + sourceTree = ""; + }; + 3472B5E6200F8CAB00DC6CD5 /* BackgroundFetchTask */ = { + isa = PBXGroup; + children = ( + 3472B5CD200F4A2B00DC6CD5 /* BackgroundFetchTask.swift */, + 3472B5D5200F61E900DC6CD5 /* BackgroundStatisticsUpload.swift */, + 3472B5D9200F7C1000DC6CD5 /* BackgroundEditsUpload.swift */, + 3472B5ED200F8F7600DC6CD5 /* BackgroundUGCUpload.swift */, + 3472B5F1200F906800DC6CD5 /* BackgroundDownloadMapNotification.swift */, + ); + path = BackgroundFetchTask; + sourceTree = ""; + }; + 3472B5E7200F8CEB00DC6CD5 /* UGC */ = { + isa = PBXGroup; + children = ( + 3472B5E8200F8CFF00DC6CD5 /* MWMUGCHelper.h */, + 3472B5E9200F8CFF00DC6CD5 /* MWMUGCHelper.mm */, + ); + path = UGC; + sourceTree = ""; + }; 34763EE31F2F392300F4D2D3 /* TextToSpeech */ = { isa = PBXGroup; children = ( @@ -6095,6 +6176,7 @@ 3454D7B81E07F045004AF2AD /* CALayer+RuntimeAttributes.mm in Sources */, 3408963E1F83CEDE00BC7117 /* MWMAuthorizationViewModel.mm in Sources */, F6E2FE1E1E097BA00083EBEC /* MWMOpeningHoursCommon.mm in Sources */, + 3472B5DA200F7C1000DC6CD5 /* BackgroundEditsUpload.swift in Sources */, F6BC1E521ACBF98600EF0360 /* MWMFacebookAlert.mm in Sources */, 34AB66641FC5AA330078E451 /* TransportTransitTrain.swift in Sources */, F6E2FF5C1E097BA00083EBEC /* MWMRecentTrackSettingsController.mm in Sources */, @@ -6102,6 +6184,7 @@ 348B926C1FF3B5E100379009 /* UIView+Animation.swift in Sources */, F6664BF91E6459CB00E703C2 /* PPFacilityCell.swift in Sources */, 347E1A8D1F1F71F1002BF7A8 /* PPCianCarouselCell.swift in Sources */, + 3472B5EE200F8F7600DC6CD5 /* BackgroundUGCUpload.swift in Sources */, F6E2FDE81E097BA00083EBEC /* MWMObjectsCategorySelectorController.mm in Sources */, 34AB665E1FC5AA330078E451 /* TransportTransitIntermediatePoint.swift in Sources */, F64F199D1AB81A00006EAF7E /* MWMDefaultAlert.mm in Sources */, @@ -6216,6 +6299,7 @@ F6558DA11E642CC0002203AE /* MWMFacilitiesController.mm in Sources */, 347E1A881F1F5DD7002BF7A8 /* CianItemModel.swift in Sources */, F6E2FF471E097BA00083EBEC /* SettingsTableViewSelectableCell.swift in Sources */, + 3472B5F2200F906800DC6CD5 /* BackgroundDownloadMapNotification.swift in Sources */, F6550C1E1FD81B3800352D88 /* RatingSummaryView+DefaultConfig.swift in Sources */, 349D1ACE1E2E325B004A2006 /* MWMBottomMenuCollectionViewCell.mm in Sources */, F6E2FF261E097BA00083EBEC /* MWMSearchTabButtonsView.mm in Sources */, @@ -6265,6 +6349,7 @@ F6FEA82D1C58E89B007223CC /* MWMButton.mm in Sources */, 348A8DFA1F66775A00D83026 /* RatingViewSettings.swift in Sources */, 34F407401E9E1AFF00E57AC0 /* RBBanner.swift in Sources */, + 3472B5E0200F86C800DC6CD5 /* MWMEditorHelper.mm in Sources */, 3444DFD11F17620C00E73099 /* MWMMapWidgetsHelper.mm in Sources */, F6E2FE3C1E097BA00083EBEC /* MWMMigrationViewController.mm in Sources */, F6E2FD4F1E097BA00083EBEC /* MWMMapDownloaderAdsTableViewCell.mm in Sources */, @@ -6295,8 +6380,10 @@ F6E2FE7B1E097BA00083EBEC /* MWMPlacePageOpeningHoursCell.mm in Sources */, 34E776321F15FAC2003040B3 /* MWMPlacePageManagerHelper.mm in Sources */, F6E2FF351E097BA00083EBEC /* MWMSearchSuggestionCell.mm in Sources */, + 3472B5CE200F4A2B00DC6CD5 /* BackgroundFetchTask.swift in Sources */, F6E2FE391E097BA00083EBEC /* MWMMigrationView.mm in Sources */, F6E2FF3B1E097BA00083EBEC /* MWMSearchTableView.mm in Sources */, + 3472B5EA200F8CFF00DC6CD5 /* MWMUGCHelper.mm in Sources */, F6E2FF651E097BA00083EBEC /* MWMTTSSettingsViewController.mm in Sources */, F6381BF51CD12045004CA943 /* LocaleTranslator.mm in Sources */, 346DB82D1E5C4F6700E3123E /* GalleryItemViewController.swift in Sources */, @@ -6317,6 +6404,8 @@ 340416571E7C0D4100E2B6D6 /* PhotosOverlayView.swift in Sources */, F6E2FD6A1E097BA00083EBEC /* MWMMapDownloaderSubplaceTableViewCell.mm in Sources */, 3409D50A1FC6D8D2000F9B3E /* FilterCheckCell.swift in Sources */, + 3472B5CA200F43EF00DC6CD5 /* BackgroundFetchScheduler.swift in Sources */, + 3472B5D6200F61E900DC6CD5 /* BackgroundStatisticsUpload.swift in Sources */, FAA614B8155F16950031C345 /* AddSetVC.mm in Sources */, F6E2FF681E097BA00083EBEC /* MWMUnitsController.mm in Sources */, 34FE5A6E1F18F30F00BCA729 /* TrafficButtonArea.swift in Sources */, @@ -6359,6 +6448,7 @@ 3477528F1F7251C7000D46A3 /* UGCAddReviewTextCell.swift in Sources */, 34E50DEF1F6FCC41008EED49 /* UGCYourReviewCell.swift in Sources */, 34AB66371FC5AA330078E451 /* RouteManagerCell.swift in Sources */, + 3472B5D2200F501500DC6CD5 /* BackgroundFetchTaskFrameworkType.swift in Sources */, F6E2FF231E097BA00083EBEC /* MWMSearchTabbedViewLayout.mm in Sources */, F6E2FF1D1E097BA00083EBEC /* MWMSearchTabbedViewController.mm in Sources */, F6E2FF2F1E097BA00083EBEC /* MWMSearchCommonCell.mm in Sources */, @@ -6479,6 +6569,7 @@ 3408963F1F83CEDE00BC7117 /* MWMAuthorizationViewModel.mm in Sources */, F6E2FE1F1E097BA00083EBEC /* MWMOpeningHoursCommon.mm in Sources */, 3454D7B91E07F045004AF2AD /* CALayer+RuntimeAttributes.mm in Sources */, + 3472B5DB200F7C1000DC6CD5 /* BackgroundEditsUpload.swift in Sources */, F6E2FF5D1E097BA00083EBEC /* MWMRecentTrackSettingsController.mm in Sources */, 34AB66651FC5AA330078E451 /* TransportTransitTrain.swift in Sources */, 343064411E9FDC7300DC7665 /* SearchIndex.swift in Sources */, @@ -6486,6 +6577,7 @@ 348B926D1FF3B5E100379009 /* UIView+Animation.swift in Sources */, 347E1A8E1F1F71F1002BF7A8 /* PPCianCarouselCell.swift in Sources */, F6E2FDE91E097BA00083EBEC /* MWMObjectsCategorySelectorController.mm in Sources */, + 3472B5EF200F8F7600DC6CD5 /* BackgroundUGCUpload.swift in Sources */, 6741A9A81BF340DE002C974C /* MWMFacebookAlert.mm in Sources */, 34AB665F1FC5AA330078E451 /* TransportTransitIntermediatePoint.swift in Sources */, 348A8DF51F66775A00D83026 /* RatingView.swift in Sources */, @@ -6600,6 +6692,7 @@ 347E1A891F1F5DD7002BF7A8 /* CianItemModel.swift in Sources */, F6E2FF451E097BA00083EBEC /* SettingsTableViewLinkCell.swift in Sources */, 34C9BD0A1C6DBCDA000DC38D /* MWMNavigationController.mm in Sources */, + 3472B5F3200F906800DC6CD5 /* BackgroundDownloadMapNotification.swift in Sources */, F6550C1F1FD81B3800352D88 /* RatingSummaryView+DefaultConfig.swift in Sources */, F6E2FE311E097BA00083EBEC /* MWMStreetEditorViewController.mm in Sources */, F6E2FE281E097BA00083EBEC /* MWMOpeningHoursSection.mm in Sources */, @@ -6649,6 +6742,7 @@ 34F407411E9E1AFF00E57AC0 /* RBBanner.swift in Sources */, 3444DFD21F17620C00E73099 /* MWMMapWidgetsHelper.mm in Sources */, 348A8DFB1F66775A00D83026 /* RatingViewSettings.swift in Sources */, + 3472B5E1200F86C800DC6CD5 /* MWMEditorHelper.mm in Sources */, F6E2FE3D1E097BA00083EBEC /* MWMMigrationViewController.mm in Sources */, F6E2FD501E097BA00083EBEC /* MWMMapDownloaderAdsTableViewCell.mm in Sources */, F6E2FE881E097BA00083EBEC /* MWMPlacePageRegularCell.mm in Sources */, @@ -6679,8 +6773,10 @@ 34E776331F15FAC2003040B3 /* MWMPlacePageManagerHelper.mm in Sources */, F6E2FF361E097BA00083EBEC /* MWMSearchSuggestionCell.mm in Sources */, F6E2FE3A1E097BA00083EBEC /* MWMMigrationView.mm in Sources */, + 3472B5CF200F4A2B00DC6CD5 /* BackgroundFetchTask.swift in Sources */, F6E2FF3C1E097BA00083EBEC /* MWMSearchTableView.mm in Sources */, F6E2FF661E097BA00083EBEC /* MWMTTSSettingsViewController.mm in Sources */, + 3472B5EB200F8CFF00DC6CD5 /* MWMUGCHelper.mm in Sources */, 3454D7C21E07F045004AF2AD /* NSString+Categories.mm in Sources */, 6741A9FE1BF340DE002C974C /* SelectSetVC.mm in Sources */, 34E7761F1F14DB48003040B3 /* PlacePageArea.swift in Sources */, @@ -6701,6 +6797,8 @@ F6E2FE821E097BA00083EBEC /* MWMPlacePageOpeningHoursDayView.mm in Sources */, F6E2FD6B1E097BA00083EBEC /* MWMMapDownloaderSubplaceTableViewCell.mm in Sources */, 3409D50B1FC6D8D2000F9B3E /* FilterCheckCell.swift in Sources */, + 3472B5CB200F43EF00DC6CD5 /* BackgroundFetchScheduler.swift in Sources */, + 3472B5D7200F61E900DC6CD5 /* BackgroundStatisticsUpload.swift in Sources */, 6741AA021BF340DE002C974C /* BookmarksRootVC.mm in Sources */, 34FE5A6F1F18F30F00BCA729 /* TrafficButtonArea.swift in Sources */, F6E2FF691E097BA00083EBEC /* MWMUnitsController.mm in Sources */, @@ -6743,6 +6841,7 @@ 347752901F7251C7000D46A3 /* UGCAddReviewTextCell.swift in Sources */, 34E50DF01F6FCC41008EED49 /* UGCYourReviewCell.swift in Sources */, 34AB66381FC5AA330078E451 /* RouteManagerCell.swift in Sources */, + 3472B5D3200F501500DC6CD5 /* BackgroundFetchTaskFrameworkType.swift in Sources */, F6E2FF241E097BA00083EBEC /* MWMSearchTabbedViewLayout.mm in Sources */, F6E2FF1E1E097BA00083EBEC /* MWMSearchTabbedViewController.mm in Sources */, F6E2FF301E097BA00083EBEC /* MWMSearchCommonCell.mm in Sources */, @@ -6863,6 +6962,7 @@ 340896401F83CEDE00BC7117 /* MWMAuthorizationViewModel.mm in Sources */, 849CF6841DE842290024A8A5 /* MWMShareActivityItem.mm in Sources */, F6E2FE201E097BA00083EBEC /* MWMOpeningHoursCommon.mm in Sources */, + 3472B5DC200F7C1000DC6CD5 /* BackgroundEditsUpload.swift in Sources */, 849CF6891DE842290024A8A5 /* MWMFacebookAlert.mm in Sources */, 34AB66661FC5AA330078E451 /* TransportTransitTrain.swift in Sources */, F6E2FF5E1E097BA00083EBEC /* MWMRecentTrackSettingsController.mm in Sources */, @@ -6870,6 +6970,7 @@ 348B926E1FF3B5E100379009 /* UIView+Animation.swift in Sources */, F6664BFB1E6459CB00E703C2 /* PPFacilityCell.swift in Sources */, 347E1A8F1F1F71F1002BF7A8 /* PPCianCarouselCell.swift in Sources */, + 3472B5F0200F8F7600DC6CD5 /* BackgroundUGCUpload.swift in Sources */, F6E2FDEA1E097BA00083EBEC /* MWMObjectsCategorySelectorController.mm in Sources */, 34AB66601FC5AA330078E451 /* TransportTransitIntermediatePoint.swift in Sources */, 849CF68A1DE842290024A8A5 /* MWMDefaultAlert.mm in Sources */, @@ -6984,6 +7085,7 @@ F6558DA31E642CC0002203AE /* MWMFacilitiesController.mm in Sources */, 347E1A8A1F1F5DD7002BF7A8 /* CianItemModel.swift in Sources */, F6E2FF491E097BA00083EBEC /* SettingsTableViewSelectableCell.swift in Sources */, + 3472B5F4200F906800DC6CD5 /* BackgroundDownloadMapNotification.swift in Sources */, F6550C201FD81B3800352D88 /* RatingSummaryView+DefaultConfig.swift in Sources */, 349D1AD01E2E325B004A2006 /* MWMBottomMenuCollectionViewCell.mm in Sources */, F6E2FF281E097BA00083EBEC /* MWMSearchTabButtonsView.mm in Sources */, @@ -7033,6 +7135,7 @@ 849CF6E91DE842290024A8A5 /* MWMCircularProgressView.mm in Sources */, 34F407421E9E1AFF00E57AC0 /* RBBanner.swift in Sources */, 348A8DFC1F66775A00D83026 /* RatingViewSettings.swift in Sources */, + 3472B5E2200F86C800DC6CD5 /* MWMEditorHelper.mm in Sources */, 3444DFD31F17620C00E73099 /* MWMMapWidgetsHelper.mm in Sources */, F6E2FE3E1E097BA00083EBEC /* MWMMigrationViewController.mm in Sources */, F6E2FD511E097BA00083EBEC /* MWMMapDownloaderAdsTableViewCell.mm in Sources */, @@ -7063,8 +7166,10 @@ F6E2FE7D1E097BA00083EBEC /* MWMPlacePageOpeningHoursCell.mm in Sources */, 34E776341F15FAC2003040B3 /* MWMPlacePageManagerHelper.mm in Sources */, F6E2FF371E097BA00083EBEC /* MWMSearchSuggestionCell.mm in Sources */, + 3472B5D0200F4A2B00DC6CD5 /* BackgroundFetchTask.swift in Sources */, F6E2FE3B1E097BA00083EBEC /* MWMMigrationView.mm in Sources */, F6E2FF3D1E097BA00083EBEC /* MWMSearchTableView.mm in Sources */, + 3472B5EC200F8CFF00DC6CD5 /* MWMUGCHelper.mm in Sources */, F6E2FF671E097BA00083EBEC /* MWMTTSSettingsViewController.mm in Sources */, 3454D7D81E07F045004AF2AD /* UIKitCategories.mm in Sources */, 346DB82F1E5C4F6700E3123E /* GalleryItemViewController.swift in Sources */, @@ -7085,6 +7190,8 @@ F6E2FE831E097BA00083EBEC /* MWMPlacePageOpeningHoursDayView.mm in Sources */, 340416591E7C0D4100E2B6D6 /* PhotosOverlayView.swift in Sources */, 3409D50C1FC6D8D2000F9B3E /* FilterCheckCell.swift in Sources */, + 3472B5CC200F43EF00DC6CD5 /* BackgroundFetchScheduler.swift in Sources */, + 3472B5D8200F61E900DC6CD5 /* BackgroundStatisticsUpload.swift in Sources */, F6E2FD6C1E097BA00083EBEC /* MWMMapDownloaderSubplaceTableViewCell.mm in Sources */, F6E2FF6A1E097BA00083EBEC /* MWMUnitsController.mm in Sources */, 34FE5A701F18F30F00BCA729 /* TrafficButtonArea.swift in Sources */, @@ -7127,6 +7234,7 @@ 347752911F7251C7000D46A3 /* UGCAddReviewTextCell.swift in Sources */, 34E50DF11F6FCC41008EED49 /* UGCYourReviewCell.swift in Sources */, 34AB66391FC5AA330078E451 /* RouteManagerCell.swift in Sources */, + 3472B5D4200F501500DC6CD5 /* BackgroundFetchTaskFrameworkType.swift in Sources */, F6E2FF251E097BA00083EBEC /* MWMSearchTabbedViewLayout.mm in Sources */, F6E2FF1F1E097BA00083EBEC /* MWMSearchTabbedViewController.mm in Sources */, F6E2FF311E097BA00083EBEC /* MWMSearchCommonCell.mm in Sources */,