diff --git a/iphone/CoreApi/CoreApi.xcodeproj/project.pbxproj b/iphone/CoreApi/CoreApi.xcodeproj/project.pbxproj index 25db86afbb..8516f92946 100644 --- a/iphone/CoreApi/CoreApi.xcodeproj/project.pbxproj +++ b/iphone/CoreApi/CoreApi.xcodeproj/project.pbxproj @@ -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 = ""; }; 47EEAFF32350CEDB005CF316 /* AppInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppInfo.h; sourceTree = ""; }; 47EEAFF52350CEF6005CF316 /* MWMCommon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMCommon.h; sourceTree = ""; }; + 99103841237EDFA200893C9F /* DeepLinkData.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DeepLinkData.h; sourceTree = ""; }; + 99103842237EDFA200893C9F /* DeepLinkData.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DeepLinkData.m; sourceTree = ""; }; 991CE2E82375AF19009EB02A /* PromoAfterBookingCampaignAdapter.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = PromoAfterBookingCampaignAdapter.mm; sourceTree = ""; }; 991CE2E92375AF19009EB02A /* PromoAfterBookingCampaignAdapter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PromoAfterBookingCampaignAdapter.h; sourceTree = ""; }; 991CE2EC2375AF25009EB02A /* PromoDiscoveryCampaignAdapter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PromoDiscoveryCampaignAdapter.h; sourceTree = ""; }; 991CE2ED2375AF25009EB02A /* PromoDiscoveryCampaignAdapter.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = PromoDiscoveryCampaignAdapter.mm; sourceTree = ""; }; + 993F54EE237C5D1000545511 /* PromoDiscoveryCampaignAdapter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PromoDiscoveryCampaignAdapter.h; sourceTree = ""; }; + 993F54EF237C5D1000545511 /* PromoAfterBookingCampaignAdapter.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = PromoAfterBookingCampaignAdapter.mm; sourceTree = ""; }; + 993F54F0237C5D1000545511 /* PromoDiscoveryCampaignAdapter.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = PromoDiscoveryCampaignAdapter.mm; sourceTree = ""; }; + 993F54F1237C5D1000545511 /* PromoAfterBookingCampaignAdapter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PromoAfterBookingCampaignAdapter.h; sourceTree = ""; }; + 99447847238559F2004DAEE5 /* DeeplinkParsingResult.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DeeplinkParsingResult.h; sourceTree = ""; }; + 9957FACC237AB01400855F48 /* DeepLinkParser.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DeepLinkParser.h; sourceTree = ""; }; + 9957FACD237AB01400855F48 /* DeepLinkParser.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = DeepLinkParser.mm; sourceTree = ""; }; + 9957FAD9237ACB1100855F48 /* DeepLinkSearchData.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DeepLinkSearchData.h; sourceTree = ""; }; + 9957FADA237ACB1100855F48 /* DeepLinkSearchData.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = DeepLinkSearchData.mm; sourceTree = ""; }; + 9957FAE6237AE5B000855F48 /* Logger.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Logger.h; sourceTree = ""; }; + 9957FAE7237AE5B000855F48 /* Logger.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = Logger.mm; sourceTree = ""; }; + 999D3A62237B097C00C5F7A8 /* DeepLinkSubscriptionData.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DeepLinkSubscriptionData.h; sourceTree = ""; }; + 999D3A63237B097C00C5F7A8 /* DeepLinkSubscriptionData.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = DeepLinkSubscriptionData.mm; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -122,6 +148,7 @@ 470015F12342509C00EBF03D /* CoreApi */, 470015F02342509C00EBF03D /* Products */, 4700161123425CFC00EBF03D /* Frameworks */, + 993F54EC237C5CD800545511 /* Recovered References */, ); sourceTree = ""; }; @@ -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 = ""; }; - 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 = ""; + }; + 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 = ""; + }; + 993F54ED237C5D1000545511 /* Promo */ = { + isa = PBXGroup; + children = ( + 993F54EE237C5D1000545511 /* PromoDiscoveryCampaignAdapter.h */, + 993F54EF237C5D1000545511 /* PromoAfterBookingCampaignAdapter.mm */, + 993F54F0237C5D1000545511 /* PromoDiscoveryCampaignAdapter.mm */, + 993F54F1237C5D1000545511 /* PromoAfterBookingCampaignAdapter.h */, ); path = Promo; sourceTree = ""; }; + 9957FAC1237AABD800855F48 /* DeepLink */ = { + isa = PBXGroup; + children = ( + 99103840237ED97600893C9F /* Data */, + 9957FACC237AB01400855F48 /* DeepLinkParser.h */, + 9957FACD237AB01400855F48 /* DeepLinkParser.mm */, + ); + path = DeepLink; + sourceTree = ""; + }; + 9957FAE5237AE59C00855F48 /* Logger */ = { + isa = PBXGroup; + children = ( + 9957FAE6237AE5B000855F48 /* Logger.h */, + 9957FAE7237AE5B000855F48 /* Logger.mm */, + ); + path = Logger; + sourceTree = ""; + }; /* 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; }; diff --git a/iphone/CoreApi/CoreApi/CoreApi-swift.h b/iphone/CoreApi/CoreApi/CoreApi-swift.h index e284fdfe49..6a03c5b73e 100644 --- a/iphone/CoreApi/CoreApi/CoreApi-swift.h +++ b/iphone/CoreApi/CoreApi/CoreApi-swift.h @@ -21,3 +21,7 @@ FOUNDATION_EXPORT const unsigned char CoreApiVersionString[]; #import #import #import +#import +#import +#import +#import diff --git a/iphone/CoreApi/CoreApi/DeepLink/Data/DeepLinkData.h b/iphone/CoreApi/CoreApi/DeepLink/Data/DeepLinkData.h new file mode 100644 index 0000000000..18816648a4 --- /dev/null +++ b/iphone/CoreApi/CoreApi/DeepLink/Data/DeepLinkData.h @@ -0,0 +1,30 @@ +#import + +NS_ASSUME_NONNULL_BEGIN + +typedef NS_ENUM(NSUInteger, DeeplinkParsingResult) { + DeeplinkParsingResultIncorrect = 0, + DeeplinkParsingResultMap, + DeeplinkParsingResultRoute, + DeeplinkParsingResultSearch, + DeeplinkParsingResultLead, + DeeplinkParsingResultCatalogue, + DeeplinkParsingResultCataloguePath, + DeeplinkParsingResultSubscription +}; + +@protocol IDeepLinkData + +@property (nonatomic, readonly) DeeplinkParsingResult result; + +@end + +@interface DeepLinkData : NSObject + +@property (nonatomic, readonly) DeeplinkParsingResult result; + +- (instancetype)init:(DeeplinkParsingResult)result; + +@end + +NS_ASSUME_NONNULL_END diff --git a/iphone/CoreApi/CoreApi/DeepLink/Data/DeepLinkData.m b/iphone/CoreApi/CoreApi/DeepLink/Data/DeepLinkData.m new file mode 100644 index 0000000000..aa21503f5c --- /dev/null +++ b/iphone/CoreApi/CoreApi/DeepLink/Data/DeepLinkData.m @@ -0,0 +1,13 @@ +#import "DeepLinkData.h" + +@implementation DeepLinkData + +- (instancetype)init:(DeeplinkParsingResult)result { + self = [super init]; + if (self) { + _result = result; + } + return self; +} + +@end diff --git a/iphone/CoreApi/CoreApi/DeepLink/Data/DeepLinkSearchData.h b/iphone/CoreApi/CoreApi/DeepLink/Data/DeepLinkSearchData.h new file mode 100644 index 0000000000..395c245d30 --- /dev/null +++ b/iphone/CoreApi/CoreApi/DeepLink/Data/DeepLinkSearchData.h @@ -0,0 +1,19 @@ +#import +#import "DeepLinkData.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface DeepLinkSearchData : NSObject + +@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 diff --git a/iphone/CoreApi/CoreApi/DeepLink/Data/DeepLinkSearchData.mm b/iphone/CoreApi/CoreApi/DeepLink/Data/DeepLinkSearchData.mm new file mode 100644 index 0000000000..257641ffcb --- /dev/null +++ b/iphone/CoreApi/CoreApi/DeepLink/Data/DeepLinkSearchData.mm @@ -0,0 +1,26 @@ +#import "DeepLinkSearchData.h" +#import +#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 diff --git a/iphone/CoreApi/CoreApi/DeepLink/Data/DeepLinkSubscriptionData.h b/iphone/CoreApi/CoreApi/DeepLink/Data/DeepLinkSubscriptionData.h new file mode 100644 index 0000000000..cd4beeea45 --- /dev/null +++ b/iphone/CoreApi/CoreApi/DeepLink/Data/DeepLinkSubscriptionData.h @@ -0,0 +1,15 @@ +#import +#import "DeepLinkData.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface DeepLinkSubscriptionData : NSObject + +@property (nonatomic, readonly) DeeplinkParsingResult result; +@property(nonatomic, readonly) NSString* deliverable; + +- (instancetype)init:(DeeplinkParsingResult)result; + +@end + +NS_ASSUME_NONNULL_END diff --git a/iphone/CoreApi/CoreApi/DeepLink/Data/DeepLinkSubscriptionData.mm b/iphone/CoreApi/CoreApi/DeepLink/Data/DeepLinkSubscriptionData.mm new file mode 100644 index 0000000000..8143c392e9 --- /dev/null +++ b/iphone/CoreApi/CoreApi/DeepLink/Data/DeepLinkSubscriptionData.mm @@ -0,0 +1,16 @@ +#import "DeepLinkSubscriptionData.h" +#import + +@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 diff --git a/iphone/CoreApi/CoreApi/DeepLink/Data/DeeplinkParsingResult.h b/iphone/CoreApi/CoreApi/DeepLink/Data/DeeplinkParsingResult.h new file mode 100644 index 0000000000..407306e22a --- /dev/null +++ b/iphone/CoreApi/CoreApi/DeepLink/Data/DeeplinkParsingResult.h @@ -0,0 +1,21 @@ +#import +#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 diff --git a/iphone/CoreApi/CoreApi/DeepLink/DeepLinkParser.h b/iphone/CoreApi/CoreApi/DeepLink/DeepLinkParser.h new file mode 100644 index 0000000000..70cbd7abe7 --- /dev/null +++ b/iphone/CoreApi/CoreApi/DeepLink/DeepLinkParser.h @@ -0,0 +1,14 @@ +#import + +NS_ASSUME_NONNULL_BEGIN + +@protocol IDeepLinkData; + +@interface DeepLinkParser : NSObject + ++ (id)parseAndSetApiURL:(NSURL*)url; ++ (bool)showMapForUrl:(NSURL*)url; ++ (void)addBookmarksFile:(NSURL*)url; +@end + +NS_ASSUME_NONNULL_END diff --git a/iphone/CoreApi/CoreApi/DeepLink/DeepLinkParser.mm b/iphone/CoreApi/CoreApi/DeepLink/DeepLinkParser.mm new file mode 100644 index 0000000000..152b481fbe --- /dev/null +++ b/iphone/CoreApi/CoreApi/DeepLink/DeepLinkParser.mm @@ -0,0 +1,31 @@ +#import "DeepLinkParser.h" +#include +#import "DeepLinkData.h" +#import "DeepLinkSearchData.h" +#import "DeepLinkSubscriptionData.h" +#import "DeeplinkParsingResult.h" + +@implementation DeepLinkParser + ++ (id)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 diff --git a/iphone/CoreApi/CoreApi/Logger/Logger.h b/iphone/CoreApi/CoreApi/Logger/Logger.h new file mode 100644 index 0000000000..be94ad8aad --- /dev/null +++ b/iphone/CoreApi/CoreApi/Logger/Logger.h @@ -0,0 +1,20 @@ +#import + +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 diff --git a/iphone/CoreApi/CoreApi/Logger/Logger.mm b/iphone/CoreApi/CoreApi/Logger/Logger.mm new file mode 100644 index 0000000000..09f4e1482c --- /dev/null +++ b/iphone/CoreApi/CoreApi/Logger/Logger.mm @@ -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 diff --git a/iphone/Maps/Bookmarks/Catalog/CatalogWebViewController.swift b/iphone/Maps/Bookmarks/Catalog/CatalogWebViewController.swift index c59f56a687..0e20ab1cb5 100644 --- a/iphone/Maps/Bookmarks/Catalog/CatalogWebViewController.swift +++ b/iphone/Maps/Bookmarks/Catalog/CatalogWebViewController.swift @@ -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) } diff --git a/iphone/Maps/Bookmarks/Catalog/PaidRouteViewController.swift b/iphone/Maps/Bookmarks/Catalog/PaidRouteViewController.swift index db6928135b..f27841b49c 100644 --- a/iphone/Maps/Bookmarks/Catalog/PaidRouteViewController.swift +++ b/iphone/Maps/Bookmarks/Catalog/PaidRouteViewController.swift @@ -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) } diff --git a/iphone/Maps/Bookmarks/Catalog/Subscription/AllPassSubscriptionViewController.swift b/iphone/Maps/Bookmarks/Catalog/Subscription/AllPassSubscriptionViewController.swift index e6e781133e..126356c4e4 100644 --- a/iphone/Maps/Bookmarks/Catalog/Subscription/AllPassSubscriptionViewController.swift +++ b/iphone/Maps/Bookmarks/Catalog/Subscription/AllPassSubscriptionViewController.swift @@ -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) } diff --git a/iphone/Maps/Bookmarks/Catalog/Subscription/BaseSubscriptionViewController.swift b/iphone/Maps/Bookmarks/Catalog/Subscription/BaseSubscriptionViewController.swift index cb4a780d94..97fbc89cdb 100644 --- a/iphone/Maps/Bookmarks/Catalog/Subscription/BaseSubscriptionViewController.swift +++ b/iphone/Maps/Bookmarks/Catalog/Subscription/BaseSubscriptionViewController.swift @@ -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) { diff --git a/iphone/Maps/Bookmarks/Catalog/Subscription/BookmarksSubscriptionViewController.swift b/iphone/Maps/Bookmarks/Catalog/Subscription/BookmarksSubscriptionViewController.swift index a521bf0112..ba9820cc84 100644 --- a/iphone/Maps/Bookmarks/Catalog/Subscription/BookmarksSubscriptionViewController.swift +++ b/iphone/Maps/Bookmarks/Catalog/Subscription/BookmarksSubscriptionViewController.swift @@ -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) { diff --git a/iphone/Maps/Bookmarks/Catalog/Subscription/SubscriptionViewBuilder.swift b/iphone/Maps/Bookmarks/Catalog/Subscription/SubscriptionViewBuilder.swift new file mode 100644 index 0000000000..cd41967a80 --- /dev/null +++ b/iphone/Maps/Bookmarks/Catalog/Subscription/SubscriptionViewBuilder.swift @@ -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 + } +} diff --git a/iphone/Maps/Bridging-Header.h b/iphone/Maps/Bridging-Header.h index ed04f48898..a253e018af 100644 --- a/iphone/Maps/Bridging-Header.h +++ b/iphone/Maps/Bridging-Header.h @@ -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" diff --git a/iphone/Maps/Categories/MWMMapViewControlsManager+AddPlace.h b/iphone/Maps/Categories/MWMMapViewControlsManager+AddPlace.h new file mode 100644 index 0000000000..309275ced2 --- /dev/null +++ b/iphone/Maps/Categories/MWMMapViewControlsManager+AddPlace.h @@ -0,0 +1,12 @@ +#import +#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 diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/MWMMapViewControlsManager.h b/iphone/Maps/Classes/CustomViews/MapViewControls/MWMMapViewControlsManager.h index 94acc8a3e7..98604adae9 100644 --- a/iphone/Maps/Classes/CustomViews/MapViewControls/MWMMapViewControlsManager.h +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/MWMMapViewControlsManager.h @@ -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 diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/MWMMapViewControlsManager.mm b/iphone/Maps/Classes/CustomViews/MapViewControls/MWMMapViewControlsManager.mm index d5ec40ad5a..a4274b922d 100644 --- a/iphone/Maps/Classes/CustomViews/MapViewControls/MWMMapViewControlsManager.mm +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/MWMMapViewControlsManager.mm @@ -1,4 +1,5 @@ #import "MWMMapViewControlsManager.h" +#import "MWMMapViewControlsManager+AddPlace.h" #import "MWMAddPlaceNavigationBar.h" #import "MWMBottomMenuControllerProtocol.h" #import "MWMMapDownloadDialog.h" diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/TrafficButton/MWMTrafficButtonViewController.mm b/iphone/Maps/Classes/CustomViews/MapViewControls/TrafficButton/MWMTrafficButtonViewController.mm index eb37a8fd98..2320956adb 100644 --- a/iphone/Maps/Classes/CustomViews/MapViewControls/TrafficButton/MWMTrafficButtonViewController.mm +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/TrafficButton/MWMTrafficButtonViewController.mm @@ -8,7 +8,7 @@ #import "MWMMapViewControlsManager.h" #import "MapViewController.h" #import "SwiftBridge.h" - +#import "base/assert.hpp" namespace { CGFloat const kTopOffset = 6; diff --git a/iphone/Maps/Classes/DeepLinkHelper.h b/iphone/Maps/Classes/DeepLinkHelper.h deleted file mode 100644 index e91ce53683..0000000000 --- a/iphone/Maps/Classes/DeepLinkHelper.h +++ /dev/null @@ -1,13 +0,0 @@ -#import - -NS_ASSUME_NONNULL_BEGIN - -@interface DeepLinkHelper : NSObject - -+ (void)handleGeoUrl:(NSURL *)url; -+ (void)handleFileUrl:(NSURL *)url; -+ (void)handleCommonUrl:(NSURL *)url; - -@end - -NS_ASSUME_NONNULL_END diff --git a/iphone/Maps/Classes/DeepLinkHelper.mm b/iphone/Maps/Classes/DeepLinkHelper.mm deleted file mode 100644 index 1bc1d46098..0000000000 --- a/iphone/Maps/Classes/DeepLinkHelper.mm +++ /dev/null @@ -1,114 +0,0 @@ -#import "DeepLinkHelper.h" - -#import - -#include -#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 diff --git a/iphone/Maps/Classes/MapsAppDelegate.mm b/iphone/Maps/Classes/MapsAppDelegate.mm index 05607614a6..d0821aa76b 100644 --- a/iphone/Maps/Classes/MapsAppDelegate.mm +++ b/iphone/Maps/Classes/MapsAppDelegate.mm @@ -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]; }); } } diff --git a/iphone/Maps/Common/Common.swift b/iphone/Maps/Common/Common.swift index f83fa81c67..eeac32549a 100644 --- a/iphone/Maps/Common/Common.swift +++ b/iphone/Maps/Common/Common.swift @@ -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) + } +} diff --git a/iphone/Maps/Common/Statistics/StatisticsStrings.h b/iphone/Maps/Common/Statistics/StatisticsStrings.h index bb59c914cf..9dc65e302d 100644 --- a/iphone/Maps/Common/Statistics/StatisticsStrings.h +++ b/iphone/Maps/Common/Statistics/StatisticsStrings.h @@ -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"; diff --git a/iphone/Maps/Classes/DeepLinkHandler.swift b/iphone/Maps/Core/DeepLink/DeepLinkHandler.swift similarity index 62% rename from iphone/Maps/Classes/DeepLinkHandler.swift rename to iphone/Maps/Core/DeepLink/DeepLinkHandler.swift index da3d733025..ac5d9f0e3a 100644 --- a/iphone/Maps/Classes/DeepLinkHandler.swift +++ b/iphone/Maps/Core/DeepLink/DeepLinkHandler.swift @@ -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() } } diff --git a/iphone/Maps/Core/DeepLink/DeepLinkStrategyFactory.swift b/iphone/Maps/Core/DeepLink/DeepLinkStrategyFactory.swift new file mode 100644 index 0000000000..ff159ba2cb --- /dev/null +++ b/iphone/Maps/Core/DeepLink/DeepLinkStrategyFactory.swift @@ -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) + } + } +} diff --git a/iphone/Maps/Core/DeepLink/Strategies/DeepLinkCataloguePathStrategy.swift b/iphone/Maps/Core/DeepLink/Strategies/DeepLinkCataloguePathStrategy.swift new file mode 100644 index 0000000000..1c2d860e95 --- /dev/null +++ b/iphone/Maps/Core/DeepLink/Strategies/DeepLinkCataloguePathStrategy.swift @@ -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) + } +} + diff --git a/iphone/Maps/Core/DeepLink/Strategies/DeepLinkCatalogueStrategy.swift b/iphone/Maps/Core/DeepLink/Strategies/DeepLinkCatalogueStrategy.swift new file mode 100644 index 0000000000..323b923079 --- /dev/null +++ b/iphone/Maps/Core/DeepLink/Strategies/DeepLinkCatalogueStrategy.swift @@ -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) + } +} diff --git a/iphone/Maps/Core/DeepLink/Strategies/DeepLinkFileStrategy.swift b/iphone/Maps/Core/DeepLink/Strategies/DeepLinkFileStrategy.swift new file mode 100644 index 0000000000..719d99bd76 --- /dev/null +++ b/iphone/Maps/Core/DeepLink/Strategies/DeepLinkFileStrategy.swift @@ -0,0 +1,13 @@ +import Foundation + +class DeepLinkFileStrategy: IDeepLinkHandlerStrategy { + var deeplinkURL: DeepLinkURL + + init(url: DeepLinkURL) { + self.deeplinkURL = url + } + + func execute() { + DeepLinkParser.addBookmarksFile(deeplinkURL.url) + } +} diff --git a/iphone/Maps/Core/DeepLink/Strategies/DeepLinkGeoStrategy.swift b/iphone/Maps/Core/DeepLink/Strategies/DeepLinkGeoStrategy.swift new file mode 100644 index 0000000000..945e220469 --- /dev/null +++ b/iphone/Maps/Core/DeepLink/Strategies/DeepLinkGeoStrategy.swift @@ -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 ?? ""]) + } + } +} diff --git a/iphone/Maps/Core/DeepLink/Strategies/DeepLinkHandlerStrategy.swift b/iphone/Maps/Core/DeepLink/Strategies/DeepLinkHandlerStrategy.swift new file mode 100644 index 0000000000..815640ffa3 --- /dev/null +++ b/iphone/Maps/Core/DeepLink/Strategies/DeepLinkHandlerStrategy.swift @@ -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]) + } +} diff --git a/iphone/Maps/Core/DeepLink/Strategies/DeepLinkIncorrectStrategy.swift b/iphone/Maps/Core/DeepLink/Strategies/DeepLinkIncorrectStrategy.swift new file mode 100644 index 0000000000..ae2c10b808 --- /dev/null +++ b/iphone/Maps/Core/DeepLink/Strategies/DeepLinkIncorrectStrategy.swift @@ -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) + } +} diff --git a/iphone/Maps/Core/DeepLink/Strategies/DeepLinkLeadStrategy.swift b/iphone/Maps/Core/DeepLink/Strategies/DeepLinkLeadStrategy.swift new file mode 100644 index 0000000000..d2a3a54dec --- /dev/null +++ b/iphone/Maps/Core/DeepLink/Strategies/DeepLinkLeadStrategy.swift @@ -0,0 +1,11 @@ +class DeepLinkLeadStrategy: IDeepLinkHandlerStrategy { + var deeplinkURL: DeepLinkURL + + init(url: DeepLinkURL) { + self.deeplinkURL = url + } + + func execute() { + sendStatisticsOnSuccess(type: kStatLead) + } +} diff --git a/iphone/Maps/Core/DeepLink/Strategies/DeepLinkMapStrategy.swift b/iphone/Maps/Core/DeepLink/Strategies/DeepLinkMapStrategy.swift new file mode 100644 index 0000000000..9711bed4e0 --- /dev/null +++ b/iphone/Maps/Core/DeepLink/Strategies/DeepLinkMapStrategy.swift @@ -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) + } + } +} diff --git a/iphone/Maps/Core/DeepLink/Strategies/DeepLinkRouteStrategy.swift b/iphone/Maps/Core/DeepLink/Strategies/DeepLinkRouteStrategy.swift new file mode 100644 index 0000000000..bc9e5a02b3 --- /dev/null +++ b/iphone/Maps/Core/DeepLink/Strategies/DeepLinkRouteStrategy.swift @@ -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) + } + } +} diff --git a/iphone/Maps/Core/DeepLink/Strategies/DeepLinkRouteStrategyAdapter.h b/iphone/Maps/Core/DeepLink/Strategies/DeepLinkRouteStrategyAdapter.h new file mode 100644 index 0000000000..7d42ead319 --- /dev/null +++ b/iphone/Maps/Core/DeepLink/Strategies/DeepLinkRouteStrategyAdapter.h @@ -0,0 +1,17 @@ +#import +#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 diff --git a/iphone/Maps/Core/DeepLink/Strategies/DeepLinkRouteStrategyAdapter.mm b/iphone/Maps/Core/DeepLink/Strategies/DeepLinkRouteStrategyAdapter.mm new file mode 100644 index 0000000000..34c1d8fbb8 --- /dev/null +++ b/iphone/Maps/Core/DeepLink/Strategies/DeepLinkRouteStrategyAdapter.mm @@ -0,0 +1,34 @@ +#import "DeepLinkRouteStrategyAdapter.h" +#import +#import +#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 diff --git a/iphone/Maps/Core/DeepLink/Strategies/DeepLinkSearchStrategy.swift b/iphone/Maps/Core/DeepLink/Strategies/DeepLinkSearchStrategy.swift new file mode 100644 index 0000000000..5139ec78bc --- /dev/null +++ b/iphone/Maps/Core/DeepLink/Strategies/DeepLinkSearchStrategy.swift @@ -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) + } +} diff --git a/iphone/Maps/Core/DeepLink/Strategies/DeepLinkSubscriptionStrategy.swift b/iphone/Maps/Core/DeepLink/Strategies/DeepLinkSubscriptionStrategy.swift new file mode 100644 index 0000000000..ac4e2f8005 --- /dev/null +++ b/iphone/Maps/Core/DeepLink/Strategies/DeepLinkSubscriptionStrategy.swift @@ -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) + } +} diff --git a/iphone/Maps/Core/Subscriptions/MWMPurchaseManager.mm b/iphone/Maps/Core/Subscriptions/MWMPurchaseManager.mm index 91574cf540..881e59ad64 100644 --- a/iphone/Maps/Core/Subscriptions/MWMPurchaseManager.mm +++ b/iphone/Maps/Core/Subscriptions/MWMPurchaseManager.mm @@ -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 diff --git a/iphone/Maps/Core/Subscriptions/SubscriptionManager.swift b/iphone/Maps/Core/Subscriptions/SubscriptionManager.swift index 152d04fab9..3b861dd71c 100644 --- a/iphone/Maps/Core/Subscriptions/SubscriptionManager.swift +++ b/iphone/Maps/Core/Subscriptions/SubscriptionManager.swift @@ -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.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 { diff --git a/iphone/Maps/Maps.xcodeproj/project.pbxproj b/iphone/Maps/Maps.xcodeproj/project.pbxproj index e0623e0380..6ba2edb978 100644 --- a/iphone/Maps/Maps.xcodeproj/project.pbxproj +++ b/iphone/Maps/Maps.xcodeproj/project.pbxproj @@ -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 = ""; }; 4788739120EE326400F6826B /* VerticallyAlignedButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VerticallyAlignedButton.swift; sourceTree = ""; }; 4797A4DB226F4B2900D3A984 /* DeepLinkHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeepLinkHandler.swift; sourceTree = ""; }; - 4797A4E02270997E00D3A984 /* DeepLinkHelper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DeepLinkHelper.h; sourceTree = ""; }; - 4797A4E12270997E00D3A984 /* DeepLinkHelper.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = DeepLinkHelper.mm; sourceTree = ""; }; 479D305522C627CB00D18278 /* MWMMegafonBannerViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MWMMegafonBannerViewController.xib; sourceTree = ""; }; 479D305922C62F4000D18278 /* MWMBookmarksBannerViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MWMBookmarksBannerViewController.xib; sourceTree = ""; }; 479D305E22C6634900D18278 /* MWMMegafonBannerViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MWMMegafonBannerViewController.h; sourceTree = ""; }; @@ -1602,6 +1613,24 @@ 991CE2BB2371D349009EB02A /* PromoCampaign.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PromoCampaign.swift; sourceTree = ""; }; 991CE2BE2371D349009EB02A /* PromoDiscoveryCampaign.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PromoDiscoveryCampaign.swift; sourceTree = ""; }; 991CE2DC2373145C009EB02A /* PromoAfterBookingCampaign.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PromoAfterBookingCampaign.swift; sourceTree = ""; }; + 991CE2F92379B86B009EB02A /* DeepLinkHandlerStrategy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeepLinkHandlerStrategy.swift; sourceTree = ""; }; + 991CE2FB2379B8E5009EB02A /* DeepLinkGeoStrategy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeepLinkGeoStrategy.swift; sourceTree = ""; }; + 991CE300237AA8C2009EB02A /* DeepLinkStrategyFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeepLinkStrategyFactory.swift; sourceTree = ""; }; + 993F54F8237C622700545511 /* DeepLinkSearchStrategy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DeepLinkSearchStrategy.swift; sourceTree = ""; }; + 993F54F9237C622700545511 /* DeepLinkRouteStrategyAdapter.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DeepLinkRouteStrategyAdapter.mm; sourceTree = ""; }; + 993F54FA237C622700545511 /* DeepLinkHandlerStrategy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DeepLinkHandlerStrategy.swift; sourceTree = ""; }; + 993F54FB237C622700545511 /* DeepLinkGeoStrategy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DeepLinkGeoStrategy.swift; sourceTree = ""; }; + 993F54FC237C622700545511 /* DeepLinkIncorrectStrategy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DeepLinkIncorrectStrategy.swift; sourceTree = ""; }; + 993F54FD237C622700545511 /* DeepLinkSubscriptionStrategy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DeepLinkSubscriptionStrategy.swift; sourceTree = ""; }; + 993F54FE237C622700545511 /* DeepLinkLeadStrategy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DeepLinkLeadStrategy.swift; sourceTree = ""; }; + 993F54FF237C622700545511 /* DeepLinkCataloguePathStrategy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DeepLinkCataloguePathStrategy.swift; sourceTree = ""; }; + 993F5500237C622700545511 /* DeepLinkMapStrategy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DeepLinkMapStrategy.swift; sourceTree = ""; }; + 993F5501237C622700545511 /* DeepLinkRouteStrategy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DeepLinkRouteStrategy.swift; sourceTree = ""; }; + 993F5502237C622700545511 /* DeepLinkCatalogueStrategy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DeepLinkCatalogueStrategy.swift; sourceTree = ""; }; + 993F5503237C622700545511 /* DeepLinkRouteStrategyAdapter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DeepLinkRouteStrategyAdapter.h; sourceTree = ""; }; + 993F5504237C622700545511 /* DeepLinkFileStrategy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DeepLinkFileStrategy.swift; sourceTree = ""; }; + 993F5505237C622700545511 /* DeepLinkHandler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DeepLinkHandler.swift; sourceTree = ""; }; + 993F5506237C622700545511 /* DeepLinkStrategyFactory.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DeepLinkStrategyFactory.swift; sourceTree = ""; }; 99425AF3236855BB00D005C0 /* PromoDiscoveryRouter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PromoDiscoveryRouter.swift; sourceTree = ""; }; 99425AFB23685F1E00D005C0 /* PromoDiscoveryPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PromoDiscoveryPresenter.swift; sourceTree = ""; }; 99536110235DABB1008B218F /* BaseSubscriptionViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseSubscriptionViewController.swift; sourceTree = ""; }; @@ -1610,7 +1639,19 @@ 995739032355CAA30019AEE7 /* PageIndicator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PageIndicator.swift; sourceTree = ""; }; 995739052355CAC40019AEE7 /* ImageViewCrossDisolve.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageViewCrossDisolve.swift; sourceTree = ""; }; 995739072355CB660019AEE7 /* AllPassSubscriptionViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AllPassSubscriptionViewController.swift; sourceTree = ""; }; + 9957FAC6237AADAD00855F48 /* DeepLinkFileStrategy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeepLinkFileStrategy.swift; sourceTree = ""; }; + 9957FAD0237AB57400855F48 /* DeepLinkRouteStrategy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeepLinkRouteStrategy.swift; sourceTree = ""; }; + 9957FAD3237ABDFE00855F48 /* DeepLinkRouteStrategyAdapter.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = DeepLinkRouteStrategyAdapter.mm; sourceTree = ""; }; + 9957FAD7237AC9A400855F48 /* DeepLinkSearchStrategy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeepLinkSearchStrategy.swift; sourceTree = ""; }; + 9957FAE0237AE04900855F48 /* MWMMapViewControlsManager+AddPlace.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "MWMMapViewControlsManager+AddPlace.h"; sourceTree = ""; }; + 9957FAE3237AE3CF00855F48 /* DeepLinkCatalogueStrategy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeepLinkCatalogueStrategy.swift; sourceTree = ""; }; + 9957FAEA237AF22800855F48 /* DeepLinkIncorrectStrategy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeepLinkIncorrectStrategy.swift; sourceTree = ""; }; 99752259236B187400ADF673 /* FirstLaunchController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FirstLaunchController.swift; sourceTree = ""; }; + 999D3A60237B088C00C5F7A8 /* DeepLinkSubscriptionStrategy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeepLinkSubscriptionStrategy.swift; sourceTree = ""; }; + 999D3A66237BFA4600C5F7A8 /* SubscriptionViewBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubscriptionViewBuilder.swift; sourceTree = ""; }; + 999D3A68237C0ADD00C5F7A8 /* DeepLinkMapStrategy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeepLinkMapStrategy.swift; sourceTree = ""; }; + 999D3A6A237C132B00C5F7A8 /* DeepLinkCataloguePathStrategy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeepLinkCataloguePathStrategy.swift; sourceTree = ""; }; + 999D3A6C237C1C0700C5F7A8 /* DeepLinkLeadStrategy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeepLinkLeadStrategy.swift; sourceTree = ""; }; 99B6A74B2362F5AA002C94CB /* PromoButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PromoButton.swift; sourceTree = ""; }; 99B6A74D2362F5CD002C94CB /* PromoCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PromoCoordinator.swift; sourceTree = ""; }; 99B6A77E23684573002C94CB /* PromoDiscoveryBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PromoDiscoveryBuilder.swift; sourceTree = ""; }; @@ -2222,9 +2263,6 @@ 340837101B7243B500B5C185 /* Share */, F6588E291B15C25C00EE1E58 /* TextView */, 34FE4C421BCC013500066718 /* Widgets */, - 4797A4DB226F4B2900D3A984 /* DeepLinkHandler.swift */, - 4797A4E02270997E00D3A984 /* DeepLinkHelper.h */, - 4797A4E12270997E00D3A984 /* DeepLinkHelper.mm */, ); path = Classes; sourceTree = ""; @@ -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 = ""; @@ -3646,6 +3687,57 @@ path = PromoAfterBookingCampaign; sourceTree = ""; }; + 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 = ""; + }; + 993F54F6237C622700545511 /* DeepLink */ = { + isa = PBXGroup; + children = ( + 993F54F7237C622700545511 /* Strategies */, + 993F5505237C622700545511 /* DeepLinkHandler.swift */, + 993F5506237C622700545511 /* DeepLinkStrategyFactory.swift */, + ); + path = DeepLink; + sourceTree = ""; + }; + 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 = ""; + }; 995738D9235481FE0019AEE7 /* Subscription */ = { isa = PBXGroup; children = ( @@ -3656,6 +3748,7 @@ 995738DA235484410019AEE7 /* AllPassSubscriptionViewController.xib */, 995739072355CB660019AEE7 /* AllPassSubscriptionViewController.swift */, 99536110235DABB1008B218F /* BaseSubscriptionViewController.swift */, + 999D3A66237BFA4600C5F7A8 /* SubscriptionViewBuilder.swift */, ); path = Subscription; sourceTree = ""; @@ -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 */, diff --git a/iphone/Maps/UI/PlacePage/MWMPlacePageManager.mm b/iphone/Maps/UI/PlacePage/MWMPlacePageManager.mm index 3063f999db..ddd3a76cc9 100644 --- a/iphone/Maps/UI/PlacePage/MWMPlacePageManager.mm +++ b/iphone/Maps/UI/PlacePage/MWMPlacePageManager.mm @@ -10,6 +10,7 @@ #import "MWMSearchManager+Filter.h" #import "MWMStorage.h" #import "SwiftBridge.h" +#import "MWMMapViewControlsManager+AddPlace.h" #import diff --git a/iphone/Maps/UI/PlacePage/MWMPlacePageProtocol.h b/iphone/Maps/UI/PlacePage/MWMPlacePageProtocol.h index 1dac0d2aa6..f94be7e4d1 100644 --- a/iphone/Maps/UI/PlacePage/MWMPlacePageProtocol.h +++ b/iphone/Maps/UI/PlacePage/MWMPlacePageProtocol.h @@ -1,5 +1,6 @@ #import "MWMMapViewControlsManager.h" #import "MWMPlacePageButtonsProtocol.h" +#include "geometry/point2d.hpp" @class MWMViewController; diff --git a/iphone/Maps/UI/Welcome/DeepLinkInfo/DeepLinkInfoBuilder.swift b/iphone/Maps/UI/Welcome/DeepLinkInfo/DeepLinkInfoBuilder.swift index cccced7c3f..e47ea14d86 100644 --- a/iphone/Maps/UI/Welcome/DeepLinkInfo/DeepLinkInfoBuilder.swift +++ b/iphone/Maps/UI/Welcome/DeepLinkInfo/DeepLinkInfoBuilder.swift @@ -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) diff --git a/iphone/Maps/UI/Welcome/PromoDiscovery/PromoDiscoveryRouter.swift b/iphone/Maps/UI/Welcome/PromoDiscovery/PromoDiscoveryRouter.swift index d677ae21a6..86324e5ef6 100644 --- a/iphone/Maps/UI/Welcome/PromoDiscovery/PromoDiscoveryRouter.swift +++ b/iphone/Maps/UI/Welcome/PromoDiscovery/PromoDiscoveryRouter.swift @@ -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() { diff --git a/map/framework.cpp b/map/framework.cpp index e7a64f9e59..d4fa6dd0c1 100644 --- a/map/framework.cpp +++ b/map/framework.cpp @@ -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 { diff --git a/map/framework.hpp b/map/framework.hpp index e2d6c09f15..55c0a80fde 100644 --- a/map/framework.hpp +++ b/map/framework.hpp @@ -678,6 +678,7 @@ public: ParsedRoutingData GetParsedRoutingData() const; url_scheme::SearchRequest GetParsedSearchRequest() const; + url_scheme::Subscription GetParsedSubscription() const; using FeatureMatcher = std::function; diff --git a/map/map_tests/mwm_url_tests.cpp b/map/map_tests/mwm_url_tests.cpp index 6d2306068d..3a38c4edfd 100644 --- a/map/map_tests/mwm_url_tests.cpp +++ b/map/map_tests/mwm_url_tests.cpp @@ -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 GetRoutePoints() const { return m_api.GetRoutePoints(); } url_scheme::SearchRequest const & GetSearchRequest() const { return m_api.GetSearchRequest(); } string const & GetGlobalBackUrl() const { return m_api.GetGlobalBackUrl(); } diff --git a/map/mwm_url.cpp b/map/mwm_url.cpp index c27b0ba0a7..95c5abee26 100644 --- a/map/mwm_url.cpp +++ b/map/mwm_url.cpp @@ -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 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(); diff --git a/map/mwm_url.hpp b/map/mwm_url.hpp index fe9e9e0ade..b4b103709d 100644 --- a/map/mwm_url.hpp +++ b/map/mwm_url.hpp @@ -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 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 & points); bool RouteKeyValue(std::string const & key, std::string const & value, std::vector & 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 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;