[iOS] Native subscription screen deeplink

https://jira.mail.ru/browse/MAPSME-12339
This commit is contained in:
Alexander Boriskov 2019-11-13 18:01:23 +03:00 committed by Aleksey Belousov
parent 018e684b77
commit 4cfc22cc4d
56 changed files with 958 additions and 297 deletions

View file

@ -46,10 +46,21 @@
47EEAFF42350CEDB005CF316 /* AppInfo.mm in Sources */ = {isa = PBXBuildFile; fileRef = 47EEAFF22350CEDA005CF316 /* AppInfo.mm */; };
47EEAFF62350CF48005CF316 /* AppInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 47EEAFF32350CEDB005CF316 /* AppInfo.h */; settings = {ATTRIBUTES = (Public, ); }; };
47EEAFF72350D060005CF316 /* MWMCommon.h in Headers */ = {isa = PBXBuildFile; fileRef = 47EEAFF52350CEF6005CF316 /* MWMCommon.h */; settings = {ATTRIBUTES = (Public, ); }; };
991CE2EA2375AF19009EB02A /* PromoAfterBookingCampaignAdapter.mm in Sources */ = {isa = PBXBuildFile; fileRef = 991CE2E82375AF19009EB02A /* PromoAfterBookingCampaignAdapter.mm */; };
991CE2EB2375AF19009EB02A /* PromoAfterBookingCampaignAdapter.h in Headers */ = {isa = PBXBuildFile; fileRef = 991CE2E92375AF19009EB02A /* PromoAfterBookingCampaignAdapter.h */; settings = {ATTRIBUTES = (Public, ); }; };
991CE2EE2375AF26009EB02A /* PromoDiscoveryCampaignAdapter.mm in Sources */ = {isa = PBXBuildFile; fileRef = 991CE2ED2375AF25009EB02A /* PromoDiscoveryCampaignAdapter.mm */; };
991CE2EF2375AF4E009EB02A /* PromoDiscoveryCampaignAdapter.h in Headers */ = {isa = PBXBuildFile; fileRef = 991CE2EC2375AF25009EB02A /* PromoDiscoveryCampaignAdapter.h */; settings = {ATTRIBUTES = (Public, ); }; };
99103843237EDFA200893C9F /* DeepLinkData.h in Headers */ = {isa = PBXBuildFile; fileRef = 99103841237EDFA200893C9F /* DeepLinkData.h */; settings = {ATTRIBUTES = (Public, ); }; };
99103844237EDFA200893C9F /* DeepLinkData.m in Sources */ = {isa = PBXBuildFile; fileRef = 99103842237EDFA200893C9F /* DeepLinkData.m */; };
993F54F2237C5D1100545511 /* PromoDiscoveryCampaignAdapter.h in Headers */ = {isa = PBXBuildFile; fileRef = 993F54EE237C5D1000545511 /* PromoDiscoveryCampaignAdapter.h */; settings = {ATTRIBUTES = (Public, ); }; };
993F54F3237C5D1100545511 /* PromoAfterBookingCampaignAdapter.mm in Sources */ = {isa = PBXBuildFile; fileRef = 993F54EF237C5D1000545511 /* PromoAfterBookingCampaignAdapter.mm */; };
993F54F4237C5D1100545511 /* PromoDiscoveryCampaignAdapter.mm in Sources */ = {isa = PBXBuildFile; fileRef = 993F54F0237C5D1000545511 /* PromoDiscoveryCampaignAdapter.mm */; };
993F54F5237C5D1100545511 /* PromoAfterBookingCampaignAdapter.h in Headers */ = {isa = PBXBuildFile; fileRef = 993F54F1237C5D1000545511 /* PromoAfterBookingCampaignAdapter.h */; settings = {ATTRIBUTES = (Public, ); }; };
99447849238559F2004DAEE5 /* DeeplinkParsingResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 99447847238559F2004DAEE5 /* DeeplinkParsingResult.h */; };
9957FACE237AB01400855F48 /* DeepLinkParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 9957FACC237AB01400855F48 /* DeepLinkParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
9957FACF237AB01400855F48 /* DeepLinkParser.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9957FACD237AB01400855F48 /* DeepLinkParser.mm */; };
9957FADB237ACB1100855F48 /* DeepLinkSearchData.h in Headers */ = {isa = PBXBuildFile; fileRef = 9957FAD9237ACB1100855F48 /* DeepLinkSearchData.h */; settings = {ATTRIBUTES = (Public, ); }; };
9957FADC237ACB1100855F48 /* DeepLinkSearchData.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9957FADA237ACB1100855F48 /* DeepLinkSearchData.mm */; };
9957FAE8237AE5B000855F48 /* Logger.h in Headers */ = {isa = PBXBuildFile; fileRef = 9957FAE6237AE5B000855F48 /* Logger.h */; settings = {ATTRIBUTES = (Public, ); }; };
9957FAE9237AE5B000855F48 /* Logger.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9957FAE7237AE5B000855F48 /* Logger.mm */; };
999D3A64237B097C00C5F7A8 /* DeepLinkSubscriptionData.h in Headers */ = {isa = PBXBuildFile; fileRef = 999D3A62237B097C00C5F7A8 /* DeepLinkSubscriptionData.h */; settings = {ATTRIBUTES = (Public, ); }; };
999D3A65237B097C00C5F7A8 /* DeepLinkSubscriptionData.mm in Sources */ = {isa = PBXBuildFile; fileRef = 999D3A63237B097C00C5F7A8 /* DeepLinkSubscriptionData.mm */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
@ -96,10 +107,25 @@
47EEAFF22350CEDA005CF316 /* AppInfo.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = AppInfo.mm; sourceTree = "<group>"; };
47EEAFF32350CEDB005CF316 /* AppInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppInfo.h; sourceTree = "<group>"; };
47EEAFF52350CEF6005CF316 /* MWMCommon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMCommon.h; sourceTree = "<group>"; };
99103841237EDFA200893C9F /* DeepLinkData.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DeepLinkData.h; sourceTree = "<group>"; };
99103842237EDFA200893C9F /* DeepLinkData.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DeepLinkData.m; sourceTree = "<group>"; };
991CE2E82375AF19009EB02A /* PromoAfterBookingCampaignAdapter.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = PromoAfterBookingCampaignAdapter.mm; sourceTree = "<group>"; };
991CE2E92375AF19009EB02A /* PromoAfterBookingCampaignAdapter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PromoAfterBookingCampaignAdapter.h; sourceTree = "<group>"; };
991CE2EC2375AF25009EB02A /* PromoDiscoveryCampaignAdapter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PromoDiscoveryCampaignAdapter.h; sourceTree = "<group>"; };
991CE2ED2375AF25009EB02A /* PromoDiscoveryCampaignAdapter.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = PromoDiscoveryCampaignAdapter.mm; sourceTree = "<group>"; };
993F54EE237C5D1000545511 /* PromoDiscoveryCampaignAdapter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PromoDiscoveryCampaignAdapter.h; sourceTree = "<group>"; };
993F54EF237C5D1000545511 /* PromoAfterBookingCampaignAdapter.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = PromoAfterBookingCampaignAdapter.mm; sourceTree = "<group>"; };
993F54F0237C5D1000545511 /* PromoDiscoveryCampaignAdapter.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = PromoDiscoveryCampaignAdapter.mm; sourceTree = "<group>"; };
993F54F1237C5D1000545511 /* PromoAfterBookingCampaignAdapter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PromoAfterBookingCampaignAdapter.h; sourceTree = "<group>"; };
99447847238559F2004DAEE5 /* DeeplinkParsingResult.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DeeplinkParsingResult.h; sourceTree = "<group>"; };
9957FACC237AB01400855F48 /* DeepLinkParser.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DeepLinkParser.h; sourceTree = "<group>"; };
9957FACD237AB01400855F48 /* DeepLinkParser.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = DeepLinkParser.mm; sourceTree = "<group>"; };
9957FAD9237ACB1100855F48 /* DeepLinkSearchData.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DeepLinkSearchData.h; sourceTree = "<group>"; };
9957FADA237ACB1100855F48 /* DeepLinkSearchData.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = DeepLinkSearchData.mm; sourceTree = "<group>"; };
9957FAE6237AE5B000855F48 /* Logger.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Logger.h; sourceTree = "<group>"; };
9957FAE7237AE5B000855F48 /* Logger.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = Logger.mm; sourceTree = "<group>"; };
999D3A62237B097C00C5F7A8 /* DeepLinkSubscriptionData.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DeepLinkSubscriptionData.h; sourceTree = "<group>"; };
999D3A63237B097C00C5F7A8 /* DeepLinkSubscriptionData.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = DeepLinkSubscriptionData.mm; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@ -122,6 +148,7 @@
470015F12342509C00EBF03D /* CoreApi */,
470015F02342509C00EBF03D /* Products */,
4700161123425CFC00EBF03D /* Frameworks */,
993F54EC237C5CD800545511 /* Recovered References */,
);
sourceTree = "<group>";
};
@ -136,7 +163,9 @@
470015F12342509C00EBF03D /* CoreApi */ = {
isa = PBXGroup;
children = (
991CE2E72375AEEF009EB02A /* Promo */,
993F54ED237C5D1000545511 /* Promo */,
9957FAE5237AE59C00855F48 /* Logger */,
9957FAC1237AABD800855F48 /* DeepLink */,
4718C42F2355FC0D00640DF1 /* NetworkPolicy */,
47C637D92354B76700E12DE0 /* Search */,
47C637D32354AEA800E12DE0 /* Traffic */,
@ -267,17 +296,61 @@
path = Search;
sourceTree = "<group>";
};
991CE2E72375AEEF009EB02A /* Promo */ = {
99103840237ED97600893C9F /* Data */ = {
isa = PBXGroup;
children = (
999D3A62237B097C00C5F7A8 /* DeepLinkSubscriptionData.h */,
999D3A63237B097C00C5F7A8 /* DeepLinkSubscriptionData.mm */,
9957FAD9237ACB1100855F48 /* DeepLinkSearchData.h */,
9957FADA237ACB1100855F48 /* DeepLinkSearchData.mm */,
99103841237EDFA200893C9F /* DeepLinkData.h */,
99103842237EDFA200893C9F /* DeepLinkData.m */,
99447847238559F2004DAEE5 /* DeeplinkParsingResult.h */,
);
path = Data;
sourceTree = "<group>";
};
993F54EC237C5CD800545511 /* Recovered References */ = {
isa = PBXGroup;
children = (
991CE2EC2375AF25009EB02A /* PromoDiscoveryCampaignAdapter.h */,
991CE2ED2375AF25009EB02A /* PromoDiscoveryCampaignAdapter.mm */,
991CE2E92375AF19009EB02A /* PromoAfterBookingCampaignAdapter.h */,
991CE2EC2375AF25009EB02A /* PromoDiscoveryCampaignAdapter.h */,
991CE2E82375AF19009EB02A /* PromoAfterBookingCampaignAdapter.mm */,
991CE2ED2375AF25009EB02A /* PromoDiscoveryCampaignAdapter.mm */,
);
name = "Recovered References";
sourceTree = "<group>";
};
993F54ED237C5D1000545511 /* Promo */ = {
isa = PBXGroup;
children = (
993F54EE237C5D1000545511 /* PromoDiscoveryCampaignAdapter.h */,
993F54EF237C5D1000545511 /* PromoAfterBookingCampaignAdapter.mm */,
993F54F0237C5D1000545511 /* PromoDiscoveryCampaignAdapter.mm */,
993F54F1237C5D1000545511 /* PromoAfterBookingCampaignAdapter.h */,
);
path = Promo;
sourceTree = "<group>";
};
9957FAC1237AABD800855F48 /* DeepLink */ = {
isa = PBXGroup;
children = (
99103840237ED97600893C9F /* Data */,
9957FACC237AB01400855F48 /* DeepLinkParser.h */,
9957FACD237AB01400855F48 /* DeepLinkParser.mm */,
);
path = DeepLink;
sourceTree = "<group>";
};
9957FAE5237AE59C00855F48 /* Logger */ = {
isa = PBXGroup;
children = (
9957FAE6237AE5B000855F48 /* Logger.h */,
9957FAE7237AE5B000855F48 /* Logger.mm */,
);
path = Logger;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
@ -285,17 +358,23 @@
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
9957FAE8237AE5B000855F48 /* Logger.h in Headers */,
470015F42342509C00EBF03D /* CoreApi.h in Headers */,
479F705F234FBB8F00011E2E /* MWMCategory.h in Headers */,
47A65CAF235008E100DCD85F /* CoreApi-swift.h in Headers */,
9957FACE237AB01400855F48 /* DeepLinkParser.h in Headers */,
993F54F5237C5D1100545511 /* PromoAfterBookingCampaignAdapter.h in Headers */,
479834F223426CCC00724D1E /* MWMTag+Convenience.h in Headers */,
479F704F234FB60400011E2E /* MWMCatalogObserver.h in Headers */,
47EEAFF72350D060005CF316 /* MWMCommon.h in Headers */,
9957FADB237ACB1100855F48 /* DeepLinkSearchData.h in Headers */,
479F7056234FB7F200011E2E /* MWMBookmarksManager.h in Headers */,
4718C4322355FC3C00640DF1 /* MWMNetworkPolicy.h in Headers */,
99103843237EDFA200893C9F /* DeepLinkData.h in Headers */,
47C637DD2354B79B00E12DE0 /* MWMSearchFrameworkHelper.h in Headers */,
479F704B234F78AB00011E2E /* MWMFrameworkHelper.h in Headers */,
479834F323426CD200724D1E /* MWMTagGroup+Convenience.h in Headers */,
999D3A64237B097C00C5F7A8 /* DeepLinkSubscriptionData.h in Headers */,
470016102342579200EBF03D /* MWMTagGroup.h in Headers */,
479F7063234FBC5900011E2E /* MWMCarPlayBookmarkObject.h in Headers */,
47EEAFF62350CF48005CF316 /* AppInfo.h in Headers */,
@ -303,9 +382,9 @@
4700160F2342579000EBF03D /* MWMTag.h in Headers */,
479F705B234FBB1100011E2E /* MWMUTM.h in Headers */,
479F704A234F785B00011E2E /* MWMTypes.h in Headers */,
991CE2EB2375AF19009EB02A /* PromoAfterBookingCampaignAdapter.h in Headers */,
991CE2EF2375AF4E009EB02A /* PromoDiscoveryCampaignAdapter.h in Headers */,
47C637D72354AEBE00E12DE0 /* MWMTrafficManager.h in Headers */,
993F54F2237C5D1100545511 /* PromoDiscoveryCampaignAdapter.h in Headers */,
99447849238559F2004DAEE5 /* DeeplinkParsingResult.h in Headers */,
47D609DC234FE625008ECC47 /* MWMBookmarksObserver.h in Headers */,
475784C22344B422008291A4 /* Framework.h in Headers */,
47C637D22354A6FB00E12DE0 /* MWMEye.h in Headers */,
@ -381,11 +460,14 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
9957FADC237ACB1100855F48 /* DeepLinkSearchData.mm in Sources */,
479F7050234FB60400011E2E /* MWMCatalogObserver.mm in Sources */,
9957FACF237AB01400855F48 /* DeepLinkParser.mm in Sources */,
99103844237EDFA200893C9F /* DeepLinkData.m in Sources */,
47C637D12354A6FB00E12DE0 /* MWMEye.mm in Sources */,
47C637DC2354B79B00E12DE0 /* MWMSearchFrameworkHelper.mm in Sources */,
993F54F4237C5D1100545511 /* PromoDiscoveryCampaignAdapter.mm in Sources */,
479F7062234FBC4700011E2E /* MWMCarPlayBookmarkObject.mm in Sources */,
991CE2EA2375AF19009EB02A /* PromoAfterBookingCampaignAdapter.mm in Sources */,
479F705E234FBB8C00011E2E /* MWMCategory.m in Sources */,
479834EB2342697400724D1E /* MWMTagGroup+Convenience.mm in Sources */,
470016082342541100EBF03D /* MWMTagGroup.m in Sources */,
@ -394,10 +476,12 @@
470016072342541100EBF03D /* MWMTag.m in Sources */,
479834EA2342697400724D1E /* MWMTag+Convenience.mm in Sources */,
47C637D62354AEBE00E12DE0 /* MWMTrafficManager.mm in Sources */,
991CE2EE2375AF26009EB02A /* PromoDiscoveryCampaignAdapter.mm in Sources */,
475784C32344B422008291A4 /* Framework.cpp in Sources */,
4718C4332355FC3C00640DF1 /* MWMNetworkPolicy.mm in Sources */,
993F54F3237C5D1100545511 /* PromoAfterBookingCampaignAdapter.mm in Sources */,
47EEAFF42350CEDB005CF316 /* AppInfo.mm in Sources */,
9957FAE9237AE5B000855F48 /* Logger.mm in Sources */,
999D3A65237B097C00C5F7A8 /* DeepLinkSubscriptionData.mm in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View file

@ -21,3 +21,7 @@ FOUNDATION_EXPORT const unsigned char CoreApiVersionString[];
#import <CoreApi/MWMUTM.h>
#import <CoreApi/PromoDiscoveryCampaignAdapter.h>
#import <CoreApi/PromoAfterBookingCampaignAdapter.h>
#import <CoreApi/DeepLinkParser.h>
#import <CoreApi/DeepLinkSearchData.h>
#import <CoreApi/DeepLinkSubscriptionData.h>
#import <CoreApi/Logger.h>

View file

@ -0,0 +1,30 @@
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
typedef NS_ENUM(NSUInteger, DeeplinkParsingResult) {
DeeplinkParsingResultIncorrect = 0,
DeeplinkParsingResultMap,
DeeplinkParsingResultRoute,
DeeplinkParsingResultSearch,
DeeplinkParsingResultLead,
DeeplinkParsingResultCatalogue,
DeeplinkParsingResultCataloguePath,
DeeplinkParsingResultSubscription
};
@protocol IDeepLinkData <NSObject>
@property (nonatomic, readonly) DeeplinkParsingResult result;
@end
@interface DeepLinkData : NSObject <IDeepLinkData>
@property (nonatomic, readonly) DeeplinkParsingResult result;
- (instancetype)init:(DeeplinkParsingResult)result;
@end
NS_ASSUME_NONNULL_END

View file

@ -0,0 +1,13 @@
#import "DeepLinkData.h"
@implementation DeepLinkData
- (instancetype)init:(DeeplinkParsingResult)result {
self = [super init];
if (self) {
_result = result;
}
return self;
}
@end

View file

@ -0,0 +1,19 @@
#import <Foundation/Foundation.h>
#import "DeepLinkData.h"
NS_ASSUME_NONNULL_BEGIN
@interface DeepLinkSearchData : NSObject <IDeepLinkData>
@property(nonatomic, readonly) DeeplinkParsingResult result;
@property(nonatomic, readonly) NSString* query;
@property(nonatomic, readonly) NSString* locale;
@property(nonatomic, readonly) double centerLat;
@property(nonatomic, readonly) double centerLon;
@property(nonatomic, readonly) BOOL isSearchOnMap;
- (instancetype)init:(DeeplinkParsingResult)result;
- (void)onViewportChanged:(int)zoomLevel;
@end
NS_ASSUME_NONNULL_END

View file

@ -0,0 +1,26 @@
#import "DeepLinkSearchData.h"
#import <CoreApi/Framework.h>
#include "drape_frontend/visual_params.hpp"
#include "geometry/mercator.hpp"
@implementation DeepLinkSearchData
- (instancetype)init:(DeeplinkParsingResult)result {
self = [super init];
if (self) {
_result = result;
auto const &request = GetFramework().GetParsedSearchRequest();
_query = [@((request.m_query + " ").c_str()) stringByRemovingPercentEncoding];
_locale = @(request.m_locale.c_str());
_centerLat = request.m_centerLat;
_centerLon = request.m_centerLon;
_isSearchOnMap = request.m_isSearchOnMap;
}
return self;
}
- (void)onViewportChanged:(int)zoomLevel {
auto const center = mercator::FromLatLon(_centerLat, _centerLon);
auto const rect = df::GetRectForDrawScale(zoomLevel, center);
GetFramework().GetSearchAPI().OnViewportChanged(rect);
}
@end

View file

@ -0,0 +1,15 @@
#import <Foundation/Foundation.h>
#import "DeepLinkData.h"
NS_ASSUME_NONNULL_BEGIN
@interface DeepLinkSubscriptionData : NSObject <IDeepLinkData>
@property (nonatomic, readonly) DeeplinkParsingResult result;
@property(nonatomic, readonly) NSString* deliverable;
- (instancetype)init:(DeeplinkParsingResult)result;
@end
NS_ASSUME_NONNULL_END

View file

@ -0,0 +1,16 @@
#import "DeepLinkSubscriptionData.h"
#import <CoreApi/Framework.h>
@implementation DeepLinkSubscriptionData
- (instancetype)init:(DeeplinkParsingResult)result {
self = [super init];
if (self) {
_result = result;
auto const &request = GetFramework().GetParsedSubscription();
_deliverable = @(request.m_deliverable.c_str());
}
return self;
}
@end

View file

@ -0,0 +1,21 @@
#import <Foundation/Foundation.h>
#import "map/mwm_url.hpp"
NS_ASSUME_NONNULL_BEGIN
static inline DeeplinkParsingResult deeplinkParsingResult(url_scheme::ParsedMapApi::ParsingResult result)
{
switch (result)
{
case url_scheme::ParsedMapApi::ParsingResult::Incorrect: return DeeplinkParsingResultIncorrect;
case url_scheme::ParsedMapApi::ParsingResult::Map: return DeeplinkParsingResultMap;
case url_scheme::ParsedMapApi::ParsingResult::Route: return DeeplinkParsingResultRoute;
case url_scheme::ParsedMapApi::ParsingResult::Search: return DeeplinkParsingResultSearch;
case url_scheme::ParsedMapApi::ParsingResult::Lead: return DeeplinkParsingResultLead;
case url_scheme::ParsedMapApi::ParsingResult::Catalogue: return DeeplinkParsingResultCatalogue;
case url_scheme::ParsedMapApi::ParsingResult::CataloguePath: return DeeplinkParsingResultCataloguePath;
case url_scheme::ParsedMapApi::ParsingResult::Subscription: return DeeplinkParsingResultSubscription;
}
}
NS_ASSUME_NONNULL_END

View file

@ -0,0 +1,14 @@
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@protocol IDeepLinkData;
@interface DeepLinkParser : NSObject
+ (id<IDeepLinkData>)parseAndSetApiURL:(NSURL*)url;
+ (bool)showMapForUrl:(NSURL*)url;
+ (void)addBookmarksFile:(NSURL*)url;
@end
NS_ASSUME_NONNULL_END

View file

@ -0,0 +1,31 @@
#import "DeepLinkParser.h"
#include <CoreApi/Framework.h>
#import "DeepLinkData.h"
#import "DeepLinkSearchData.h"
#import "DeepLinkSubscriptionData.h"
#import "DeeplinkParsingResult.h"
@implementation DeepLinkParser
+ (id<IDeepLinkData>)parseAndSetApiURL:(NSURL *)url {
Framework &f = GetFramework();
DeeplinkParsingResult result = deeplinkParsingResult(f.ParseAndSetApiURL(url.absoluteString.UTF8String));
switch (result) {
case DeeplinkParsingResultSearch:
return [[DeepLinkSearchData alloc] init:result];
case DeeplinkParsingResultSubscription:
return [[DeepLinkSubscriptionData alloc] init:result];
default:
return [[DeepLinkData alloc] init:result];
}
}
+ (bool)showMapForUrl:(NSURL *)url {
return GetFramework().ShowMapForURL(url.absoluteString.UTF8String);
}
+ (void)addBookmarksFile:(NSURL *)url {
GetFramework().AddBookmarksFile(url.relativePath.UTF8String, false /* isTemporaryFile */);
}
@end

View file

@ -0,0 +1,20 @@
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
typedef NS_ENUM(NSUInteger, LogLevel) {
LogLevelDebug = 0,
LogLevelInfo,
LogLevelWarning,
LogLevelError,
LogLevelCritical
};
@interface Logger : NSObject
+ (void)log:(LogLevel)level message:(NSString*)message;
+ (BOOL)canLog:(LogLevel)level;
@end
NS_ASSUME_NONNULL_END

View file

@ -0,0 +1,33 @@
#import "Logger.h"
#import "base/logging.hpp"
@interface Logger ()
+ (base::LogLevel)baseLevel:(LogLevel)level;
@end
@implementation Logger
+ (void)log:(LogLevel)level message:(NSString*)message {
LOG_SHORT([Logger baseLevel:level], (message.UTF8String));
}
+ (BOOL)canLog:(LogLevel)level {
return [Logger baseLevel:level] >= base::g_LogLevel;
}
+ (base::LogLevel)baseLevel:(LogLevel)level {
switch (level) {
case LogLevelDebug:
return LDEBUG;
case LogLevelInfo:
return LINFO;
case LogLevelWarning:
return LWARNING;
case LogLevelError:
return LERROR;
case LogLevelCritical:
return LCRITICAL;
}
}
@end

View file

@ -205,25 +205,13 @@ final class CatalogWebViewController: WebViewController {
}
private func showSubscribe(type: SubscriptionGroupType) {
let subscribeViewController: BaseSubscriptionViewController
switch type {
case .allPass:
subscribeViewController = AllPassSubscriptionViewController()
case .sightseeing:
subscribeViewController = BookmarksSubscriptionViewController()
let subscribeViewController = SubscriptionViewBuilder.build(type: type,
parentViewController: self,
source: kStatWebView) { [weak self] (success) in
if (success) {
self?.webView.reloadFromOrigin()
}
}
subscribeViewController.onSubscribe = { [weak self] in
self?.webView.reloadFromOrigin()
self?.dismiss(animated: true)
let successDialog = SubscriptionSuccessViewController(type) { [weak self] in
self?.dismiss(animated: true)
}
self?.present(successDialog, animated: true)
}
subscribeViewController.onCancel = { [weak self] in
self?.dismiss(animated: true)
}
present(subscribeViewController, animated: true)
}

View file

@ -114,9 +114,9 @@ class PaidRouteViewController: MWMViewController {
self?.subscribeButton.setTitle(title, for: .normal)
self?.subscribeButton.isEnabled = true
self?.subscription = s
Statistics.logEvent(kStatInappShow, withParameters: [kStatVendor : MWMPurchaseManager.bookmarksSubscriptionVendorId(),
Statistics.logEvent(kStatInappShow, withParameters: [kStatVendor : self?.subscriptionManager.vendorId ?? "",
kStatProduct : s.productId,
kStatPurchase : MWMPurchaseManager.bookmarksSubscriptionServerId()],
kStatPurchase : self?.subscriptionManager.serverId ?? ""],
with: .realtime)
}
@ -214,8 +214,8 @@ class PaidRouteViewController: MWMViewController {
}
Statistics.logEvent(kStatInappSelect, withParameters: [kStatProduct : subscription.productId,
kStatPurchase : MWMPurchaseManager.bookmarksSubscriptionServerId()])
Statistics.logEvent(kStatInappPay, withParameters: [kStatPurchase : MWMPurchaseManager.bookmarksSubscriptionServerId()],
kStatPurchase : self?.subscriptionManager.serverId ?? ""])
Statistics.logEvent(kStatInappPay, withParameters: [kStatPurchase : self?.subscriptionManager.serverId ?? ""],
with: .realtime)
self?.subscriptionManager.subscribe(to: subscription)
}
@ -223,7 +223,7 @@ class PaidRouteViewController: MWMViewController {
@IBAction func onCancel(_ sender: UIButton) {
statistics.logCancel()
Statistics.logEvent(kStatInappCancel, withParameters: [kStatPurchase : MWMPurchaseManager.bookmarksSubscriptionServerId()])
Statistics.logEvent(kStatInappCancel, withParameters: [kStatPurchase : subscriptionManager.serverId])
delegate?.didCancelPurchase(self)
}

View file

@ -79,7 +79,7 @@ class AllPassSubscriptionViewController: BaseSubscriptionViewController {
Statistics.logEvent(kStatInappShow, withParameters: [kStatVendor: MWMPurchaseManager.allPassProductIds,
kStatPurchase: MWMPurchaseManager.allPassSubscriptionServerId(),
kStatProduct: BOOKMARKS_SUBSCRIPTION_YEARLY_PRODUCT_ID, //FIXME
kStatProduct: MWMPurchaseManager.allPassProductIds()[0],
kStatFrom: source], with: .realtime)
}

View file

@ -66,6 +66,11 @@ class BaseSubscriptionViewController: MWMViewController {
}
}
}
Statistics.logEvent(kStatInappShow, withParameters: [kStatVendor: subscriptionManager?.vendorId ?? "",
kStatPurchase: subscriptionManager?.serverId ?? "",
kStatProduct: subscriptionManager?.productIds[0] ?? "",
kStatFrom: source], with: .realtime)
}
func purchase(sender: UIButton, period: SubscriptionPeriod) {
@ -87,12 +92,12 @@ class BaseSubscriptionViewController: MWMViewController {
self?.subscriptionManager?.subscribe(to: subscription)
}
}
Statistics.logEvent(kStatInappPay, withParameters: [kStatPurchase: MWMPurchaseManager.bookmarksSubscriptionServerId()],
Statistics.logEvent(kStatInappPay, withParameters: [kStatPurchase: subscriptionManager?.serverId ?? ""],
with: .realtime)
}
@IBAction func onRestore(_ sender: UIButton) {
Statistics.logEvent(kStatInappRestore, withParameters: [kStatPurchase: MWMPurchaseManager.bookmarksSubscriptionServerId()])
Statistics.logEvent(kStatInappRestore, withParameters: [kStatPurchase: subscriptionManager?.serverId ?? ""])
signup(anchor: sender) { [weak self] (success) in
guard success else { return }
self?.loadingView.isHidden = false
@ -114,7 +119,7 @@ class BaseSubscriptionViewController: MWMViewController {
@IBAction func onClose(_ sender: UIButton) {
onCancel?()
Statistics.logEvent(kStatInappCancel, withParameters: [kStatPurchase: MWMPurchaseManager.bookmarksSubscriptionServerId()])
Statistics.logEvent(kStatInappCancel, withParameters: [kStatPurchase: subscriptionManager?.serverId ?? ""])
}
@IBAction func onTerms(_ sender: UIButton) {

View file

@ -53,11 +53,6 @@ import SafariServices
.year: annualDiscountLabel])
self.preferredContentSize = CGSize(width: 414, height: contentView.frame.height)
Statistics.logEvent(kStatInappShow, withParameters: [kStatVendor: MWMPurchaseManager.bookmarksSubscriptionVendorId(),
kStatPurchase: MWMPurchaseManager.bookmarksSubscriptionServerId(),
kStatProduct: BOOKMARKS_SUBSCRIPTION_YEARLY_PRODUCT_ID,
kStatFrom: source], with: .realtime)
}
@IBAction func onAnnualButtonTap(_ sender: UIButton) {

View file

@ -0,0 +1,28 @@
class SubscriptionViewBuilder {
static func build(type: SubscriptionGroupType,
parentViewController: UIViewController,
source: String,
completion: ((Bool) -> Void)?) -> UIViewController {
let subscribeViewController: BaseSubscriptionViewController
switch type {
case .allPass:
subscribeViewController = AllPassSubscriptionViewController()
case .sightseeing:
subscribeViewController = BookmarksSubscriptionViewController()
}
subscribeViewController.source = source
subscribeViewController.onSubscribe = {
completion?(true);
parentViewController.dismiss(animated: true)
let successDialog = SubscriptionSuccessViewController(type) {
parentViewController.dismiss(animated: true)
}
parentViewController.present(successDialog, animated: true)
}
subscribeViewController.onCancel = {
completion?(false)
parentViewController.dismiss(animated: true)
}
return subscribeViewController
}
}

View file

@ -26,7 +26,6 @@
#import "FacebookNativeAdAdapter.h"
#import "CatalogPromoItem.h"
#import "CoreNotificationWrapper.h"
#import "DeepLinkHelper.h"
#import "MapViewController.h"
#import "MWMActivityViewController.h"
#import "MWMAlertViewController.h"
@ -86,3 +85,6 @@
#import "MWMRouterResultCode.h"
#import "MWMLocationModeListener.h"
#import "MWMSpeedCameraManagerMode.h"
#import "MapsAppDelegate.h"
#import "DeepLinkRouteStrategyAdapter.h"
#import "MWMMapViewControlsManager.h"

View file

@ -0,0 +1,12 @@
#import <Foundation/Foundation.h>
#include "geometry/point2d.hpp"
NS_ASSUME_NONNULL_BEGIN
@interface MWMMapViewControlsManager (AddPlace)
- (void)addPlace:(BOOL)isBusiness hasPoint:(BOOL)hasPoint point:(m2::PointD const &)point;
@end
NS_ASSUME_NONNULL_END

View file

@ -3,20 +3,13 @@
#import "MWMNavigationDashboardManager.h"
#import "MWMSearchManager.h"
#include "geometry/point2d.hpp"
@class MapViewController;
@protocol MWMFeatureHolder;
@protocol MWMBookingInfoHolder;
namespace place_page
{
class Info;
} // namespace place_page
@interface MWMMapViewControlsManager : NSObject
+ (MWMMapViewControlsManager *)manager;
+ (MWMMapViewControlsManager *)manager NS_SWIFT_NAME(manager());
@property(nonatomic) BOOL hidden;
@property(nonatomic) BOOL zoomHidden;
@ -46,7 +39,6 @@ class Info;
- (void)showPlacePage;
- (void)updatePlacePage;
- (void)showPlacePageReview;
- (void)addPlace:(BOOL)isBusiness hasPoint:(BOOL)hasPoint point:(m2::PointD const &)point;
#pragma mark - MWMNavigationDashboardManager

View file

@ -1,4 +1,5 @@
#import "MWMMapViewControlsManager.h"
#import "MWMMapViewControlsManager+AddPlace.h"
#import "MWMAddPlaceNavigationBar.h"
#import "MWMBottomMenuControllerProtocol.h"
#import "MWMMapDownloadDialog.h"

View file

@ -8,7 +8,7 @@
#import "MWMMapViewControlsManager.h"
#import "MapViewController.h"
#import "SwiftBridge.h"
#import "base/assert.hpp"
namespace
{
CGFloat const kTopOffset = 6;

View file

@ -1,13 +0,0 @@
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface DeepLinkHelper : NSObject
+ (void)handleGeoUrl:(NSURL *)url;
+ (void)handleFileUrl:(NSURL *)url;
+ (void)handleCommonUrl:(NSURL *)url;
@end
NS_ASSUME_NONNULL_END

View file

@ -1,114 +0,0 @@
#import "DeepLinkHelper.h"
#import <Crashlytics/Crashlytics.h>
#include <CoreApi/Framework.h>
#import "Statistics.h"
#import "MapViewController.h"
#import "MapsAppDelegate.h"
#import "MWMRouter.h"
#import "MWMRoutePoint+CPP.h"
#import "MWMCoreRouterType.h"
#import "MWMMapViewControlsManager.h"
#include "drape_frontend/visual_params.hpp"
#include "geometry/mercator.hpp"
@implementation DeepLinkHelper
+ (void)handleGeoUrl:(NSURL *)url {
NSLog(@"deeplink: handleGeoUrl %@", url);
if (GetFramework().ShowMapForURL(url.absoluteString.UTF8String)) {
[Statistics logEvent:kStatEventName(kStatApplication, kStatImport)
withParameters:@{kStatValue : url.scheme}];
[MapsAppDelegate.theApp showMap];
}
}
+ (void)handleFileUrl:(NSURL *)url {
NSLog(@"deeplink: handleFileUrl %@", url);
GetFramework().AddBookmarksFile(url.relativePath.UTF8String, false /* isTemporaryFile */);
}
+ (void)handleCommonUrl:(NSURL *)url {
NSLog(@"deeplink: handleCommonUrl %@", url);
using namespace url_scheme;
Framework &f = GetFramework();
auto const parsingType = f.ParseAndSetApiURL(url.absoluteString.UTF8String);
switch (parsingType) {
case ParsedMapApi::ParsingResult::Incorrect:
LOG(LWARNING, ("Incorrect parsing result for url:", url));
break;
case ParsedMapApi::ParsingResult::Route: {
auto const parsedData = f.GetParsedRoutingData();
auto const points = parsedData.m_points;
if (points.size() == 2) {
auto p1 = [[MWMRoutePoint alloc] initWithURLSchemeRoutePoint:points.front()
type:MWMRoutePointTypeStart
intermediateIndex:0];
auto p2 = [[MWMRoutePoint alloc] initWithURLSchemeRoutePoint:points.back()
type:MWMRoutePointTypeFinish
intermediateIndex:0];
[MWMRouter buildApiRouteWithType:routerType(parsedData.m_type)
startPoint:p1
finishPoint:p2];
} else {
NSError *err = [[NSError alloc] initWithDomain:kMapsmeErrorDomain
code:5
userInfo:@{ @"Description" : @"Invalid number of route points",
@"URL" : url }];
[[Crashlytics sharedInstance] recordError:err];
}
[MapsAppDelegate.theApp showMap];
break;
}
case ParsedMapApi::ParsingResult::Map:
if (f.ShowMapForURL(url.absoluteString.UTF8String))
[MapsAppDelegate.theApp showMap];
break;
case ParsedMapApi::ParsingResult::Search: {
int constexpr kSearchInViewportZoom = 16;
auto const &request = f.GetParsedSearchRequest();
auto query = [@((request.m_query + " ").c_str()) stringByRemovingPercentEncoding];
auto locale = @(request.m_locale.c_str());
// Set viewport only when cll parameter was provided in url.
if (request.m_centerLat != 0.0 || request.m_centerLon != 0.0) {
[MapViewController setViewport:request.m_centerLat
lon:request.m_centerLon
zoomLevel:kSearchInViewportZoom];
// We need to update viewport for search api manually because of drape engine
// will not notify subscribers when search view is shown.
if (!request.m_isSearchOnMap)
{
auto const center = mercator::FromLatLon(request.m_centerLat, request.m_centerLon);
auto const rect = df::GetRectForDrawScale(kSearchInViewportZoom, center);
f.GetSearchAPI().OnViewportChanged(rect);
}
}
if (request.m_isSearchOnMap) {
[MWMMapViewControlsManager.manager searchTextOnMap:query forInputLocale:locale];
} else {
[MWMMapViewControlsManager.manager searchText:query forInputLocale:locale];
}
break;
}
case ParsedMapApi::ParsingResult::Catalogue:
[MapViewController.sharedController openCatalogDeeplink:url animated:NO utm:MWMUTMNone];
break;
case ParsedMapApi::ParsingResult::CataloguePath:
[MapViewController.sharedController openCatalogDeeplink:url animated:NO utm:MWMUTMNone];
break;
case ParsedMapApi::ParsingResult::Lead: break;
}
}
@end

View file

@ -826,7 +826,8 @@ continueUserActivity:(NSUserActivity *)userActivity
NSURL *deeplinkUrl = [NSURL URLWithString:deeplink];
if (deeplinkUrl != nil) {
dispatch_async(dispatch_get_main_queue(), ^{
[[DeepLinkHandler shared] applicationDidReceiveUniversalLink:deeplinkUrl];
[[DeepLinkHandler shared] applicationDidReceiveUniversalLink: deeplinkUrl
provider: DeepLinkProviderAppsflyer];
});
}
}

View file

@ -26,3 +26,15 @@ func statusBarHeight() -> CGFloat {
let statusBarSize = UIApplication.shared.statusBarFrame.size
return min(statusBarSize.height, statusBarSize.width)
}
func LOG(_ level: LogLevel,
_ message: @autoclosure () -> Any,
functionName: StaticString = #function,
fileName: StaticString = #file,
lineNumber: UInt = #line) {
if (Logger.canLog(level)) {
let shorFileName = URL(string: "\(fileName)")?.lastPathComponent ?? ""
let formattedMessage = "\(shorFileName):\(lineNumber) \(functionName): \(message())"
Logger.log(level, message: formattedMessage)
}
}

View file

@ -19,6 +19,7 @@ static NSString * const kStatAdd = @"add";
static NSString * const kStatAddDescription = @"add_description";
static NSString * const kStatAddPlace = @"add_place";
static NSString * const kStatAfterSave = @"after_save";
static NSString * const kStatAppsflyer = @"appsflyer";
static NSString * const kStatAlert = @"Alert";
static NSString * const kStatAllMaps = @"all_maps";
static NSString * const kStatAlways = @"Always";
@ -73,6 +74,7 @@ static NSString * const kStatCampSite = @"campSite";
static NSString * const kStatCancel = @"cancel";
static NSString * const kStatCatalogOpen = @"Bookmarks_Downloaded_Catalogue_open";
static NSString * const kStatCatalogue = @"catalogue";
static NSString * const kStatCataloguePath = @"guides_page";
static NSString * const kStatDone = @"done";
static NSString * const kStatCarplay = @"carplay";
static NSString * const kStatCarplayActivated = @"CarPlay_activated";
@ -118,6 +120,8 @@ static NSString * const kStatCountry = @"Country";
static NSString * const kStatCurrentMap = @"current_map";
static NSString * const kStatDate = @"date";
static NSString * const kStatDeeplink = @"Deeplink";
static NSString * const kStatDeeplinkCall = @"Deeplink_call";
static NSString * const kStatDeeplinkCallMissed = @"Deeplink_call_missed";
static NSString * const kStatDelete = @"delete";
static NSString * const kStatDeleteAll = @"delete all";
static NSString * const kStatDeleteAllWithChanges = @"delete_all_with_changes";
@ -235,6 +239,7 @@ static NSString * const kStatLandscape = @"Landscape";
static NSString * const kStatLanguage = @"Language";
static NSString * const kStatLat = @"lat";
static NSString * const kStatLon = @"lon";
static NSString * const kStatLead = @"lead";
static NSString * const kStatListSettings = @"list_settings";
static NSString * const kStatLocals = @"Locals";
static NSString * const kStatLocalsProvider = @"Locals.Maps.Me";
@ -270,6 +275,7 @@ static NSString * const kStatMyPosition = @"My position";
static NSString * const kStatMyTargetAppsClicked = @"MyTargetAppsClicked";
static NSString * const kStatMyTargetAppsDisplayed = @"MyTargetAppsDisplayed";
static NSString * const kStatName = @"Name";
static NSString * const kStatNative = @"native";
static NSString * const kStatNavigation = @"navigation";
static NSString * const kStatNavigationDashboard = @"Navigation dashboard";
static NSString * const kStatNetwork = @"network";
@ -294,6 +300,7 @@ static NSString * const kStatOffscreen = @"Offscreen";
static NSString * const kStatOn = @"On";
static NSString * const kStatOnboardingDlShow= @"OnboardingDeeplinkScreen_show";
static NSString * const kStatOnboardingDlAccept = @"OnboardingDeeplinkScreen_accept";
static NSString * const kStatOnboardingGuidesSubscription = @"onboarding_guides_subscription";
static NSString * const kStatOnline = @"online";
static NSString * const kStatOpen = @"Open";
static NSString * const kStatOpenActionSheet = @"Open action sheet";
@ -443,6 +450,7 @@ static NSString * const kStatSponsor = @"sponsor";
static NSString * const kStatSponsoredButton = @"sponsored_button";
static NSString * const kStatStart = @"Start";
static NSString * const kStatState = @"state";
static NSString * const kStatSubscription = @"subscription";
static NSString * const kStatSwapRoutingPoints = @"Swap routing points";
static NSString * const kStatTTS = @"TTS";
static NSString * const kStatTTSSettings = @"TTS settings";

View file

@ -1,22 +1,39 @@
fileprivate enum DeeplinkType {
case geo
case file
case common
@objc enum DeepLinkProvider: Int {
case native
case appsflyer
var statName: String {
switch self {
case .native:
return kStatNative
case .appsflyer:
return kStatAppsflyer
}
}
}
class DeepLinkURL {
let url: URL
let provider: DeepLinkProvider
init(url: URL, provider: DeepLinkProvider = .native) {
self.url = url
self.provider = provider
}
}
@objc @objcMembers class DeepLinkHandler: NSObject {
static let shared = DeepLinkHandler()
private(set) var isLaunchedByDeeplink = false
private(set) var deeplinkURL: URL?
private(set) var deeplinkURL: DeepLinkURL?
var needExtraWelcomeScreen: Bool {
guard let host = deeplinkURL?.host else { return false }
guard let host = deeplinkURL?.url.host else { return false }
return host == "catalogue" || host == "guides_page"
}
private var canHandleLink = false
private var deeplinkType: DeeplinkType = .common
private override init() {
super.init()
@ -31,39 +48,40 @@ fileprivate enum DeeplinkType {
if let launchDeeplink = options?[UIApplication.LaunchOptionsKey.url] as? URL {
isLaunchedByDeeplink = true
deeplinkURL = launchDeeplink
deeplinkURL = DeepLinkURL(url: launchDeeplink)
}
}
func applicationDidOpenUrl(_ url: URL) -> Bool {
guard let dlType = deeplinkType(url) else { return false }
deeplinkType = dlType
deeplinkURL = url
deeplinkURL = DeepLinkURL(url: url)
if canHandleLink {
handleInternal()
}
return true
}
private func setUniversalLink(_ url: URL) -> Bool {
private func setUniversalLink(_ url: URL, provider: DeepLinkProvider) -> Bool {
let dlUrl = convertUniversalLink(url)
guard let dlType = deeplinkType(dlUrl), deeplinkURL == nil else { return false }
deeplinkType = dlType
deeplinkURL = dlUrl
guard deeplinkURL == nil else { return false }
deeplinkURL = DeepLinkURL(url: dlUrl)
return true
}
func applicationDidReceiveUniversalLink(_ url: URL) -> Bool {
applicationDidReceiveUniversalLink(url, provider: .native)
}
func applicationDidReceiveUniversalLink(_ url: URL, provider: DeepLinkProvider) -> Bool {
var result = false
if let host = url.host, host == "mapsme.onelink.me" {
URLComponents(url: url, resolvingAgainstBaseURL: false)?.queryItems?.forEach {
if $0.name == "af_dp" {
guard let value = $0.value, let dl = URL(string: value) else { return }
result = setUniversalLink(dl)
result = setUniversalLink(dl, provider: provider)
}
}
} else {
result = setUniversalLink(url)
result = setUniversalLink(url, provider: provider)
}
if canHandleLink {
handleInternal()
@ -79,7 +97,7 @@ fileprivate enum DeeplinkType {
}
func handleDeeplink(_ url: URL) {
deeplinkURL = url
deeplinkURL = DeepLinkURL(url: url)
handleDeeplink()
}
@ -93,31 +111,13 @@ fileprivate enum DeeplinkType {
return URL(string: convertedLink)!
}
private func deeplinkType(_ deeplink: URL) -> DeeplinkType? {
switch deeplink.scheme {
case "geo", "ge0":
return .geo
case "file":
return .file
case "mapswithme", "mapsme", "mwm":
return .common
default:
return nil
}
}
private func handleInternal() {
guard let url = deeplinkURL else {
assertionFailure()
return
}
switch deeplinkType {
case .geo:
DeepLinkHelper.handleGeoUrl(url)
case .file:
DeepLinkHelper.handleFileUrl(url)
case .common:
DeepLinkHelper.handleCommonUrl(url)
}
LOG(.info, "Handle deeplink: \(url)")
let deeplinkHandlerStrategy = DeepLinkStrategyFactory.create(url: url)
deeplinkHandlerStrategy.execute()
}
}

View file

@ -0,0 +1,42 @@
class DeepLinkStrategyFactory {
static func create(url deeplinkURL: DeepLinkURL) -> IDeepLinkHandlerStrategy {
switch deeplinkURL.url.scheme {
case "geo", "ge0":
return DeepLinkGeoStrategy(url: deeplinkURL)
case "file":
return DeepLinkFileStrategy(url: deeplinkURL)
case "mapswithme", "mapsme", "mwm":
return DeepLinkStrategyFactory.createCommon(url: deeplinkURL)
default:
return DeepLinkIncorrectStrategy(url: deeplinkURL)
}
}
private static func createCommon(url deeplinkURL: DeepLinkURL) -> IDeepLinkHandlerStrategy {
let data = DeepLinkParser.parseAndSetApiURL(deeplinkURL.url)
switch data.result {
case .incorrect:
return DeepLinkIncorrectStrategy(url: deeplinkURL)
case .route:
return DeepLinkRouteStrategy(url: deeplinkURL)
case .map:
return DeepLinkMapStrategy(url: deeplinkURL)
case .search:
guard let searchData = data as? DeepLinkSearchData else {
return DeepLinkIncorrectStrategy(url: deeplinkURL)
}
return DeepLinkSearchStrategy(url: deeplinkURL, data: searchData)
case .catalogue:
return DeepLinkCatalogueStrategy(url: deeplinkURL)
case .cataloguePath:
return DeepLinkCataloguePathStrategy(url: deeplinkURL)
case .subscription:
guard let subscriptionData = data as? DeepLinkSubscriptionData else {
return DeepLinkIncorrectStrategy(url: deeplinkURL)
}
return DeepLinkSubscriptionStrategy(url: deeplinkURL, data: subscriptionData)
case .lead:
return DeepLinkLeadStrategy(url: deeplinkURL)
}
}
}

View file

@ -0,0 +1,13 @@
class DeepLinkCataloguePathStrategy: IDeepLinkHandlerStrategy {
var deeplinkURL: DeepLinkURL
init(url: DeepLinkURL) {
self.deeplinkURL = url
}
func execute() {
MapViewController.shared()?.openCatalogDeeplink(deeplinkURL.url, animated: false, utm: .none);
sendStatisticsOnSuccess(type: kStatCataloguePath)
}
}

View file

@ -0,0 +1,12 @@
class DeepLinkCatalogueStrategy: IDeepLinkHandlerStrategy {
var deeplinkURL: DeepLinkURL
init(url: DeepLinkURL) {
self.deeplinkURL = url
}
func execute() {
MapViewController.shared()?.openCatalogDeeplink(deeplinkURL.url, animated: false, utm: .none);
sendStatisticsOnSuccess(type: kStatCatalogue)
}
}

View file

@ -0,0 +1,13 @@
import Foundation
class DeepLinkFileStrategy: IDeepLinkHandlerStrategy {
var deeplinkURL: DeepLinkURL
init(url: DeepLinkURL) {
self.deeplinkURL = url
}
func execute() {
DeepLinkParser.addBookmarksFile(deeplinkURL.url)
}
}

View file

@ -0,0 +1,15 @@
class DeepLinkGeoStrategy: IDeepLinkHandlerStrategy {
var deeplinkURL: DeepLinkURL
required init(url: DeepLinkURL) {
self.deeplinkURL = url
}
func execute() {
if (DeepLinkParser.showMap(for: deeplinkURL.url)) {
MapsAppDelegate.theApp().showMap()
Statistics.logEvent(kStatEventName(kStatApplication, kStatImport),
withParameters: [kStatValue: deeplinkURL.url.scheme ?? ""])
}
}
}

View file

@ -0,0 +1,19 @@
protocol IDeepLinkHandlerStrategy {
var deeplinkURL: DeepLinkURL { get }
func execute()
func sendStatisticsOnSuccess(type: String)
func sendStatisticsOnFail(type: String)
}
extension IDeepLinkHandlerStrategy {
func sendStatisticsOnSuccess(type:String) {
Statistics.logEvent(kStatDeeplinkCall, withParameters: [kStatType : type,
kStatProvider: deeplinkURL.provider.statName])
}
func sendStatisticsOnFail(type:String) {
Statistics.logEvent(kStatDeeplinkCallMissed, withParameters: [kStatType : type,
kStatProvider: deeplinkURL.provider.statName])
}
}

View file

@ -0,0 +1,12 @@
class DeepLinkIncorrectStrategy: IDeepLinkHandlerStrategy {
var deeplinkURL: DeepLinkURL
init(url: DeepLinkURL) {
self.deeplinkURL = url
}
func execute() {
LOG(.warning, "Incorrect parsing result for url: \(deeplinkURL.url)");
sendStatisticsOnFail(type: kStatUnknown)
}
}

View file

@ -0,0 +1,11 @@
class DeepLinkLeadStrategy: IDeepLinkHandlerStrategy {
var deeplinkURL: DeepLinkURL
init(url: DeepLinkURL) {
self.deeplinkURL = url
}
func execute() {
sendStatisticsOnSuccess(type: kStatLead)
}
}

View file

@ -0,0 +1,16 @@
class DeepLinkMapStrategy: IDeepLinkHandlerStrategy {
var deeplinkURL: DeepLinkURL
init(url: DeepLinkURL) {
self.deeplinkURL = url
}
func execute() {
if (DeepLinkParser.showMap(for: deeplinkURL.url)) {
MapsAppDelegate.theApp().showMap()
sendStatisticsOnSuccess(type: kStatMap)
} else {
sendStatisticsOnFail(type: kStatMap)
}
}
}

View file

@ -0,0 +1,17 @@
class DeepLinkRouteStrategy: IDeepLinkHandlerStrategy {
var deeplinkURL: DeepLinkURL
init(url: DeepLinkURL) {
self.deeplinkURL = url
}
func execute() {
if let adapter = DeepLinkRouteStrategyAdapter(deeplinkURL.url) {
MWMRouter.buildApiRoute(with: adapter.type, start: adapter.p1, finish: adapter.p2)
MapsAppDelegate.theApp().showMap()
sendStatisticsOnSuccess(type: kStatRoute)
} else {
sendStatisticsOnFail(type: kStatRoute)
}
}
}

View file

@ -0,0 +1,17 @@
#import <Foundation/Foundation.h>
#import "MWMRouterType.h"
NS_ASSUME_NONNULL_BEGIN
@class MWMRoutePoint;
@interface DeepLinkRouteStrategyAdapter : NSObject
@property(nonatomic, readonly) MWMRoutePoint* p1;
@property(nonatomic, readonly) MWMRoutePoint* p2;
@property(nonatomic, readonly) MWMRouterType type;
- (nullable instancetype)init:(NSURL*)url;
@end
NS_ASSUME_NONNULL_END

View file

@ -0,0 +1,34 @@
#import "DeepLinkRouteStrategyAdapter.h"
#import <CoreApi/Framework.h>
#import <Crashlytics/Crashlytics.h>
#import "MWMCoreRouterType.h"
#import "MWMRoutePoint+CPP.h"
@implementation DeepLinkRouteStrategyAdapter
- (instancetype)init:(NSURL *)url {
self = [super init];
if (self) {
auto const parsedData = GetFramework().GetParsedRoutingData();
auto const points = parsedData.m_points;
if (points.size() == 2) {
_p1 = [[MWMRoutePoint alloc] initWithURLSchemeRoutePoint:points.front()
type:MWMRoutePointTypeStart
intermediateIndex:0];
_p2 = [[MWMRoutePoint alloc] initWithURLSchemeRoutePoint:points.back()
type:MWMRoutePointTypeFinish
intermediateIndex:0];
_type = routerType(parsedData.m_type);
} else {
NSError *err = [[NSError alloc] initWithDomain:kMapsmeErrorDomain
code:5
userInfo:@{@"Description": @"Invalid number of route points", @"URL": url}];
[[Crashlytics sharedInstance] recordError:err];
return nil;
}
}
return self;
}
@end

View file

@ -0,0 +1,31 @@
class DeepLinkSearchStrategy: IDeepLinkHandlerStrategy{
var deeplinkURL: DeepLinkURL
private var data: DeepLinkSearchData
init(url: DeepLinkURL, data: DeepLinkSearchData) {
self.deeplinkURL = url
self.data = data
}
func execute() {
let kSearchInViewportZoom: Int32 = 16;
// Set viewport only when cll parameter was provided in url.
if (data.centerLat != 0.0 && data.centerLon != 0.0) {
MapViewController.setViewport(data.centerLat, lon: data.centerLon, zoomLevel: kSearchInViewportZoom)
// We need to update viewport for search api manually because of drape engine
// will not notify subscribers when search view is shown.
if (!data.isSearchOnMap) {
data.onViewportChanged(kSearchInViewportZoom)
}
}
if (data.isSearchOnMap) {
MWMMapViewControlsManager.manager()?.searchText(onMap: data.query, forInputLocale: data.locale)
} else {
MWMMapViewControlsManager.manager()?.searchText(data.query, forInputLocale: data.locale)
}
sendStatisticsOnSuccess(type: kStatSearch)
}
}

View file

@ -0,0 +1,33 @@
class DeepLinkSubscriptionStrategy: IDeepLinkHandlerStrategy {
var deeplinkURL: DeepLinkURL
private var data: DeepLinkSubscriptionData
init(url: DeepLinkURL, data: DeepLinkSubscriptionData) {
self.deeplinkURL = url
self.data = data
}
func execute() {
guard let mapViewController = MapViewController.shared() else {
return;
}
let type: SubscriptionGroupType
switch data.deliverable {
case MWMPurchaseManager.bookmarksSubscriptionServerId():
type = .sightseeing
case MWMPurchaseManager.allPassSubscriptionServerId():
type = .allPass
default:
LOG(.error, "Deliverable is wrong: \(deeplinkURL.url)");
return;
}
mapViewController.dismiss(animated: false, completion: nil)
mapViewController.navigationController?.popToRootViewController(animated: false)
let subscriptionViewController = SubscriptionViewBuilder.build(type: type,
parentViewController: mapViewController,
source: kStatDeeplink,
completion: nil)
mapViewController.present(subscriptionViewController, animated: true, completion: nil)
sendStatisticsOnSuccess(type: kStatSubscription)
}
}

View file

@ -19,7 +19,7 @@
+ (NSString *)bookmarksSubscriptionServerId
{
return @(BOOKMARKS_SUBSCRIPTION_SERVER_ID);
return @(BOOKMARKS_SUBSCRIPTION_SIGHTS_SERVER_ID);
}
+ (NSString *)bookmarksSubscriptionVendorId
@ -29,8 +29,8 @@
+ (NSArray *)bookmakrsProductIds
{
return @[@(BOOKMARKS_SUBSCRIPTION_YEARLY_PRODUCT_ID),
@(BOOKMARKS_SUBSCRIPTION_MONTHLY_PRODUCT_ID)];
return @[@(BOOKMARKS_SUBSCRIPTION_SIGHTS_YEARLY_PRODUCT_ID),
@(BOOKMARKS_SUBSCRIPTION_SIGHTS_MONTHLY_PRODUCT_ID)];
}
+ (NSString *)allPassSubscriptionServerId

View file

@ -1,7 +1,11 @@
@objc protocol ISubscriptionManager: class{
typealias SuscriptionsCompletion = ([ISubscription]?, Error?) -> Void
typealias ValidationCompletion = (MWMValidationResult) -> Void
var productIds: [String] { get }
var serverId: String { get }
var vendorId: String { get }
@objc static func canMakePayments() -> Bool
@objc func getAvailableSubscriptions(_ completion: @escaping SuscriptionsCompletion)
@objc func subscribe(to subscription: ISubscription)
@ -28,22 +32,18 @@ class SubscriptionManager: NSObject, ISubscriptionManager {
private var listeners = NSHashTable<SubscriptionManagerListener>.weakObjects()
private var restorationCallback: ValidationCompletion?
private var productIds: [String] = []
private var serverId: String = ""
private var vendorId: String = ""
let productIds: [String]
let serverId: String
let vendorId: String
private var purchaseManager: MWMPurchaseManager?
convenience init(productIds: [String], serverId: String, vendorId: String) {
self.init()
init(productIds: [String], serverId: String, vendorId: String) {
self.productIds = productIds
self.serverId = serverId
self.vendorId = vendorId
self.purchaseManager = MWMPurchaseManager(vendorId: vendorId)
}
override private init() {
super.init()
paymentQueue.add(self)
self.purchaseManager = MWMPurchaseManager(vendorId: vendorId)
}
deinit {

View file

@ -390,8 +390,6 @@
4788738F20EE30B300F6826B /* LayersViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4788738D20EE30B300F6826B /* LayersViewController.swift */; };
4788739020EE30B300F6826B /* LayersViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4788738E20EE30B300F6826B /* LayersViewController.xib */; };
4788739220EE326500F6826B /* VerticallyAlignedButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4788739120EE326400F6826B /* VerticallyAlignedButton.swift */; };
4797A4DC226F4B2900D3A984 /* DeepLinkHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4797A4DB226F4B2900D3A984 /* DeepLinkHandler.swift */; };
4797A4E22270997E00D3A984 /* DeepLinkHelper.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4797A4E12270997E00D3A984 /* DeepLinkHelper.mm */; };
479D305722C627CB00D18278 /* MWMMegafonBannerViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 479D305522C627CB00D18278 /* MWMMegafonBannerViewController.xib */; };
479D305B22C62F4000D18278 /* MWMBookmarksBannerViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 479D305922C62F4000D18278 /* MWMBookmarksBannerViewController.xib */; };
479D306122C6634900D18278 /* MWMMegafonBannerViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 479D305F22C6634900D18278 /* MWMMegafonBannerViewController.m */; };
@ -554,6 +552,20 @@
991CE2C02371D349009EB02A /* PromoCampaign.swift in Sources */ = {isa = PBXBuildFile; fileRef = 991CE2BB2371D349009EB02A /* PromoCampaign.swift */; };
991CE2C22371D349009EB02A /* PromoDiscoveryCampaign.swift in Sources */ = {isa = PBXBuildFile; fileRef = 991CE2BE2371D349009EB02A /* PromoDiscoveryCampaign.swift */; };
991CE2DD2373145C009EB02A /* PromoAfterBookingCampaign.swift in Sources */ = {isa = PBXBuildFile; fileRef = 991CE2DC2373145C009EB02A /* PromoAfterBookingCampaign.swift */; };
993F5507237C622700545511 /* DeepLinkSearchStrategy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 993F54F8237C622700545511 /* DeepLinkSearchStrategy.swift */; };
993F5508237C622700545511 /* DeepLinkRouteStrategyAdapter.mm in Sources */ = {isa = PBXBuildFile; fileRef = 993F54F9237C622700545511 /* DeepLinkRouteStrategyAdapter.mm */; };
993F5509237C622700545511 /* DeepLinkHandlerStrategy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 993F54FA237C622700545511 /* DeepLinkHandlerStrategy.swift */; };
993F550A237C622700545511 /* DeepLinkGeoStrategy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 993F54FB237C622700545511 /* DeepLinkGeoStrategy.swift */; };
993F550B237C622700545511 /* DeepLinkIncorrectStrategy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 993F54FC237C622700545511 /* DeepLinkIncorrectStrategy.swift */; };
993F550C237C622700545511 /* DeepLinkSubscriptionStrategy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 993F54FD237C622700545511 /* DeepLinkSubscriptionStrategy.swift */; };
993F550D237C622700545511 /* DeepLinkLeadStrategy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 993F54FE237C622700545511 /* DeepLinkLeadStrategy.swift */; };
993F550E237C622700545511 /* DeepLinkCataloguePathStrategy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 993F54FF237C622700545511 /* DeepLinkCataloguePathStrategy.swift */; };
993F550F237C622700545511 /* DeepLinkMapStrategy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 993F5500237C622700545511 /* DeepLinkMapStrategy.swift */; };
993F5510237C622700545511 /* DeepLinkRouteStrategy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 993F5501237C622700545511 /* DeepLinkRouteStrategy.swift */; };
993F5511237C622700545511 /* DeepLinkCatalogueStrategy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 993F5502237C622700545511 /* DeepLinkCatalogueStrategy.swift */; };
993F5512237C622700545511 /* DeepLinkFileStrategy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 993F5504237C622700545511 /* DeepLinkFileStrategy.swift */; };
993F5513237C622700545511 /* DeepLinkHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 993F5505237C622700545511 /* DeepLinkHandler.swift */; };
993F5514237C622700545511 /* DeepLinkStrategyFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 993F5506237C622700545511 /* DeepLinkStrategyFactory.swift */; };
99425AF4236855BB00D005C0 /* PromoDiscoveryRouter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 99425AF3236855BB00D005C0 /* PromoDiscoveryRouter.swift */; };
99425AFC23685F1E00D005C0 /* PromoDiscoveryPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 99425AFB23685F1E00D005C0 /* PromoDiscoveryPresenter.swift */; };
99536111235DABB1008B218F /* BaseSubscriptionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 99536110235DABB1008B218F /* BaseSubscriptionViewController.swift */; };
@ -563,6 +575,7 @@
995739062355CAC40019AEE7 /* ImageViewCrossDisolve.swift in Sources */ = {isa = PBXBuildFile; fileRef = 995739052355CAC40019AEE7 /* ImageViewCrossDisolve.swift */; };
995739082355CB660019AEE7 /* AllPassSubscriptionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 995739072355CB660019AEE7 /* AllPassSubscriptionViewController.swift */; };
9975225A236B187400ADF673 /* FirstLaunchController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 99752259236B187400ADF673 /* FirstLaunchController.swift */; };
999D3A67237BFA4600C5F7A8 /* SubscriptionViewBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 999D3A66237BFA4600C5F7A8 /* SubscriptionViewBuilder.swift */; };
99B6A74C2362F5AA002C94CB /* PromoButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 99B6A74B2362F5AA002C94CB /* PromoButton.swift */; };
99B6A74E2362F5CD002C94CB /* PromoCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 99B6A74D2362F5CD002C94CB /* PromoCoordinator.swift */; };
99B6A77F23684573002C94CB /* PromoDiscoveryBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 99B6A77E23684573002C94CB /* PromoDiscoveryBuilder.swift */; };
@ -1474,8 +1487,6 @@
4788738E20EE30B300F6826B /* LayersViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = LayersViewController.xib; sourceTree = "<group>"; };
4788739120EE326400F6826B /* VerticallyAlignedButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VerticallyAlignedButton.swift; sourceTree = "<group>"; };
4797A4DB226F4B2900D3A984 /* DeepLinkHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeepLinkHandler.swift; sourceTree = "<group>"; };
4797A4E02270997E00D3A984 /* DeepLinkHelper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DeepLinkHelper.h; sourceTree = "<group>"; };
4797A4E12270997E00D3A984 /* DeepLinkHelper.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = DeepLinkHelper.mm; sourceTree = "<group>"; };
479D305522C627CB00D18278 /* MWMMegafonBannerViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MWMMegafonBannerViewController.xib; sourceTree = "<group>"; };
479D305922C62F4000D18278 /* MWMBookmarksBannerViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MWMBookmarksBannerViewController.xib; sourceTree = "<group>"; };
479D305E22C6634900D18278 /* MWMMegafonBannerViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MWMMegafonBannerViewController.h; sourceTree = "<group>"; };
@ -1602,6 +1613,24 @@
991CE2BB2371D349009EB02A /* PromoCampaign.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PromoCampaign.swift; sourceTree = "<group>"; };
991CE2BE2371D349009EB02A /* PromoDiscoveryCampaign.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PromoDiscoveryCampaign.swift; sourceTree = "<group>"; };
991CE2DC2373145C009EB02A /* PromoAfterBookingCampaign.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PromoAfterBookingCampaign.swift; sourceTree = "<group>"; };
991CE2F92379B86B009EB02A /* DeepLinkHandlerStrategy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeepLinkHandlerStrategy.swift; sourceTree = "<group>"; };
991CE2FB2379B8E5009EB02A /* DeepLinkGeoStrategy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeepLinkGeoStrategy.swift; sourceTree = "<group>"; };
991CE300237AA8C2009EB02A /* DeepLinkStrategyFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeepLinkStrategyFactory.swift; sourceTree = "<group>"; };
993F54F8237C622700545511 /* DeepLinkSearchStrategy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DeepLinkSearchStrategy.swift; sourceTree = "<group>"; };
993F54F9237C622700545511 /* DeepLinkRouteStrategyAdapter.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DeepLinkRouteStrategyAdapter.mm; sourceTree = "<group>"; };
993F54FA237C622700545511 /* DeepLinkHandlerStrategy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DeepLinkHandlerStrategy.swift; sourceTree = "<group>"; };
993F54FB237C622700545511 /* DeepLinkGeoStrategy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DeepLinkGeoStrategy.swift; sourceTree = "<group>"; };
993F54FC237C622700545511 /* DeepLinkIncorrectStrategy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DeepLinkIncorrectStrategy.swift; sourceTree = "<group>"; };
993F54FD237C622700545511 /* DeepLinkSubscriptionStrategy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DeepLinkSubscriptionStrategy.swift; sourceTree = "<group>"; };
993F54FE237C622700545511 /* DeepLinkLeadStrategy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DeepLinkLeadStrategy.swift; sourceTree = "<group>"; };
993F54FF237C622700545511 /* DeepLinkCataloguePathStrategy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DeepLinkCataloguePathStrategy.swift; sourceTree = "<group>"; };
993F5500237C622700545511 /* DeepLinkMapStrategy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DeepLinkMapStrategy.swift; sourceTree = "<group>"; };
993F5501237C622700545511 /* DeepLinkRouteStrategy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DeepLinkRouteStrategy.swift; sourceTree = "<group>"; };
993F5502237C622700545511 /* DeepLinkCatalogueStrategy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DeepLinkCatalogueStrategy.swift; sourceTree = "<group>"; };
993F5503237C622700545511 /* DeepLinkRouteStrategyAdapter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DeepLinkRouteStrategyAdapter.h; sourceTree = "<group>"; };
993F5504237C622700545511 /* DeepLinkFileStrategy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DeepLinkFileStrategy.swift; sourceTree = "<group>"; };
993F5505237C622700545511 /* DeepLinkHandler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DeepLinkHandler.swift; sourceTree = "<group>"; };
993F5506237C622700545511 /* DeepLinkStrategyFactory.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DeepLinkStrategyFactory.swift; sourceTree = "<group>"; };
99425AF3236855BB00D005C0 /* PromoDiscoveryRouter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PromoDiscoveryRouter.swift; sourceTree = "<group>"; };
99425AFB23685F1E00D005C0 /* PromoDiscoveryPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PromoDiscoveryPresenter.swift; sourceTree = "<group>"; };
99536110235DABB1008B218F /* BaseSubscriptionViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseSubscriptionViewController.swift; sourceTree = "<group>"; };
@ -1610,7 +1639,19 @@
995739032355CAA30019AEE7 /* PageIndicator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PageIndicator.swift; sourceTree = "<group>"; };
995739052355CAC40019AEE7 /* ImageViewCrossDisolve.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageViewCrossDisolve.swift; sourceTree = "<group>"; };
995739072355CB660019AEE7 /* AllPassSubscriptionViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AllPassSubscriptionViewController.swift; sourceTree = "<group>"; };
9957FAC6237AADAD00855F48 /* DeepLinkFileStrategy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeepLinkFileStrategy.swift; sourceTree = "<group>"; };
9957FAD0237AB57400855F48 /* DeepLinkRouteStrategy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeepLinkRouteStrategy.swift; sourceTree = "<group>"; };
9957FAD3237ABDFE00855F48 /* DeepLinkRouteStrategyAdapter.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = DeepLinkRouteStrategyAdapter.mm; sourceTree = "<group>"; };
9957FAD7237AC9A400855F48 /* DeepLinkSearchStrategy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeepLinkSearchStrategy.swift; sourceTree = "<group>"; };
9957FAE0237AE04900855F48 /* MWMMapViewControlsManager+AddPlace.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "MWMMapViewControlsManager+AddPlace.h"; sourceTree = "<group>"; };
9957FAE3237AE3CF00855F48 /* DeepLinkCatalogueStrategy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeepLinkCatalogueStrategy.swift; sourceTree = "<group>"; };
9957FAEA237AF22800855F48 /* DeepLinkIncorrectStrategy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeepLinkIncorrectStrategy.swift; sourceTree = "<group>"; };
99752259236B187400ADF673 /* FirstLaunchController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FirstLaunchController.swift; sourceTree = "<group>"; };
999D3A60237B088C00C5F7A8 /* DeepLinkSubscriptionStrategy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeepLinkSubscriptionStrategy.swift; sourceTree = "<group>"; };
999D3A66237BFA4600C5F7A8 /* SubscriptionViewBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubscriptionViewBuilder.swift; sourceTree = "<group>"; };
999D3A68237C0ADD00C5F7A8 /* DeepLinkMapStrategy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeepLinkMapStrategy.swift; sourceTree = "<group>"; };
999D3A6A237C132B00C5F7A8 /* DeepLinkCataloguePathStrategy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeepLinkCataloguePathStrategy.swift; sourceTree = "<group>"; };
999D3A6C237C1C0700C5F7A8 /* DeepLinkLeadStrategy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeepLinkLeadStrategy.swift; sourceTree = "<group>"; };
99B6A74B2362F5AA002C94CB /* PromoButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PromoButton.swift; sourceTree = "<group>"; };
99B6A74D2362F5CD002C94CB /* PromoCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PromoCoordinator.swift; sourceTree = "<group>"; };
99B6A77E23684573002C94CB /* PromoDiscoveryBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PromoDiscoveryBuilder.swift; sourceTree = "<group>"; };
@ -2222,9 +2263,6 @@
340837101B7243B500B5C185 /* Share */,
F6588E291B15C25C00EE1E58 /* TextView */,
34FE4C421BCC013500066718 /* Widgets */,
4797A4DB226F4B2900D3A984 /* DeepLinkHandler.swift */,
4797A4E02270997E00D3A984 /* DeepLinkHelper.h */,
4797A4E12270997E00D3A984 /* DeepLinkHelper.mm */,
);
path = Classes;
sourceTree = "<group>";
@ -2259,6 +2297,7 @@
29B97317FDCFA39411CA2CEA /* Resources */,
F6E2FBFB1E097B9F0083EBEC /* UI */,
044715AD432F538B6F731670 /* Pods */,
993F54EB237C5CD800545511 /* Recovered References */,
);
indentWidth = 2;
name = Maps;
@ -2494,6 +2533,7 @@
340475281E081A4600C92850 /* Core */ = {
isa = PBXGroup;
children = (
993F54F6237C622700545511 /* DeepLink */,
991CE2B92371D349009EB02A /* PromoCampaign */,
CDCA27822245090900167D87 /* EventListening */,
47B9064821C7FA100079C85E /* WebImage */,
@ -2796,6 +2836,7 @@
47699A0621F08E37009E6585 /* NSDate+TimeDistance.h */,
47699A0721F08E37009E6585 /* NSDate+TimeDistance.m */,
99E2B0112368A8C700FFABC5 /* MWMCategory+PlacesCountTitle.swift */,
9957FAE0237AE04900855F48 /* MWMMapViewControlsManager+AddPlace.h */,
);
path = Categories;
sourceTree = "<group>";
@ -3646,6 +3687,57 @@
path = PromoAfterBookingCampaign;
sourceTree = "<group>";
};
993F54EB237C5CD800545511 /* Recovered References */ = {
isa = PBXGroup;
children = (
9957FAD3237ABDFE00855F48 /* DeepLinkRouteStrategyAdapter.mm */,
991CE2F92379B86B009EB02A /* DeepLinkHandlerStrategy.swift */,
9957FAC6237AADAD00855F48 /* DeepLinkFileStrategy.swift */,
4797A4DB226F4B2900D3A984 /* DeepLinkHandler.swift */,
9957FAEA237AF22800855F48 /* DeepLinkIncorrectStrategy.swift */,
991CE300237AA8C2009EB02A /* DeepLinkStrategyFactory.swift */,
999D3A68237C0ADD00C5F7A8 /* DeepLinkMapStrategy.swift */,
9957FAD7237AC9A400855F48 /* DeepLinkSearchStrategy.swift */,
999D3A6A237C132B00C5F7A8 /* DeepLinkCataloguePathStrategy.swift */,
991CE2FB2379B8E5009EB02A /* DeepLinkGeoStrategy.swift */,
999D3A6C237C1C0700C5F7A8 /* DeepLinkLeadStrategy.swift */,
9957FAD0237AB57400855F48 /* DeepLinkRouteStrategy.swift */,
999D3A60237B088C00C5F7A8 /* DeepLinkSubscriptionStrategy.swift */,
9957FAE3237AE3CF00855F48 /* DeepLinkCatalogueStrategy.swift */,
);
name = "Recovered References";
sourceTree = "<group>";
};
993F54F6237C622700545511 /* DeepLink */ = {
isa = PBXGroup;
children = (
993F54F7237C622700545511 /* Strategies */,
993F5505237C622700545511 /* DeepLinkHandler.swift */,
993F5506237C622700545511 /* DeepLinkStrategyFactory.swift */,
);
path = DeepLink;
sourceTree = "<group>";
};
993F54F7237C622700545511 /* Strategies */ = {
isa = PBXGroup;
children = (
993F54F8237C622700545511 /* DeepLinkSearchStrategy.swift */,
993F54F9237C622700545511 /* DeepLinkRouteStrategyAdapter.mm */,
993F5503237C622700545511 /* DeepLinkRouteStrategyAdapter.h */,
993F54FA237C622700545511 /* DeepLinkHandlerStrategy.swift */,
993F54FB237C622700545511 /* DeepLinkGeoStrategy.swift */,
993F54FC237C622700545511 /* DeepLinkIncorrectStrategy.swift */,
993F54FD237C622700545511 /* DeepLinkSubscriptionStrategy.swift */,
993F54FE237C622700545511 /* DeepLinkLeadStrategy.swift */,
993F54FF237C622700545511 /* DeepLinkCataloguePathStrategy.swift */,
993F5500237C622700545511 /* DeepLinkMapStrategy.swift */,
993F5501237C622700545511 /* DeepLinkRouteStrategy.swift */,
993F5502237C622700545511 /* DeepLinkCatalogueStrategy.swift */,
993F5504237C622700545511 /* DeepLinkFileStrategy.swift */,
);
path = Strategies;
sourceTree = "<group>";
};
995738D9235481FE0019AEE7 /* Subscription */ = {
isa = PBXGroup;
children = (
@ -3656,6 +3748,7 @@
995738DA235484410019AEE7 /* AllPassSubscriptionViewController.xib */,
995739072355CB660019AEE7 /* AllPassSubscriptionViewController.swift */,
99536110235DABB1008B218F /* BaseSubscriptionViewController.swift */,
999D3A66237BFA4600C5F7A8 /* SubscriptionViewBuilder.swift */,
);
path = Subscription;
sourceTree = "<group>";
@ -5339,6 +5432,7 @@
3404F48B202894EA0090E401 /* BMCViewController.swift in Sources */,
349D1ABC1E2D05EF004A2006 /* SearchBar.swift in Sources */,
F6E2FD7A1E097BA00083EBEC /* MWMMapDownloaderDefaultDataSource.mm in Sources */,
993F5511237C622700545511 /* DeepLinkCatalogueStrategy.swift in Sources */,
34E50DF81F6FCC96008EED49 /* UGCReviewCell.swift in Sources */,
F6E2FF3F1E097BA00083EBEC /* MWMSearchTableViewController.mm in Sources */,
F6E2FDE01E097BA00083EBEC /* MWMEditorViewController.mm in Sources */,
@ -5354,6 +5448,7 @@
F6E2FE4C1E097BA00083EBEC /* MWMPlacePageManager.mm in Sources */,
3404757E1E081B3300C92850 /* iosOGLContext.mm in Sources */,
34763F071F3092E700F4D2D3 /* String+Format.swift in Sources */,
993F5513237C622700545511 /* DeepLinkHandler.swift in Sources */,
346DB83A1E5C4F6700E3123E /* GalleryItemModel.swift in Sources */,
F6E2FD5C1E097BA00083EBEC /* MWMMapDownloaderCellHeader.m in Sources */,
CDCA278E2248F34C00167D87 /* MWMRoutingManager.mm in Sources */,
@ -5382,6 +5477,7 @@
34ABA62D1C2D57D500FE1BEC /* MWMInputPasswordValidator.m in Sources */,
BBED27022292F6C000788143 /* BookmarksSection.mm in Sources */,
F6E2FDA11E097BA00083EBEC /* MWMEditorAdditionalNamesTableViewController.mm in Sources */,
999D3A67237BFA4600C5F7A8 /* SubscriptionViewBuilder.swift in Sources */,
4767CDA620AB1F6200BD8166 /* LeftAlignedIconButton.swift in Sources */,
3454D7D41E07F045004AF2AD /* UIImageView+Coloring.m in Sources */,
3463BA671DE81DB90082417F /* MWMTrafficButtonViewController.mm in Sources */,
@ -5509,6 +5605,7 @@
34F407321E9E1AFF00E57AC0 /* BannerType.swift in Sources */,
F63AF5131EA6250F00A1DB98 /* FilterCollectionHolderCell.swift in Sources */,
34AB663E1FC5AA330078E451 /* RouteManagerTransitioning.swift in Sources */,
993F550B237C622700545511 /* DeepLinkIncorrectStrategy.swift in Sources */,
34BBD65C1F826FD30070CA50 /* AuthorizationiPhonePresentationController.swift in Sources */,
56C74C391C74A3BC00B71B9F /* MWMInputEmailValidator.m in Sources */,
6741A9F51BF340DE002C974C /* BookmarksVC.mm in Sources */,
@ -5518,8 +5615,8 @@
99CB34C5236B00FD001D28AD /* WelcomeStorage.swift in Sources */,
CDB92CF1229EB8A800EC757C /* MWMDiscoverySearchViewModel.m in Sources */,
34AB662F1FC5AA330078E451 /* RouteManageriPhonePresentationController.swift in Sources */,
993F5508237C622700545511 /* DeepLinkRouteStrategyAdapter.mm in Sources */,
BB87BF8D22FAF435008A8A72 /* InfoSection.mm in Sources */,
4797A4DC226F4B2900D3A984 /* DeepLinkHandler.swift in Sources */,
34AB66201FC5AA330078E451 /* RouteStartButton.swift in Sources */,
34F4072C1E9E1AFF00E57AC0 /* Banner.swift in Sources */,
F660DEE51EAF4F59004DC056 /* MWMLocationManager+SpeedAndAltitude.swift in Sources */,
@ -5565,6 +5662,7 @@
340416581E7C0D4100E2B6D6 /* PhotosOverlayView.swift in Sources */,
F6E2FE821E097BA00083EBEC /* MWMPlacePageOpeningHoursDayView.m in Sources */,
340FDC092031C39E00F140AD /* BMCPermissionsPendingCell.swift in Sources */,
993F550C237C622700545511 /* DeepLinkSubscriptionStrategy.swift in Sources */,
F6E2FD6B1E097BA00083EBEC /* MWMMapDownloaderSubplaceTableViewCell.mm in Sources */,
CDCA27842245090900167D87 /* ListenerContainer.swift in Sources */,
47E3C7252111E41B008B3B27 /* DimmedModalPresentationController.swift in Sources */,
@ -5580,6 +5678,7 @@
6741AA031BF340DE002C974C /* MWMActivityViewController.mm in Sources */,
F6E2FE9D1E097BA00083EBEC /* MWMiPhonePlacePageLayoutImpl.mm in Sources */,
CDCA27382237F1BD00167D87 /* BookmarkInfo.swift in Sources */,
993F5509237C622700545511 /* DeepLinkHandlerStrategy.swift in Sources */,
34AB668C1FC5AA330078E451 /* NavigationStreetNameView.swift in Sources */,
3454D7C81E07F045004AF2AD /* UIButton+RuntimeAttributes.m in Sources */,
337F98A621D37B7400C8AC27 /* SearchTabViewController.swift in Sources */,
@ -5602,6 +5701,7 @@
3454D7BC1E07F045004AF2AD /* CLLocation+Mercator.mm in Sources */,
47E3C7272111E5A8008B3B27 /* AlertPresentationController.swift in Sources */,
F6E2FF4E1E097BA00083EBEC /* MWMAboutController.m in Sources */,
993F5512237C622700545511 /* DeepLinkFileStrategy.swift in Sources */,
47B06DF921B95F5E0094CCAD /* IGeoTracker.swift in Sources */,
CDCA27812243F59800167D87 /* CarPlayRouter.swift in Sources */,
34F407381E9E1AFF00E57AC0 /* FacebookBanner.swift in Sources */,
@ -5651,6 +5751,7 @@
34943BBB1E2626B200B14F84 /* WelcomePageController.swift in Sources */,
34D3AFE21E376F7E004100F9 /* UITableView+Updates.swift in Sources */,
3404164C1E7BF42E00E2B6D6 /* UIView+Coordinates.swift in Sources */,
993F5510237C622700545511 /* DeepLinkRouteStrategy.swift in Sources */,
349D1ADB1E2E325C004A2006 /* MWMBottomMenuView.m in Sources */,
344BEAF61F66BDC30045DC45 /* RatingSummaryViewSettings.swift in Sources */,
F6E2FD921E097BA00083EBEC /* MWMBookmarkColorViewController.mm in Sources */,
@ -5659,9 +5760,11 @@
347752881F725002000D46A3 /* UGCAddReviewRatingCell.swift in Sources */,
47E3C7332111F4D8008B3B27 /* CoverVerticalDismissalAnimator.swift in Sources */,
99E2B01E23698B0800FFABC5 /* WelcomeProtocols.swift in Sources */,
993F550F237C622700545511 /* DeepLinkMapStrategy.swift in Sources */,
34AB661A1FC5AA330078E451 /* MWMTaxiCollectionLayout.m in Sources */,
345C2F8A1F86361B009DB8B4 /* MWMUGCViewModel.mm in Sources */,
33F8BA4E2199AB9500ECA8EE /* TagsDataSource.swift in Sources */,
993F5507237C622700545511 /* DeepLinkSearchStrategy.swift in Sources */,
47F67D1521CAB21B0069754E /* MWMImageCoder.m in Sources */,
34AB66861FC5AA330078E451 /* MWMNavigationInfoView.mm in Sources */,
34C9BD051C6DB693000DC38D /* MWMViewController.m in Sources */,
@ -5680,6 +5783,7 @@
340475711E081A4600C92850 /* MWMSettings.mm in Sources */,
33046832219C57180041F3A8 /* CategorySettingsViewController.swift in Sources */,
3404165C1E7C29AE00E2B6D6 /* PhotosInteractionAnimator.swift in Sources */,
993F550E237C622700545511 /* DeepLinkCataloguePathStrategy.swift in Sources */,
34E50DE01F6FCBA1008EED49 /* UGCAddReviewCell.swift in Sources */,
3404756E1E081A4600C92850 /* MWMSearch.mm in Sources */,
6741AA191BF340DE002C974C /* MWMDownloaderDialogCell.m in Sources */,
@ -5718,6 +5822,7 @@
F69CE8D61E5C49B4002B5881 /* PPHotelCarouselCell.swift in Sources */,
47B9065321C7FA400079C85E /* MWMImageCache.m in Sources */,
472C40E8232BA810009AA777 /* CatalogPromoItem.m in Sources */,
993F550A237C622700545511 /* DeepLinkGeoStrategy.swift in Sources */,
F6FEA82E1C58F108007223CC /* MWMButton.m in Sources */,
3445324E1F714FD70059FBCC /* UGCAddReviewController.swift in Sources */,
34B924431DC8A29C0008D971 /* MWMMailViewController.m in Sources */,
@ -5737,11 +5842,11 @@
34E50DD81F6FCAB1008EED49 /* UGCSummaryRatingCell.swift in Sources */,
6741AA281BF340DE002C974C /* MWMAlert.mm in Sources */,
F6E2FF571E097BA00083EBEC /* MWMMobileInternetViewController.m in Sources */,
4797A4E22270997E00D3A984 /* DeepLinkHelper.mm in Sources */,
47B06E0021BAAC270094CCAD /* GeoZoneTracker.swift in Sources */,
3404F4952028A1B80090E401 /* BMCPermissionsCell.swift in Sources */,
340416441E7BED3900E2B6D6 /* PhotosTransitionAnimator.swift in Sources */,
34AB66261FC5AA330078E451 /* RouteManagerDimView.swift in Sources */,
993F5514237C622700545511 /* DeepLinkStrategyFactory.swift in Sources */,
6741AA291BF340DE002C974C /* ColorPickerView.mm in Sources */,
6741AA2B1BF340DE002C974C /* CircleView.m in Sources */,
F6E2FEEB1E097BA00083EBEC /* MWMSearchTextField.mm in Sources */,
@ -5753,6 +5858,7 @@
3451F4EE1F026DAF00A981F2 /* PlacePageTaxiCell.swift in Sources */,
3467CEB6202C6FA900D3C670 /* BMCNotificationsCell.swift in Sources */,
34B846A32029DFEB0081ECCD /* BMCPermissionsHeader.swift in Sources */,
993F550D237C622700545511 /* DeepLinkLeadStrategy.swift in Sources */,
F6E2FD9E1E097BA00083EBEC /* MWMEditBookmarkController.mm in Sources */,
337F98B221D3BAE600C8AC27 /* SearchCategoriesViewController.swift in Sources */,
47B06DED21B696C20094CCAD /* GeoTracker.swift in Sources */,

View file

@ -10,6 +10,7 @@
#import "MWMSearchManager+Filter.h"
#import "MWMStorage.h"
#import "SwiftBridge.h"
#import "MWMMapViewControlsManager+AddPlace.h"
#import <CoreApi/CoreApi.h>

View file

@ -1,5 +1,6 @@
#import "MWMMapViewControlsManager.h"
#import "MWMPlacePageButtonsProtocol.h"
#include "geometry/point2d.hpp"
@class MWMViewController;

View file

@ -3,7 +3,7 @@ class DeepLinkInfoBuilder {
let sb = UIStoryboard.instance(.welcome)
let vc = sb.instantiateViewController(ofType: WelcomeViewController.self);
let deeplinkUrl = DeepLinkHandler.shared.deeplinkURL
let deeplinkUrl = DeepLinkHandler.shared.deeplinkURL?.url
let router = DeepLinkInfoRouter(viewController: vc,
delegate: delegate,
deeplink: deeplinkUrl)

View file

@ -40,19 +40,14 @@ extension PromoDiscoveryRouter: IPromoDiscoveryRouter {
}
private func presentPromoDiscoverySubscribe() {
let subscribeViewController = AllPassSubscriptionViewController()
subscribeViewController.onSubscribe = { [weak self] in
self?.rootViewController?.dismiss(animated: true)
let successDialog = SubscriptionSuccessViewController(.allPass) { [weak self] in
self?.rootViewController?.dismiss(animated: true)
}
self?.rootViewController?.present(successDialog, animated: true)
guard let viewController = viewController else {
return;
}
subscribeViewController.onCancel = { [weak self] in
self?.rootViewController?.dismiss(animated: true)
}
viewController?.present(subscribeViewController, animated: true)
let subscribeViewController = SubscriptionViewBuilder.build(type: .allPass,
parentViewController: viewController,
source: kStatOnboardingGuidesSubscription,
completion: nil)
viewController.present(subscribeViewController, animated: true)
}
private func presentPromoDiscoveryFree() {

View file

@ -2260,6 +2260,11 @@ url_scheme::SearchRequest Framework::GetParsedSearchRequest() const
return m_ParsedMapApi.GetSearchRequest();
}
url_scheme::Subscription Framework::GetParsedSubscription() const
{
return m_ParsedMapApi.GetSubscription();
}
FeatureID Framework::GetFeatureAtPoint(m2::PointD const & mercator,
FeatureMatcher && matcher /* = nullptr */) const
{

View file

@ -678,6 +678,7 @@ public:
ParsedRoutingData GetParsedRoutingData() const;
url_scheme::SearchRequest GetParsedSearchRequest() const;
url_scheme::Subscription GetParsedSubscription() const;
using FeatureMatcher = std::function<bool(FeatureType & ft)>;

View file

@ -58,7 +58,7 @@ public:
return m_m->GetUserMarkIds(type).size();
}
CatalogItem const & GetCatalogItem() const { return m_api.GetCatalogItem(); }
Catalog const & GetCatalogItem() const { return m_api.GetCatalogItem(); }
vector<RoutePoint> GetRoutePoints() const { return m_api.GetRoutePoints(); }
url_scheme::SearchRequest const & GetSearchRequest() const { return m_api.GetSearchRequest(); }
string const & GetGlobalBackUrl() const { return m_api.GetGlobalBackUrl(); }

View file

@ -101,10 +101,15 @@ char const * kId = "id";
char const * kName = "name";
} // namespace catalogue
namespace cataloguePath
namespace catalogue_path
{
char const * kUrl = "url";
} // namespace cataloguePath
} // namespace catalogue_path
namespace subscription
{
char const * kDeliverable = "deliverable";
} // namespace subscription
namespace
{
@ -116,7 +121,8 @@ enum class ApiURLType
Search,
Lead,
Catalogue,
CataloguePath
CataloguePath,
Subscription
};
std::array<std::string, 3> const kAvailableSchemes = {{"mapswithme", "mwm", "mapsme"}};
@ -139,6 +145,8 @@ ApiURLType URLType(Uri const & uri)
return ApiURLType::Catalogue;
if (path == "guides_page")
return ApiURLType::CataloguePath;
if (path == "subscription")
return ApiURLType::Subscription;
return ApiURLType::Incorrect;
}
@ -201,10 +209,8 @@ ParsedMapApi::ParsingResult ParsedMapApi::Parse(Uri const & uri)
{
return AddKeyValue(key, value, points);
});
if (!result)
return ParsingResult::Incorrect;
if (points.empty())
if (!result || points.empty())
return ParsingResult::Incorrect;
ASSERT(m_bmManager != nullptr, ());
@ -230,10 +236,7 @@ ParsedMapApi::ParsingResult ParsedMapApi::Parse(Uri const & uri)
return RouteKeyValue(key, value, pattern);
});
if (!result)
return ParsingResult::Incorrect;
if (pattern.size() != 0)
if (!result || pattern.size() != 0)
return ParsingResult::Incorrect;
if (m_routePoints.size() != 2)
@ -264,10 +267,8 @@ ParsedMapApi::ParsingResult ParsedMapApi::Parse(Uri const & uri)
{
return LeadKeyValue(key, value, description);
});
if (!result)
return ParsingResult::Incorrect;
if (!description.IsValid())
if (!result || !description.IsValid())
return ParsingResult::Incorrect;
description.Write();
@ -275,38 +276,46 @@ ParsedMapApi::ParsingResult ParsedMapApi::Parse(Uri const & uri)
}
case ApiURLType::Catalogue:
{
CatalogItem item;
Catalog item;
auto const result = uri.ForEachKeyValue([&item, this](string const & key, string const & value)
{
return CatalogKeyValue(key, value, item);
});
if (!result)
if (!result || item.m_id.empty())
return ParsingResult::Incorrect;
if (item.m_id.empty())
return ParsingResult::Incorrect;
m_catalogItem = item;
m_catalog = item;
return ParsingResult::Catalogue;
}
case ApiURLType::CataloguePath:
{
CatalogPathItem item;
CatalogPath item;
auto const result = uri.ForEachKeyValue([&item, this](string const & key, string const & value)
{
return CatalogPathKeyValue(key, value, item);
});
if (!result)
if (!result || item.m_url.empty())
return ParsingResult::Incorrect;
if (item.m_url.empty())
return ParsingResult::Incorrect;
m_catalogPathItem = item;
m_catalogPath = item;
return ParsingResult::CataloguePath;
}
case ApiURLType::Subscription:
{
Subscription item;
auto const result = uri.ForEachKeyValue([&item, this](string const & key, string const & value)
{
return SubscriptionKeyValue(key, value, item);
});
if (!result || item.m_deliverable.empty())
return ParsingResult::Incorrect;
m_subscription = item;
return ParsingResult::Subscription;
}
}
UNREACHABLE();
}
@ -484,7 +493,7 @@ bool ParsedMapApi::LeadKeyValue(string const & key, string const & value, lead::
return true;
}
bool ParsedMapApi::CatalogKeyValue(string const & key, string const & value, CatalogItem & item) const
bool ParsedMapApi::CatalogKeyValue(string const & key, string const & value, Catalog & item) const
{
using namespace catalogue;
@ -496,16 +505,22 @@ bool ParsedMapApi::CatalogKeyValue(string const & key, string const & value, Cat
return true;
}
bool ParsedMapApi::CatalogPathKeyValue(string const & key, string const & value, CatalogPathItem & item) const
bool ParsedMapApi::CatalogPathKeyValue(string const & key, string const & value, CatalogPath & item) const
{
using namespace cataloguePath;
if (key == kUrl)
if (key == catalogue_path::kUrl)
item.m_url = value;
return true;
}
bool ParsedMapApi::SubscriptionKeyValue(string const & key, string const & value, Subscription & item) const
{
if (key == subscription::kDeliverable)
item.m_deliverable = value;
return true;
}
void ParsedMapApi::Reset()
{
m_globalBackUrl.clear();

View file

@ -37,17 +37,22 @@ struct SearchRequest
bool m_isSearchOnMap = false;
};
struct CatalogItem
struct Catalog
{
std::string m_id;
std::string m_name;
};
struct CatalogPathItem
struct CatalogPath
{
std::string m_url;
};
struct Subscription
{
std::string m_deliverable;
};
namespace lead
{
struct CampaignDescription;
@ -67,7 +72,8 @@ public:
Search,
Lead,
Catalogue,
CataloguePath
CataloguePath,
Subscription
};
ParsedMapApi() = default;
@ -88,22 +94,25 @@ public:
std::vector<RoutePoint> const & GetRoutePoints() const { return m_routePoints; }
std::string const & GetRoutingType() const { return m_routingType; }
SearchRequest const & GetSearchRequest() const { return m_request; }
CatalogItem const & GetCatalogItem() const { return m_catalogItem; }
CatalogPathItem const & GetCatalogPathItem() const { return m_catalogPathItem; }
Catalog const & GetCatalog() const { return m_catalog; }
CatalogPath const & GetCatalogPath() const { return m_catalogPath; }
Subscription const & GetSubscription() const { return m_subscription; }
private:
ParsingResult Parse(Uri const & uri);
bool AddKeyValue(std::string const & key, std::string const & value, std::vector<ApiPoint> & points);
bool RouteKeyValue(std::string const & key, std::string const & value, std::vector<std::string> & pattern);
bool SearchKeyValue(std::string const & key, std::string const & value, SearchRequest & request) const;
bool LeadKeyValue(std::string const & key, std::string const & value, lead::CampaignDescription & description) const;
bool CatalogKeyValue(std::string const & key, std::string const & value, CatalogItem & item) const;
bool CatalogPathKeyValue(std::string const & key, std::string const & value, CatalogPathItem & item) const;
bool CatalogKeyValue(std::string const & key, std::string const & value, Catalog & item) const;
bool CatalogPathKeyValue(std::string const & key, std::string const & value, CatalogPath & item) const;
bool SubscriptionKeyValue(std::string const & key, std::string const & value, Subscription & item) const;
BookmarkManager * m_bmManager = nullptr;
std::vector<RoutePoint> m_routePoints;
SearchRequest m_request;
CatalogItem m_catalogItem;
CatalogPathItem m_catalogPathItem;
Catalog m_catalog;
CatalogPath m_catalogPath;
Subscription m_subscription;
std::string m_globalBackUrl;
std::string m_appTitle;
std::string m_routingType;