Safer migration, boolean description fix.
[ADDED] Safer store migration: don't delete the old store, allowing the client to downgrade. [ADDED] Log checkpoints and send to TestFlight too. [FIXED] Describe booleans as YES/NO, not 1/0.
This commit is contained in:
parent
5e1e88bdeb
commit
ab15694d9a
2
External/Pearl
vendored
2
External/Pearl
vendored
@ -1 +1 @@
|
|||||||
Subproject commit b889e6312d5ecd9d2e45eb1402cadc6e27ed84c4
|
Subproject commit 720acb2e6583a2ed9efbbe28ab53681a19070a42
|
@ -15,6 +15,20 @@
|
|||||||
#define STORE_OPTIONS
|
#define STORE_OPTIONS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define MPMigrationLevelLocalStoreKey @"MPMigrationLevelLocalStoreKey"
|
||||||
|
typedef enum {
|
||||||
|
MPMigrationLevelLocalStoreV13,
|
||||||
|
MPMigrationLevelLocalStoreV14,
|
||||||
|
MPMigrationLevelLocalStoreCurrent = MPMigrationLevelLocalStoreV14,
|
||||||
|
} MPMigrationLevelLocalStore;
|
||||||
|
|
||||||
|
#define MPMigrationLevelCloudStoreKey @"MPMigrationLevelCloudStoreKey"
|
||||||
|
typedef enum {
|
||||||
|
MPMigrationLevelCloudStoreV13,
|
||||||
|
MPMigrationLevelCloudStoreV14,
|
||||||
|
MPMigrationLevelCloudStoreCurrent = MPMigrationLevelCloudStoreV14,
|
||||||
|
} MPMigrationLevelCloudStore;
|
||||||
|
|
||||||
@implementation MPAppDelegate_Shared(Store)
|
@implementation MPAppDelegate_Shared(Store)
|
||||||
#if TARGET_OS_IPHONE
|
#if TARGET_OS_IPHONE
|
||||||
PearlAssociatedObjectProperty(PearlAlert*, HandleCloudContentAlert, handleCloudContentAlert);
|
PearlAssociatedObjectProperty(PearlAlert*, HandleCloudContentAlert, handleCloudContentAlert);
|
||||||
@ -98,18 +112,18 @@ PearlAssociatedObjectProperty(NSManagedObjectContext*, MainManagedObjectContext,
|
|||||||
[[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationWillTerminateNotification
|
[[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationWillTerminateNotification
|
||||||
object:[UIApplication sharedApplication] queue:nil
|
object:[UIApplication sharedApplication] queue:nil
|
||||||
usingBlock:^(NSNotification *note) {
|
usingBlock:^(NSNotification *note) {
|
||||||
[self saveContexts];
|
[[self mainManagedObjectContext] saveToStore];
|
||||||
}];
|
}];
|
||||||
[[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationWillResignActiveNotification
|
[[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationWillResignActiveNotification
|
||||||
object:[UIApplication sharedApplication] queue:nil
|
object:[UIApplication sharedApplication] queue:nil
|
||||||
usingBlock:^(NSNotification *note) {
|
usingBlock:^(NSNotification *note) {
|
||||||
[self saveContexts];
|
[[self mainManagedObjectContext] saveToStore];
|
||||||
}];
|
}];
|
||||||
#else
|
#else
|
||||||
[[NSNotificationCenter defaultCenter] addObserverForName:NSApplicationWillTerminateNotification
|
[[NSNotificationCenter defaultCenter] addObserverForName:NSApplicationWillTerminateNotification
|
||||||
object:[NSApplication sharedApplication] queue:nil
|
object:[NSApplication sharedApplication] queue:nil
|
||||||
usingBlock:^(NSNotification *note) {
|
usingBlock:^(NSNotification *note) {
|
||||||
[self saveContexts];
|
[[self mainManagedObjectContext] saveToStore];
|
||||||
}];
|
}];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -126,6 +140,11 @@ PearlAssociatedObjectProperty(NSManagedObjectContext*, MainManagedObjectContext,
|
|||||||
|
|
||||||
- (void)migrateLocalStoreForManager:(UbiquityStoreManager *)manager {
|
- (void)migrateLocalStoreForManager:(UbiquityStoreManager *)manager {
|
||||||
|
|
||||||
|
MPMigrationLevelLocalStore migrationLevel = [[NSUserDefaults standardUserDefaults] integerForKey:@"MPMigrationLevelLocalStore"];
|
||||||
|
if (migrationLevel >= MPMigrationLevelLocalStoreCurrent)
|
||||||
|
// Local store up-to-date.
|
||||||
|
return;
|
||||||
|
|
||||||
NSURL *applicationFilesDirectory = [[[NSFileManager defaultManager]
|
NSURL *applicationFilesDirectory = [[[NSFileManager defaultManager]
|
||||||
URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
|
URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
|
||||||
NSURL *oldLocalStoreURL = [[applicationFilesDirectory
|
NSURL *oldLocalStoreURL = [[applicationFilesDirectory
|
||||||
@ -137,10 +156,12 @@ PearlAssociatedObjectProperty(NSManagedObjectContext*, MainManagedObjectContext,
|
|||||||
}
|
}
|
||||||
if (![[NSFileManager defaultManager] fileExistsAtPath:oldLocalStoreURL.path isDirectory:NO]) {
|
if (![[NSFileManager defaultManager] fileExistsAtPath:oldLocalStoreURL.path isDirectory:NO]) {
|
||||||
// No local store to migrate.
|
// No local store to migrate.
|
||||||
|
[[NSUserDefaults standardUserDefaults] setInteger:MPMigrationLevelLocalStoreCurrent forKey:MPMigrationLevelLocalStoreKey];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ([[NSFileManager defaultManager] fileExistsAtPath:newLocalStoreURL.path isDirectory:NO]) {
|
if ([[NSFileManager defaultManager] fileExistsAtPath:newLocalStoreURL.path isDirectory:NO]) {
|
||||||
wrn(@"Can't migrate old local store: A new local store already exists.");
|
wrn(@"Can't migrate old local store: A new local store already exists.");
|
||||||
|
[[NSUserDefaults standardUserDefaults] setInteger:MPMigrationLevelLocalStoreCurrent forKey:MPMigrationLevelLocalStoreKey];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,11 +193,17 @@ PearlAssociatedObjectProperty(NSManagedObjectContext*, MainManagedObjectContext,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[NSUserDefaults standardUserDefaults] setInteger:MPMigrationLevelLocalStoreCurrent forKey:MPMigrationLevelLocalStoreKey];
|
||||||
inf(@"Successfully migrated old to new local store.");
|
inf(@"Successfully migrated old to new local store.");
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)migrateCloudStoreForManager:(UbiquityStoreManager *)manager {
|
- (void)migrateCloudStoreForManager:(UbiquityStoreManager *)manager {
|
||||||
|
|
||||||
|
MPMigrationLevelCloudStore migrationLevel = [[NSUserDefaults standardUserDefaults] integerForKey:@"MPMigrationLevelCloudStore"];
|
||||||
|
if (migrationLevel >= MPMigrationLevelCloudStoreCurrent)
|
||||||
|
// Cloud store up-to-date.
|
||||||
|
return;
|
||||||
|
|
||||||
// Migrate cloud enabled preference.
|
// Migrate cloud enabled preference.
|
||||||
NSNumber *oldCloudEnabled = [[NSUserDefaults standardUserDefaults] objectForKey:@"iCloudEnabledKey"];
|
NSNumber *oldCloudEnabled = [[NSUserDefaults standardUserDefaults] objectForKey:@"iCloudEnabledKey"];
|
||||||
if ([oldCloudEnabled boolValue]) {
|
if ([oldCloudEnabled boolValue]) {
|
||||||
@ -186,12 +213,15 @@ PearlAssociatedObjectProperty(NSManagedObjectContext*, MainManagedObjectContext,
|
|||||||
|
|
||||||
// Migrate cloud store.
|
// Migrate cloud store.
|
||||||
NSString *uuid = [[NSUserDefaults standardUserDefaults] stringForKey:@"LocalUUIDKey"];
|
NSString *uuid = [[NSUserDefaults standardUserDefaults] stringForKey:@"LocalUUIDKey"];
|
||||||
if (!uuid)
|
if (!uuid) {
|
||||||
// No old cloud store to migrate.
|
// No old cloud store to migrate.
|
||||||
|
[[NSUserDefaults standardUserDefaults] setInteger:MPMigrationLevelCloudStoreCurrent forKey:MPMigrationLevelCloudStoreKey];
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (![manager cloudSafeForSeeding]) {
|
if (![manager cloudSafeForSeeding]) {
|
||||||
wrn(@"Can't migrate old cloud store: A new cloud store already exists.");
|
wrn(@"Can't migrate old cloud store: A new cloud store already exists.");
|
||||||
|
[[NSUserDefaults standardUserDefaults] setInteger:MPMigrationLevelCloudStoreCurrent forKey:MPMigrationLevelCloudStoreKey];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -244,27 +274,10 @@ PearlAssociatedObjectProperty(NSManagedObjectContext*, MainManagedObjectContext,
|
|||||||
error:nil cause:nil context:nil])
|
error:nil cause:nil context:nil])
|
||||||
return;
|
return;
|
||||||
|
|
||||||
[[NSUserDefaults standardUserDefaults] removeObjectForKey:@"LocalUUIDKey"];
|
[[NSUserDefaults standardUserDefaults] setInteger:MPMigrationLevelCloudStoreCurrent forKey:MPMigrationLevelCloudStoreKey];
|
||||||
inf(@"Successfully migrated old to new cloud store.");
|
inf(@"Successfully migrated old to new cloud store.");
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)saveContexts {
|
|
||||||
|
|
||||||
NSManagedObjectContext *mainManagedObjectContext = self.mainManagedObjectContext;
|
|
||||||
[mainManagedObjectContext performBlockAndWait:^{
|
|
||||||
NSError *error = nil;
|
|
||||||
if (![mainManagedObjectContext save:&error])
|
|
||||||
err(@"While saving main context: %@", error);
|
|
||||||
}];
|
|
||||||
|
|
||||||
NSManagedObjectContext *privateManagedObjectContext = [self privateManagedObjectContextIfReady];
|
|
||||||
[privateManagedObjectContext performBlockAndWait:^{
|
|
||||||
NSError *error = nil;
|
|
||||||
if (![privateManagedObjectContext save:&error])
|
|
||||||
err(@"While saving private context: %@", error);
|
|
||||||
}];
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma mark - UbiquityStoreManagerDelegate
|
#pragma mark - UbiquityStoreManagerDelegate
|
||||||
|
|
||||||
- (NSManagedObjectContext *)managedObjectContextForUbiquityStoreManager:(UbiquityStoreManager *)usm {
|
- (NSManagedObjectContext *)managedObjectContextForUbiquityStoreManager:(UbiquityStoreManager *)usm {
|
||||||
@ -301,8 +314,7 @@ PearlAssociatedObjectProperty(NSManagedObjectContext*, MainManagedObjectContext,
|
|||||||
} );
|
} );
|
||||||
|
|
||||||
// Create our contexts.
|
// Create our contexts.
|
||||||
NSManagedObjectContext
|
NSManagedObjectContext *privateManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
|
||||||
*privateManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
|
|
||||||
[privateManagedObjectContext performBlockAndWait:^{
|
[privateManagedObjectContext performBlockAndWait:^{
|
||||||
privateManagedObjectContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy;
|
privateManagedObjectContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy;
|
||||||
privateManagedObjectContext.persistentStoreCoordinator = coordinator;
|
privateManagedObjectContext.persistentStoreCoordinator = coordinator;
|
||||||
|
@ -78,7 +78,11 @@ typedef enum {
|
|||||||
|
|
||||||
static void MPCheckpoint(NSString *checkpoint, NSDictionary *attributes) {
|
static void MPCheckpoint(NSString *checkpoint, NSDictionary *attributes) {
|
||||||
|
|
||||||
|
inf(@"%@: %@", checkpoint, attributes);
|
||||||
#ifdef LOCALYTICS
|
#ifdef LOCALYTICS
|
||||||
[[LocalyticsSession sharedLocalyticsSession] tagEvent:checkpoint attributes:attributes];
|
[[LocalyticsSession sharedLocalyticsSession] tagEvent:checkpoint attributes:attributes];
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef TESTFLIGHT_SDK_VERSION
|
||||||
|
[TestFlight passCheckpoint:checkpoint];
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -202,23 +202,28 @@
|
|||||||
[[Crashlytics sharedInstance] setObjectValue:[PearlConfig get].reviewedVersion forKey:@"reviewedVersion"];
|
[[Crashlytics sharedInstance] setObjectValue:[PearlConfig get].reviewedVersion forKey:@"reviewedVersion"];
|
||||||
|
|
||||||
#ifdef TESTFLIGHT_SDK_VERSION
|
#ifdef TESTFLIGHT_SDK_VERSION
|
||||||
[TestFlight addCustomEnvironmentInformation:[@([[MPConfig get].rememberLogin boolValue]) description]
|
[TestFlight addCustomEnvironmentInformation:PearlStringNSB([MPConfig get].rememberLogin)
|
||||||
forKey:@"rememberLogin"];
|
forKey:@"rememberLogin"];
|
||||||
[TestFlight addCustomEnvironmentInformation:[@([self storeManager].cloudEnabled) description] forKey:@"iCloud"];
|
[TestFlight addCustomEnvironmentInformation:PearlStringB([self storeManager].cloudEnabled)
|
||||||
[TestFlight addCustomEnvironmentInformation:[@([[MPConfig get].iCloudDecided boolValue]) description]
|
forKey:@"iCloud"];
|
||||||
|
[TestFlight addCustomEnvironmentInformation:PearlStringNSB([MPConfig get].iCloudDecided)
|
||||||
forKey:@"iCloudDecided"];
|
forKey:@"iCloudDecided"];
|
||||||
[TestFlight addCustomEnvironmentInformation:[@([[MPiOSConfig get].sendInfo boolValue]) description] forKey:@"sendInfo"];
|
[TestFlight addCustomEnvironmentInformation:PearlStringNSB([MPiOSConfig get].sendInfo)
|
||||||
[TestFlight addCustomEnvironmentInformation:[@([[MPiOSConfig get].helpHidden boolValue]) description]
|
forKey:@"sendInfo"];
|
||||||
|
[TestFlight addCustomEnvironmentInformation:PearlStringNSB([MPiOSConfig get].helpHidden)
|
||||||
forKey:@"helpHidden"];
|
forKey:@"helpHidden"];
|
||||||
[TestFlight addCustomEnvironmentInformation:[@([[MPiOSConfig get].showSetup boolValue]) description]
|
[TestFlight addCustomEnvironmentInformation:PearlStringNSB([MPiOSConfig get].showSetup)
|
||||||
forKey:@"showQuickStart"];
|
forKey:@"showQuickStart"];
|
||||||
[TestFlight addCustomEnvironmentInformation:[@([[PearlConfig get].firstRun boolValue]) description] forKey:@"firstRun"];
|
[TestFlight addCustomEnvironmentInformation:PearlStringNSB([PearlConfig get].firstRun)
|
||||||
[TestFlight addCustomEnvironmentInformation:[[PearlConfig get].launchCount description] forKey:@"launchCount"];
|
forKey:@"firstRun"];
|
||||||
[TestFlight addCustomEnvironmentInformation:[@([[PearlConfig get].askForReviews boolValue]) description]
|
[TestFlight addCustomEnvironmentInformation:PearlStringNSB([PearlConfig get].launchCount)
|
||||||
|
forKey:@"launchCount"];
|
||||||
|
[TestFlight addCustomEnvironmentInformation:PearlStringNSB([PearlConfig get].askForReviews)
|
||||||
forKey:@"askForReviews"];
|
forKey:@"askForReviews"];
|
||||||
[TestFlight addCustomEnvironmentInformation:[[PearlConfig get].reviewAfterLaunches description]
|
[TestFlight addCustomEnvironmentInformation:PearlStringNSB([PearlConfig get].reviewAfterLaunches)
|
||||||
forKey:@"reviewAfterLaunches"];
|
forKey:@"reviewAfterLaunches"];
|
||||||
[TestFlight addCustomEnvironmentInformation:[PearlConfig get].reviewedVersion forKey:@"reviewedVersion"];
|
[TestFlight addCustomEnvironmentInformation:[PearlConfig get].reviewedVersion
|
||||||
|
forKey:@"reviewedVersion"];
|
||||||
#endif
|
#endif
|
||||||
MPCheckpoint( MPCheckpointConfig, @{
|
MPCheckpoint( MPCheckpointConfig, @{
|
||||||
@"rememberLogin" : @([[MPConfig get].rememberLogin boolValue]),
|
@"rememberLogin" : @([[MPConfig get].rememberLogin boolValue]),
|
||||||
@ -228,9 +233,9 @@
|
|||||||
@"helpHidden" : @([[MPiOSConfig get].helpHidden boolValue]),
|
@"helpHidden" : @([[MPiOSConfig get].helpHidden boolValue]),
|
||||||
@"showQuickStart" : @([[MPiOSConfig get].showSetup boolValue]),
|
@"showQuickStart" : @([[MPiOSConfig get].showSetup boolValue]),
|
||||||
@"firstRun" : @([[PearlConfig get].firstRun boolValue]),
|
@"firstRun" : @([[PearlConfig get].firstRun boolValue]),
|
||||||
@"launchCount" : NilToNSNull([[PearlConfig get].launchCount description]),
|
@"launchCount" : NilToNSNull([PearlConfig get].launchCount),
|
||||||
@"askForReviews" : @([[PearlConfig get].askForReviews boolValue]),
|
@"askForReviews" : @([[PearlConfig get].askForReviews boolValue]),
|
||||||
@"reviewAfterLaunches" : NilToNSNull([[PearlConfig get].reviewAfterLaunches description]),
|
@"reviewAfterLaunches" : NilToNSNull([PearlConfig get].reviewAfterLaunches),
|
||||||
@"reviewedVersion" : NilToNSNull([PearlConfig get].reviewedVersion)
|
@"reviewedVersion" : NilToNSNull([PearlConfig get].reviewedVersion)
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user