diff --git a/iphone/Maps/Classes/Common.h b/iphone/Maps/Classes/Common.h index 1ead015aa4..8e15781c2d 100644 --- a/iphone/Maps/Classes/Common.h +++ b/iphone/Maps/Classes/Common.h @@ -1,9 +1,31 @@ +#import -#define FIRST_LAUNCH_KEY @"FIRST_LAUNCH_KEY" +static NSString * const FIRST_LAUNCH_KEY = @"FIRST_LAUNCH_KEY"; -#define MAPSWITHME_PREMIUM_LOCAL_URL @"mapswithmepro://" +static NSString * const MAPSWITHME_PREMIUM_LOCAL_URL = @"mapswithmepro://"; -#define BOOKMARK_CATEGORY_DELETED_NOTIFICATION @"BookmarkCategoryDeletedNotification" -#define METRICS_CHANGED_NOTIFICATION @"MetricsChangedNotification" -#define BOOKMARK_DELETED_NOTIFICATION @"BookmarkDeletedNotification" -#define LOCATION_MANAGER_STARTED_NOTIFICATION @"LocationManagerStartedNotification" \ No newline at end of file +static NSString * const BOOKMARK_CATEGORY_DELETED_NOTIFICATION = @"BookmarkCategoryDeletedNotification"; + +static NSString * const METRICS_CHANGED_NOTIFICATION = @"MetricsChangedNotification"; + +static NSString * const BOOKMARK_DELETED_NOTIFICATION = @"BookmarkDeletedNotification"; + +static NSString * const LOCATION_MANAGER_STARTED_NOTIFICATION = @"LocationManagerStartedNotification"; + +static NSString * const kDownloadingProgressUpdateNotificationId = @"DownloadingProgressUpdateNotificationId"; + +static NSString * const kHaveAppleWatch = @"HaveAppleWatch"; + +static inline NSString * const kApplicationGroupIdentifier() +{ + static NSString * const productionGroupIdentifier = @"group.mapsme.watchkit.production"; + static NSString * const developerGroupIdentifier = @"group.mapsme.watchkit"; + + static NSString * const productionAppBundleIdentifier = @"com.mapswithme.full"; + static NSString * const productionExtBundleIdentifier = @"com.mapswithme.full.watchkitextension"; + + NSString * bundleIdentifier = [[NSBundle mainBundle] bundleIdentifier]; + if ([bundleIdentifier isEqualToString:productionAppBundleIdentifier] || [bundleIdentifier isEqualToString:productionExtBundleIdentifier]) + return productionGroupIdentifier; + return developerGroupIdentifier; +} diff --git a/platform/platform_ios.hpp b/platform/platform_ios.hpp new file mode 100644 index 0000000000..b76dcc55cd --- /dev/null +++ b/platform/platform_ios.hpp @@ -0,0 +1,11 @@ +#pragma once + +#include "platform.hpp" + +class CustomIOSPlatform : public Platform +{ +public: + CustomIOSPlatform(); + + void MigrateWritableDirForAppleWatch(); +}; \ No newline at end of file diff --git a/platform/platform_ios.mm b/platform/platform_ios.mm index 2f6a71b63a..5fd1310059 100644 --- a/platform/platform_ios.mm +++ b/platform/platform_ios.mm @@ -1,4 +1,4 @@ -#include "platform/platform.hpp" +#include "platform/platform_ios.hpp" #include "platform/platform_unix_impl.hpp" #include "platform/constants.hpp" @@ -19,6 +19,8 @@ #define IFT_ETHER 0x6 /* Ethernet CSMACD */ #endif +#import "../iphone/Maps/Classes/Common.h" + #import #import #import @@ -28,30 +30,8 @@ #import #import - Platform::Platform() { - NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; - - NSBundle * bundle = [NSBundle mainBundle]; - NSString * path = [bundle resourcePath]; - m_resourcesDir = [path UTF8String]; - m_resourcesDir += "/"; - - NSArray * dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); - NSString * docsDir = [dirPaths objectAtIndex:0]; - m_writableDir = [docsDir UTF8String]; - m_writableDir += "/"; - m_settingsDir = m_writableDir; - m_tmpDir = [NSHomeDirectory() UTF8String]; - m_tmpDir += "/tmp/"; - - NSString * appID = [[bundle infoDictionary] objectForKey:@"CFBundleIdentifier"]; - - UIDevice * device = [UIDevice currentDevice]; - NSLog(@"Device: %@, SystemName: %@, SystemVersion: %@", device.model, device.systemName, device.systemVersion); - - [pool release]; } Platform::EError Platform::MkDir(string const & dirName) const @@ -189,9 +169,98 @@ void Platform::RunAsync(TFunctor const & fn, Priority p) dispatch_async_f(dispatch_get_global_queue(priority, 0), new TFunctor(fn), &PerformImpl); } +CustomIOSPlatform::CustomIOSPlatform() +{ + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + + NSBundle * bundle = [NSBundle mainBundle]; + NSString * path = [bundle resourcePath]; + m_resourcesDir = [path UTF8String]; + m_resourcesDir += "/"; + + NSArray * dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); + NSString * docsDir = [dirPaths firstObject]; + m_writableDir = [docsDir UTF8String]; + + // This check is needed for Apple Watch support only on 8.2+ devices. + if ([UIDevice currentDevice].systemVersion.floatValue >= 8.0 && [[[NSUserDefaults alloc] initWithSuiteName:kApplicationGroupIdentifier()] boolForKey:kHaveAppleWatch]) + { + NSURL * sharedURL = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:kApplicationGroupIdentifier()]; + if (sharedURL) + m_writableDir = [sharedURL.path UTF8String]; + } + m_writableDir += "/"; + m_settingsDir = m_writableDir; + + NSString * tmpDir = NSTemporaryDirectory(); + if (tmpDir) + m_tmpDir = [tmpDir UTF8String]; + else + { + m_tmpDir = [NSHomeDirectory() UTF8String]; + m_tmpDir += "/tmp/"; + } + + NSString * appID = [[bundle infoDictionary] objectForKey:@"CFBundleIdentifier"]; + + UIDevice * device = [UIDevice currentDevice]; + NSLog(@"Device: %@, SystemName: %@, SystemVersion: %@", device.model, device.systemName, device.systemVersion); + + [pool release]; +} + +void migrate() +{ + NSArray * excludeFiles = @[@"com-facebook-sdk-AppEventsPersistedEvents.json", + @"Inbox", + @"MRGService"]; + + NSFileManager * fileManager = [NSFileManager defaultManager]; + NSURL * privateURL = [fileManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask].firstObject; + NSURL * sharedURL = [fileManager containerURLForSecurityApplicationGroupIdentifier:kApplicationGroupIdentifier()]; + + NSDirectoryEnumerator * dirEnum = [fileManager enumeratorAtURL:privateURL includingPropertiesForKeys:nil options:NSDirectoryEnumerationSkipsSubdirectoryDescendants | NSDirectoryEnumerationSkipsPackageDescendants | NSDirectoryEnumerationSkipsHiddenFiles errorHandler:nil]; + + NSURL * sourceURL = nil; + while ((sourceURL = [dirEnum nextObject])) + { + NSString * fileName = [sourceURL lastPathComponent]; + if (![excludeFiles containsObject:fileName]) + { + NSURL * destinationURL = [sharedURL URLByAppendingPathComponent:fileName]; + NSError * error = nil; + [fileManager moveItemAtURL:sourceURL toURL:destinationURL error:&error]; + if (error && [error.domain isEqualToString:NSCocoaErrorDomain] && error.code == NSFileWriteFileExistsError) + { + [fileManager removeItemAtURL:destinationURL error:nil]; + [fileManager moveItemAtURL:sourceURL toURL:destinationURL error:nil]; + } + } + } +} + +// This method should be called ONLY from the Watch code (iOS 8.2+). +void CustomIOSPlatform::MigrateWritableDirForAppleWatch() +{ + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + + NSURL * sharedURL = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:kApplicationGroupIdentifier()]; + if (sharedURL) + { + migrate(); + + NSString * path = sharedURL.path; + m_writableDir = [path UTF8String]; + m_writableDir += "/"; + m_settingsDir = m_writableDir; + } + + [pool release]; +} + //////////////////////////////////////////////////////////////////////// extern Platform & GetPlatform() { - static Platform platform; + static CustomIOSPlatform platform; return platform; }