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:
parent
71e3f44c8c
commit
076cfb1257
Binary file not shown.
@ -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
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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
2
External/Pearl
vendored
@ -1 +1 @@
|
|||||||
Subproject commit 2293e3a48a0e54c09a7ce135c946e4c4ca46bac7
|
Subproject commit c2b07f9c648fd6386aca0c982b44769bb36ac4b3
|
2
External/UbiquityStoreManager
vendored
2
External/UbiquityStoreManager
vendored
@ -1 +1 @@
|
|||||||
Subproject commit 226619a45744dd4aefbbdb948d7e44ab3ecad341
|
Subproject commit 389c8b78501331af77c363857f381a497cbf0060
|
@ -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 auto‑correct 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 auto‑corrected 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 {
|
||||||
|
@ -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];
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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"];
|
||||||
|
@ -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];
|
||||||
}];
|
}];
|
||||||
|
|
||||||
|
@ -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];
|
||||||
}];
|
}];
|
||||||
|
@ -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];
|
||||||
|
@ -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];
|
||||||
}];
|
}];
|
||||||
|
@ -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 auto‑correct 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 auto‑corrected 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 {
|
||||||
|
Loading…
Reference in New Issue
Block a user