2
0

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:
Maarten Billemont 2013-05-02 11:19:34 -04:00
parent 5e1e88bdeb
commit ab15694d9a
4 changed files with 61 additions and 40 deletions

2
External/Pearl vendored

@ -1 +1 @@
Subproject commit b889e6312d5ecd9d2e45eb1402cadc6e27ed84c4
Subproject commit 720acb2e6583a2ed9efbbe28ab53681a19070a42

View File

@ -15,6 +15,20 @@
#define STORE_OPTIONS
#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)
#if TARGET_OS_IPHONE
PearlAssociatedObjectProperty(PearlAlert*, HandleCloudContentAlert, handleCloudContentAlert);
@ -98,18 +112,18 @@ PearlAssociatedObjectProperty(NSManagedObjectContext*, MainManagedObjectContext,
[[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationWillTerminateNotification
object:[UIApplication sharedApplication] queue:nil
usingBlock:^(NSNotification *note) {
[self saveContexts];
[[self mainManagedObjectContext] saveToStore];
}];
[[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationWillResignActiveNotification
object:[UIApplication sharedApplication] queue:nil
usingBlock:^(NSNotification *note) {
[self saveContexts];
[[self mainManagedObjectContext] saveToStore];
}];
#else
[[NSNotificationCenter defaultCenter] addObserverForName:NSApplicationWillTerminateNotification
object:[NSApplication sharedApplication] queue:nil
usingBlock:^(NSNotification *note) {
[self saveContexts];
[[self mainManagedObjectContext] saveToStore];
}];
#endif
@ -126,6 +140,11 @@ PearlAssociatedObjectProperty(NSManagedObjectContext*, MainManagedObjectContext,
- (void)migrateLocalStoreForManager:(UbiquityStoreManager *)manager {
MPMigrationLevelLocalStore migrationLevel = [[NSUserDefaults standardUserDefaults] integerForKey:@"MPMigrationLevelLocalStore"];
if (migrationLevel >= MPMigrationLevelLocalStoreCurrent)
// Local store up-to-date.
return;
NSURL *applicationFilesDirectory = [[[NSFileManager defaultManager]
URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
NSURL *oldLocalStoreURL = [[applicationFilesDirectory
@ -137,10 +156,12 @@ PearlAssociatedObjectProperty(NSManagedObjectContext*, MainManagedObjectContext,
}
if (![[NSFileManager defaultManager] fileExistsAtPath:oldLocalStoreURL.path isDirectory:NO]) {
// No local store to migrate.
[[NSUserDefaults standardUserDefaults] setInteger:MPMigrationLevelLocalStoreCurrent forKey:MPMigrationLevelLocalStoreKey];
return;
}
if ([[NSFileManager defaultManager] fileExistsAtPath:newLocalStoreURL.path isDirectory:NO]) {
wrn(@"Can't migrate old local store: A new local store already exists.");
[[NSUserDefaults standardUserDefaults] setInteger:MPMigrationLevelLocalStoreCurrent forKey:MPMigrationLevelLocalStoreKey];
return;
}
@ -172,11 +193,17 @@ PearlAssociatedObjectProperty(NSManagedObjectContext*, MainManagedObjectContext,
return;
}
[[NSUserDefaults standardUserDefaults] setInteger:MPMigrationLevelLocalStoreCurrent forKey:MPMigrationLevelLocalStoreKey];
inf(@"Successfully migrated old to new local store.");
}
- (void)migrateCloudStoreForManager:(UbiquityStoreManager *)manager {
MPMigrationLevelCloudStore migrationLevel = [[NSUserDefaults standardUserDefaults] integerForKey:@"MPMigrationLevelCloudStore"];
if (migrationLevel >= MPMigrationLevelCloudStoreCurrent)
// Cloud store up-to-date.
return;
// Migrate cloud enabled preference.
NSNumber *oldCloudEnabled = [[NSUserDefaults standardUserDefaults] objectForKey:@"iCloudEnabledKey"];
if ([oldCloudEnabled boolValue]) {
@ -186,12 +213,15 @@ PearlAssociatedObjectProperty(NSManagedObjectContext*, MainManagedObjectContext,
// Migrate cloud store.
NSString *uuid = [[NSUserDefaults standardUserDefaults] stringForKey:@"LocalUUIDKey"];
if (!uuid)
// No old cloud store to migrate.
if (!uuid) {
// No old cloud store to migrate.
[[NSUserDefaults standardUserDefaults] setInteger:MPMigrationLevelCloudStoreCurrent forKey:MPMigrationLevelCloudStoreKey];
return;
}
if (![manager cloudSafeForSeeding]) {
wrn(@"Can't migrate old cloud store: A new cloud store already exists.");
[[NSUserDefaults standardUserDefaults] setInteger:MPMigrationLevelCloudStoreCurrent forKey:MPMigrationLevelCloudStoreKey];
return;
}
@ -244,27 +274,10 @@ PearlAssociatedObjectProperty(NSManagedObjectContext*, MainManagedObjectContext,
error:nil cause:nil context:nil])
return;
[[NSUserDefaults standardUserDefaults] removeObjectForKey:@"LocalUUIDKey"];
[[NSUserDefaults standardUserDefaults] setInteger:MPMigrationLevelCloudStoreCurrent forKey:MPMigrationLevelCloudStoreKey];
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
- (NSManagedObjectContext *)managedObjectContextForUbiquityStoreManager:(UbiquityStoreManager *)usm {
@ -301,8 +314,7 @@ PearlAssociatedObjectProperty(NSManagedObjectContext*, MainManagedObjectContext,
} );
// Create our contexts.
NSManagedObjectContext
*privateManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
NSManagedObjectContext *privateManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[privateManagedObjectContext performBlockAndWait:^{
privateManagedObjectContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy;
privateManagedObjectContext.persistentStoreCoordinator = coordinator;

View File

@ -68,7 +68,7 @@ typedef enum {
#define MPCheckpointApps @"MPCheckpointApps"
#define MPCheckpointApp @"MPCheckpointApp"
#define MPCheckpointEmergencyGenerator @"MPCheckpointEmergencyGenerator"
#define MPCheckpointLogs @"MPCheckpointLogs"
#define MPCheckpointLogs @"MPCheckpointLogs"
#define MPSignedInNotification @"MPSignedInNotification"
#define MPSignedOutNotification @"MPSignedOutNotification"
@ -78,7 +78,11 @@ typedef enum {
static void MPCheckpoint(NSString *checkpoint, NSDictionary *attributes) {
inf(@"%@: %@", checkpoint, attributes);
#ifdef LOCALYTICS
[[LocalyticsSession sharedLocalyticsSession] tagEvent:checkpoint attributes:attributes];
#endif
#ifdef TESTFLIGHT_SDK_VERSION
[TestFlight passCheckpoint:checkpoint];
#endif
}

View File

@ -202,23 +202,28 @@
[[Crashlytics sharedInstance] setObjectValue:[PearlConfig get].reviewedVersion forKey:@"reviewedVersion"];
#ifdef TESTFLIGHT_SDK_VERSION
[TestFlight addCustomEnvironmentInformation:[@([[MPConfig get].rememberLogin boolValue]) description]
[TestFlight addCustomEnvironmentInformation:PearlStringNSB([MPConfig get].rememberLogin)
forKey:@"rememberLogin"];
[TestFlight addCustomEnvironmentInformation:[@([self storeManager].cloudEnabled) description] forKey:@"iCloud"];
[TestFlight addCustomEnvironmentInformation:[@([[MPConfig get].iCloudDecided boolValue]) description]
[TestFlight addCustomEnvironmentInformation:PearlStringB([self storeManager].cloudEnabled)
forKey:@"iCloud"];
[TestFlight addCustomEnvironmentInformation:PearlStringNSB([MPConfig get].iCloudDecided)
forKey:@"iCloudDecided"];
[TestFlight addCustomEnvironmentInformation:[@([[MPiOSConfig get].sendInfo boolValue]) description] forKey:@"sendInfo"];
[TestFlight addCustomEnvironmentInformation:[@([[MPiOSConfig get].helpHidden boolValue]) description]
[TestFlight addCustomEnvironmentInformation:PearlStringNSB([MPiOSConfig get].sendInfo)
forKey:@"sendInfo"];
[TestFlight addCustomEnvironmentInformation:PearlStringNSB([MPiOSConfig get].helpHidden)
forKey:@"helpHidden"];
[TestFlight addCustomEnvironmentInformation:[@([[MPiOSConfig get].showSetup boolValue]) description]
[TestFlight addCustomEnvironmentInformation:PearlStringNSB([MPiOSConfig get].showSetup)
forKey:@"showQuickStart"];
[TestFlight addCustomEnvironmentInformation:[@([[PearlConfig get].firstRun boolValue]) description] forKey:@"firstRun"];
[TestFlight addCustomEnvironmentInformation:[[PearlConfig get].launchCount description] forKey:@"launchCount"];
[TestFlight addCustomEnvironmentInformation:[@([[PearlConfig get].askForReviews boolValue]) description]
[TestFlight addCustomEnvironmentInformation:PearlStringNSB([PearlConfig get].firstRun)
forKey:@"firstRun"];
[TestFlight addCustomEnvironmentInformation:PearlStringNSB([PearlConfig get].launchCount)
forKey:@"launchCount"];
[TestFlight addCustomEnvironmentInformation:PearlStringNSB([PearlConfig get].askForReviews)
forKey:@"askForReviews"];
[TestFlight addCustomEnvironmentInformation:[[PearlConfig get].reviewAfterLaunches description]
[TestFlight addCustomEnvironmentInformation:PearlStringNSB([PearlConfig get].reviewAfterLaunches)
forKey:@"reviewAfterLaunches"];
[TestFlight addCustomEnvironmentInformation:[PearlConfig get].reviewedVersion forKey:@"reviewedVersion"];
[TestFlight addCustomEnvironmentInformation:[PearlConfig get].reviewedVersion
forKey:@"reviewedVersion"];
#endif
MPCheckpoint( MPCheckpointConfig, @{
@"rememberLogin" : @([[MPConfig get].rememberLogin boolValue]),
@ -228,9 +233,9 @@
@"helpHidden" : @([[MPiOSConfig get].helpHidden boolValue]),
@"showQuickStart" : @([[MPiOSConfig get].showSetup boolValue]),
@"firstRun" : @([[PearlConfig get].firstRun boolValue]),
@"launchCount" : NilToNSNull([[PearlConfig get].launchCount description]),
@"launchCount" : NilToNSNull([PearlConfig get].launchCount),
@"askForReviews" : @([[PearlConfig get].askForReviews boolValue]),
@"reviewAfterLaunches" : NilToNSNull([[PearlConfig get].reviewAfterLaunches description]),
@"reviewAfterLaunches" : NilToNSNull([PearlConfig get].reviewAfterLaunches),
@"reviewedVersion" : NilToNSNull([PearlConfig get].reviewedVersion)
} );
}