2
0

MOC saving improvements, Mac app activation, loading overlay, USM update.

[MOVED]     iOS code from MPAppDelegate_Shared to MPiOSAppDelegate.
[FIXED]     Perform MOC saving in MOC perform blocks.
[FIXED]     Mac: Activate app when showing password window and not active.
[FIXED]     Hide overlay while corruption dialog is up.
[FIXED]     Hide corruption dialog when reloading store.
This commit is contained in:
Maarten Billemont 2013-05-11 08:54:49 -04:00
parent 71e3f44c8c
commit 076cfb1257
14 changed files with 113 additions and 89 deletions

View File

@ -170,6 +170,16 @@ OBJC_EXTERN void CLSNSLog(NSString *format, ...) NS_FORMAT_FUNCTION(1,2);
**/ **/
@property (nonatomic, readonly) NSDate *crashedOnDate; @property (nonatomic, readonly) NSDate *crashedOnDate;
/**
* Returns the os version that the application crashed on.
**/
@property (nonatomic, readonly) NSString *OSVersion;
/**
* Returns the os build version that the application crashed on.
**/
@property (nonatomic, readonly) NSString *OSBuildVersion;
@end @end
/** /**

View File

@ -15,13 +15,13 @@
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>FMWK</string> <string>FMWK</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>2.0.8</string> <string>2.0.9</string>
<key>CFBundleSupportedPlatforms</key> <key>CFBundleSupportedPlatforms</key>
<array> <array>
<string>iPhoneOS</string> <string>iPhoneOS</string>
</array> </array>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>0200.08.00</string> <string>0200.09.00</string>
<key>DTPlatformName</key> <key>DTPlatformName</key>
<string>iphoneos</string> <string>iphoneos</string>
<key>MinimumOSVersion</key> <key>MinimumOSVersion</key>

2
External/Pearl vendored

@ -1 +1 @@
Subproject commit 2293e3a48a0e54c09a7ce135c946e4c4ca46bac7 Subproject commit c2b07f9c648fd6386aca0c982b44769bb36ac4b3

@ -1 +1 @@
Subproject commit 226619a45744dd4aefbbdb948d7e44ab3ecad341 Subproject commit 389c8b78501331af77c363857f381a497cbf0060

View File

@ -33,11 +33,6 @@ typedef NS_ENUM(NSInteger, MPMigrationLevelCloudStore) {
}; };
@implementation MPAppDelegate_Shared(Store) @implementation MPAppDelegate_Shared(Store)
#if TARGET_OS_IPHONE
PearlAssociatedObjectProperty(PearlAlert*, HandleCloudContentAlert, handleCloudContentAlert);
PearlAssociatedObjectProperty(PearlAlert*, FixCloudContentAlert, fixCloudContentAlert);
PearlAssociatedObjectProperty(PearlOverlay*, StoreLoading, storeLoading);
#endif
PearlAssociatedObjectProperty(NSManagedObjectContext*, PrivateManagedObjectContext, privateManagedObjectContext); PearlAssociatedObjectProperty(NSManagedObjectContext*, PrivateManagedObjectContext, privateManagedObjectContext);
PearlAssociatedObjectProperty(NSManagedObjectContext*, MainManagedObjectContext, mainManagedObjectContext); PearlAssociatedObjectProperty(NSManagedObjectContext*, MainManagedObjectContext, mainManagedObjectContext);
@ -127,7 +122,10 @@ PearlAssociatedObjectProperty(NSManagedObjectContext*, MainManagedObjectContext,
[[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 mainManagedObjectContext] saveToStore]; NSManagedObjectContext *moc = self.mainManagedObjectContextIfReady;
[moc performBlockAndWait:^{
[moc saveToStore];
}];
}]; }];
#endif #endif
@ -330,15 +328,13 @@ PearlAssociatedObjectProperty(NSManagedObjectContext*, MainManagedObjectContext,
- (void)ubiquityStoreManager:(UbiquityStoreManager *)manager willLoadStoreIsCloud:(BOOL)isCloudStore { - (void)ubiquityStoreManager:(UbiquityStoreManager *)manager willLoadStoreIsCloud:(BOOL)isCloudStore {
NSManagedObjectContext *moc = self.mainManagedObjectContextIfReady;
[moc performBlockAndWait:^{
[moc saveToStore];
self.privateManagedObjectContext = nil; self.privateManagedObjectContext = nil;
self.mainManagedObjectContext = nil; self.mainManagedObjectContext = nil;
}];
#if TARGET_OS_IPHONE
dispatch_async( dispatch_get_main_queue(), ^{
if (![self.storeLoading isVisible])
self.storeLoading = [PearlOverlay showOverlayWithTitle:@"Opening Your Data"];
} );
#endif
[self migrateStoreForManager:manager isCloud:isCloudStore]; [self migrateStoreForManager:manager isCloud:isCloudStore];
} }
@ -378,12 +374,6 @@ PearlAssociatedObjectProperty(NSManagedObjectContext*, MainManagedObjectContext,
self.privateManagedObjectContext = privateManagedObjectContext; self.privateManagedObjectContext = privateManagedObjectContext;
self.mainManagedObjectContext = mainManagedObjectContext; self.mainManagedObjectContext = mainManagedObjectContext;
#if TARGET_OS_IPHONE
[self.handleCloudContentAlert cancelAlertAnimated:YES];
[self.fixCloudContentAlert cancelAlertAnimated:YES];
[self.storeLoading cancelOverlay];
#endif
} }
- (void)ubiquityStoreManager:(UbiquityStoreManager *)manager didEncounterError:(NSError *)error cause:(UbiquityStoreErrorCause)cause - (void)ubiquityStoreManager:(UbiquityStoreManager *)manager didEncounterError:(NSError *)error cause:(UbiquityStoreErrorCause)cause
@ -397,46 +387,6 @@ PearlAssociatedObjectProperty(NSManagedObjectContext*, MainManagedObjectContext,
} ); } );
} }
- (BOOL)ubiquityStoreManager:(UbiquityStoreManager *)manager handleCloudContentCorruptionWithHealthyStore:(BOOL)storeHealthy {
#if TARGET_OS_IPHONE
if (manager.cloudEnabled && !storeHealthy && !([self.handleCloudContentAlert.alertView isVisible] || [self.fixCloudContentAlert.alertView isVisible]))
dispatch_async( dispatch_get_main_queue(), ^{
[self showCloudContentAlert];
} );
#endif
return NO;
}
#if TARGET_OS_IPHONE
- (void)showCloudContentAlert {
__weak MPAppDelegate_Shared *wSelf = self;
[self.handleCloudContentAlert cancelAlertAnimated:NO];
self.handleCloudContentAlert = [PearlAlert showActivityWithTitle:@"iCloud Sync Problem" message:
@"Waiting for your other device to autocorrect the problem..."
initAlert:^(UIAlertView *alert) {
[alert addButtonWithTitle:@"Fix Now"];
}];
self.handleCloudContentAlert.tappedButtonBlock = ^(UIAlertView *alert, NSInteger buttonIndex) {
wSelf.fixCloudContentAlert = [PearlAlert showAlertWithTitle:@"Fix iCloud Now" message:
@"This problem can usually be autocorrected by opening the app on another device where you recently made changes.\n"
@"You can correct the problem from this device anyway, but recent changes made on another device might get lost."
viewStyle:UIAlertViewStyleDefault initAlert:nil tappedButtonBlock:
^(UIAlertView *alert_, NSInteger buttonIndex_) {
if (buttonIndex_ == alert_.cancelButtonIndex)
[wSelf showCloudContentAlert];
if (buttonIndex_ == [alert_ firstOtherButtonIndex])
[wSelf.storeManager rebuildCloudContentFromCloudStoreOrLocalStore:YES];
}
cancelTitle:[PearlStrings get].commonButtonBack otherTitles:@"Fix Anyway", nil];
};
}
#endif
#pragma mark - Utilities #pragma mark - Utilities
- (void)addElementNamed:(NSString *)siteName completion:(void (^)(MPElementEntity *element))completion { - (void)addElementNamed:(NSString *)siteName completion:(void (^)(MPElementEntity *element))completion {

View File

@ -13,11 +13,12 @@
- (BOOL)saveToStore { - (BOOL)saveToStore {
NSError *error; __block BOOL success = NO;
if (![self save:&error]) { [self performBlockAndWait:^{
NSError *error = nil;
if (!(success = [self save:&error]))
err(@"While saving: %@", error); err(@"While saving: %@", error);
return NO; }];
}
return !self.parentContext || [self.parentContext saveToStore]; return !self.parentContext || [self.parentContext saveToStore];
} }

View File

@ -26,7 +26,6 @@
@property(nonatomic, weak) IBOutlet NSMenuItem *dialogStyleHUD; @property(nonatomic, weak) IBOutlet NSMenuItem *dialogStyleHUD;
- (IBAction)showPasswordWindow; - (IBAction)showPasswordWindow;
- (IBAction)activate:(id)sender;
- (IBAction)togglePreference:(NSMenuItem *)sender; - (IBAction)togglePreference:(NSMenuItem *)sender;
- (IBAction)newUser:(NSMenuItem *)sender; - (IBAction)newUser:(NSMenuItem *)sender;
- (IBAction)lock:(id)sender; - (IBAction)lock:(id)sender;

View File

@ -119,18 +119,6 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
[self.statusItem popUpStatusItemMenu:self.statusMenu]; [self.statusItem popUpStatusItemMenu:self.statusMenu];
} }
- (IBAction)activate:(id)sender {
if (![self activeUserForThread])
// No user, can't activate.
return;
if ([[NSApplication sharedApplication] isActive])
[self applicationDidBecomeActive:nil];
else
[[NSApplication sharedApplication] activateIgnoringOtherApps:YES];
}
- (IBAction)togglePreference:(NSMenuItem *)sender { - (IBAction)togglePreference:(NSMenuItem *)sender {
if (sender == self.useICloudItem) if (sender == self.useICloudItem)
@ -227,12 +215,12 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
self.statusItem.target = self; self.statusItem.target = self;
self.statusItem.action = @selector(showMenu); self.statusItem.action = @selector(showMenu);
[[NSNotificationCenter defaultCenter] addObserverForName:UbiquityManagedStoreDidChangeNotification object:nil queue:nil usingBlock: [[NSNotificationCenter defaultCenter] addObserverForName:USMStoreDidChangeNotification object:nil queue:nil usingBlock:
^(NSNotification *note) { ^(NSNotification *note) {
[self updateUsers]; [self updateUsers];
}]; }];
[[NSNotificationCenter defaultCenter] [[NSNotificationCenter defaultCenter]
addObserverForName:UbiquityManagedStoreDidImportChangesNotification object:nil queue:nil usingBlock: addObserverForName:USMStoreDidImportChangesNotification object:nil queue:nil usingBlock:
^(NSNotification *note) { ^(NSNotification *note) {
[self updateUsers]; [self updateUsers];
}]; }];
@ -359,6 +347,14 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
- (IBAction)showPasswordWindow { - (IBAction)showPasswordWindow {
// If no user, can't activate.
if (![self activeUserForThread])
return;
// Activate the app if not active.
if (![[NSApplication sharedApplication] isActive])
[[NSApplication sharedApplication] activateIgnoringOtherApps:YES];
// Don't show window if we weren't already running (ie. if we haven't been activated before). // Don't show window if we weren't already running (ie. if we haven't been activated before).
if (!self.passwordWindow) if (!self.passwordWindow)
self.passwordWindow = [[MPPasswordWindowController alloc] initWithWindowNibName:@"MPPasswordWindowController"]; self.passwordWindow = [[MPPasswordWindowController alloc] initWithWindowNibName:@"MPPasswordWindowController"];

View File

@ -69,7 +69,7 @@
[self.window close]; [self.window close];
}]; }];
[[NSNotificationCenter defaultCenter] [[NSNotificationCenter defaultCenter]
addObserverForName:UbiquityManagedStoreDidChangeNotification object:nil queue:nil usingBlock:^(NSNotification *note) { addObserverForName:USMStoreDidChangeNotification object:nil queue:nil usingBlock:^(NSNotification *note) {
[self waitUntilStoreLoaded]; [self waitUntilStoreLoaded];
}]; }];

View File

@ -15,7 +15,7 @@
- (void)viewDidLoad { - (void)viewDidLoad {
[[NSNotificationCenter defaultCenter] addObserverForName:UbiquityManagedStoreDidChangeNotification object:nil queue:nil usingBlock: [[NSNotificationCenter defaultCenter] addObserverForName:USMStoreDidChangeNotification object:nil queue:nil usingBlock:
^(NSNotification *note) { ^(NSNotification *note) {
[self updateData]; [self updateData];
}]; }];

View File

@ -107,7 +107,7 @@
[self.navigationController popToRootViewControllerAnimated:animated]; [self.navigationController popToRootViewControllerAnimated:animated];
}]; }];
}]; }];
[[NSNotificationCenter defaultCenter] addObserverForName:UbiquityManagedStoreDidChangeNotification object:nil queue:nil usingBlock: [[NSNotificationCenter defaultCenter] addObserverForName:USMStoreDidChangeNotification object:nil queue:nil usingBlock:
^(NSNotification *note) { ^(NSNotification *note) {
if (!self.activeElementForThread) if (!self.activeElementForThread)
[self didSelectElement:nil]; [self didSelectElement:nil];

View File

@ -164,11 +164,11 @@
[self initializeWordLabel:wordLabel]; [self initializeWordLabel:wordLabel];
} recurse:NO]; } recurse:NO];
[[NSNotificationCenter defaultCenter] addObserverForName:UbiquityManagedStoreDidChangeNotification object:nil queue:nil usingBlock: [[NSNotificationCenter defaultCenter] addObserverForName:USMStoreDidChangeNotification object:nil queue:nil usingBlock:
^(NSNotification *note) { ^(NSNotification *note) {
[self updateUsers]; [self updateUsers];
}]; }];
[[NSNotificationCenter defaultCenter] addObserverForName:UbiquityManagedStoreDidImportChangesNotification object:nil queue:nil [[NSNotificationCenter defaultCenter] addObserverForName:USMStoreDidImportChangesNotification object:nil queue:nil
usingBlock:^(NSNotification *note) { usingBlock:^(NSNotification *note) {
[self updateUsers]; [self updateUsers];
}]; }];

View File

@ -12,6 +12,13 @@
#import "IASKSettingsReader.h" #import "IASKSettingsReader.h"
#import "GPPSignIn.h" #import "GPPSignIn.h"
@interface MPiOSAppDelegate()
@property(nonatomic, strong) PearlAlert *handleCloudContentAlert;
@property(nonatomic, strong) PearlAlert *fixCloudContentAlert;
@property(nonatomic, strong) PearlOverlay *storeLoading;
@end
@implementation MPiOSAppDelegate @implementation MPiOSAppDelegate
+ (void)initialize { + (void)initialize {
@ -630,6 +637,67 @@
} }
#pragma mark - Google+
- (void)ubiquityStoreManager:(UbiquityStoreManager *)manager willLoadStoreIsCloud:(BOOL)isCloudStore {
dispatch_async( dispatch_get_main_queue(), ^{
[self.handleCloudContentAlert cancelAlertAnimated:YES];
if (![self.storeLoading isVisible])
self.storeLoading = [PearlOverlay showOverlayWithTitle:@"Opening Your Data"];
} );
[super ubiquityStoreManager:manager willLoadStoreIsCloud:isCloudStore];
}
- (void)ubiquityStoreManager:(UbiquityStoreManager *)manager didLoadStoreForCoordinator:(NSPersistentStoreCoordinator *)coordinator
isCloud:(BOOL)isCloudStore {
[super ubiquityStoreManager:manager didLoadStoreForCoordinator:coordinator isCloud:isCloudStore];
dispatch_async( dispatch_get_main_queue(), ^{
[self.handleCloudContentAlert cancelAlertAnimated:YES];
[self.fixCloudContentAlert cancelAlertAnimated:YES];
[self.storeLoading cancelOverlayAnimated:YES];
} );
}
- (BOOL)ubiquityStoreManager:(UbiquityStoreManager *)manager handleCloudContentCorruptionWithHealthyStore:(BOOL)storeHealthy {
if (manager.cloudEnabled && !storeHealthy && !([self.handleCloudContentAlert.alertView isVisible] || [self.fixCloudContentAlert.alertView isVisible]))
dispatch_async( dispatch_get_main_queue(), ^{
[self.storeLoading cancelOverlayAnimated:YES];
[self showCloudContentAlert];
} );
return NO;
}
- (void)showCloudContentAlert {
__weak MPiOSAppDelegate *wSelf = self;
[self.handleCloudContentAlert cancelAlertAnimated:NO];
self.handleCloudContentAlert = [PearlAlert showActivityWithTitle:@"iCloud Sync Problem" message:
@"Waiting for your other device to autocorrect the problem..."
initAlert:^(UIAlertView *alert) {
[alert addButtonWithTitle:@"Fix Now"];
}];
self.handleCloudContentAlert.tappedButtonBlock = ^(UIAlertView *alert, NSInteger buttonIndex) {
wSelf.fixCloudContentAlert = [PearlAlert showAlertWithTitle:@"Fix iCloud Now" message:
@"This problem can usually be autocorrected by opening the app on another device where you recently made changes.\n"
@"You can correct the problem from this device anyway, but recent changes made on another device might get lost."
viewStyle:UIAlertViewStyleDefault initAlert:nil tappedButtonBlock:
^(UIAlertView *alert_, NSInteger buttonIndex_) {
if (buttonIndex_ == alert_.cancelButtonIndex)
[wSelf showCloudContentAlert];
if (buttonIndex_ == [alert_ firstOtherButtonIndex])
[wSelf.storeManager rebuildCloudContentFromCloudStoreOrLocalStore:YES];
}
cancelTitle:[PearlStrings get].commonButtonBack otherTitles:@"Fix Anyway", nil];
};
}
#pragma mark - Google+ #pragma mark - Google+
- (NSDictionary *)googlePlusInfo { - (NSDictionary *)googlePlusInfo {