2
0

Some usability improvements + apptentive fixes.

[IMPROVED]  Make persistence more lazy to avoid UI blocks.
[IMPROVED]  Use "Master Password" as CFBundleDisplayName at runtime.  No
            home-screen length restrictions there.
[FIXED]     Inform Apptentive of significant events.
This commit is contained in:
Maarten Billemont 2012-05-27 14:26:13 +02:00
parent ac14b10752
commit 7d0ea4b3f5
11 changed files with 170 additions and 119 deletions

2
.gitmodules vendored
View File

@ -6,7 +6,7 @@
url = git://github.com/futuretap/InAppSettingsKit.git
[submodule "External/iCloudStoreManager"]
path = External/iCloudStoreManager
url = git://github.com/alekseyn/iCloudStoreManager.git
url = git://github.com/lhunath/iCloudStoreManager.git
[submodule "External/apptentive"]
path = External/apptentive
url = git://github.com/apptentive/apptentive-ios.git

2
External/Pearl vendored

@ -1 +1 @@
Subproject commit f92b0b1490e483d1bd4b8b6d1b9482c7ecfd4e44
Subproject commit 046dba155843d7a10d5c087e5b1d698ab271df67

@ -1 +1 @@
Subproject commit 6c19d5aa27b07d9a55cd19b003c4383b055b995f
Subproject commit 84c718a57d64933e626d3756993fce513ad2bc2a

View File

@ -18,6 +18,13 @@
DA0A1D1215690AD40092735D /* tip_arrow_wood.png in Resources */ = {isa = PBXBuildFile; fileRef = DA0A1D0C15690AD40092735D /* tip_arrow_wood.png */; };
DA0A1D1515690AF40092735D /* Icon-72@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DA0A1D1315690AF30092735D /* Icon-72@2x.png */; };
DA0A1D1615690AF40092735D /* Icon-Small-50@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DA0A1D1415690AF40092735D /* Icon-Small-50@2x.png */; };
DA30E9CE15722ECA00A68B4C /* NSBundle_PearlMutableInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = DA30E9CB15722ECA00A68B4C /* NSBundle_PearlMutableInfo.h */; };
DA30E9CF15722ECA00A68B4C /* NSBundle_PearlMutableInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = DA30E9CC15722ECA00A68B4C /* NSBundle_PearlMutableInfo.m */; };
DA30E9D015722ECA00A68B4C /* Pearl.m in Sources */ = {isa = PBXBuildFile; fileRef = DA30E9CD15722ECA00A68B4C /* Pearl.m */; };
DA30E9D215722EE500A68B4C /* Pearl-Crypto.m in Sources */ = {isa = PBXBuildFile; fileRef = DA30E9D115722EE500A68B4C /* Pearl-Crypto.m */; };
DA30E9D415722EF400A68B4C /* Pearl-UIKit.m in Sources */ = {isa = PBXBuildFile; fileRef = DA30E9D315722EF400A68B4C /* Pearl-UIKit.m */; };
DA30E9D715723E6900A68B4C /* PearlLazy.h in Headers */ = {isa = PBXBuildFile; fileRef = DA30E9D515723E6900A68B4C /* PearlLazy.h */; };
DA30E9D815723E6900A68B4C /* PearlLazy.m in Sources */ = {isa = PBXBuildFile; fileRef = DA30E9D615723E6900A68B4C /* PearlLazy.m */; };
DA4425CC1557BED40052177D /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA5BFA4A147E415C00F98B1E /* Foundation.framework */; };
DA4426001557BF260052177D /* UbiquityStoreManager.h in Headers */ = {isa = PBXBuildFile; fileRef = DA4425F11557BF260052177D /* UbiquityStoreManager.h */; };
DA4426011557BF260052177D /* UbiquityStoreManager.m in Sources */ = {isa = PBXBuildFile; fileRef = DA4425F21557BF260052177D /* UbiquityStoreManager.m */; };
@ -925,6 +932,13 @@
DA0A1D0C15690AD40092735D /* tip_arrow_wood.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = tip_arrow_wood.png; path = Resources/Tooltips/tip_arrow_wood.png; sourceTree = SOURCE_ROOT; };
DA0A1D1315690AF30092735D /* Icon-72@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-72@2x.png"; sourceTree = "<group>"; };
DA0A1D1415690AF40092735D /* Icon-Small-50@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small-50@2x.png"; sourceTree = "<group>"; };
DA30E9CB15722ECA00A68B4C /* NSBundle_PearlMutableInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NSBundle_PearlMutableInfo.h; sourceTree = "<group>"; };
DA30E9CC15722ECA00A68B4C /* NSBundle_PearlMutableInfo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NSBundle_PearlMutableInfo.m; sourceTree = "<group>"; };
DA30E9CD15722ECA00A68B4C /* Pearl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Pearl.m; sourceTree = "<group>"; };
DA30E9D115722EE500A68B4C /* Pearl-Crypto.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "Pearl-Crypto.m"; sourceTree = "<group>"; };
DA30E9D315722EF400A68B4C /* Pearl-UIKit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "Pearl-UIKit.m"; sourceTree = "<group>"; };
DA30E9D515723E6900A68B4C /* PearlLazy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PearlLazy.h; sourceTree = "<group>"; };
DA30E9D615723E6900A68B4C /* PearlLazy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PearlLazy.m; sourceTree = "<group>"; };
DA4425CB1557BED40052177D /* libiCloudStoreManager.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libiCloudStoreManager.a; sourceTree = BUILT_PRODUCTS_DIR; };
DA4425F11557BF260052177D /* UbiquityStoreManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UbiquityStoreManager.h; sourceTree = "<group>"; };
DA4425F21557BF260052177D /* UbiquityStoreManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UbiquityStoreManager.m; sourceTree = "<group>"; };
@ -2892,6 +2906,8 @@
DAFE45D715039823003ABA7C /* Pearl */ = {
isa = PBXGroup;
children = (
DA30E9CB15722ECA00A68B4C /* NSBundle_PearlMutableInfo.h */,
DA30E9CC15722ECA00A68B4C /* NSBundle_PearlMutableInfo.m */,
DAFE45D815039823003ABA7C /* NSObject_PearlExport.h */,
DAFE45D915039823003ABA7C /* NSObject_PearlExport.m */,
DAFE45DA15039823003ABA7C /* NSString_PearlNSArrayFormat.h */,
@ -2899,6 +2915,7 @@
DAFE45DC15039823003ABA7C /* NSString_PearlSEL.h */,
DAFE45DD15039823003ABA7C /* NSString_PearlSEL.m */,
DAFE45DE15039823003ABA7C /* Pearl.h */,
DA30E9CD15722ECA00A68B4C /* Pearl.m */,
DAFE45DF15039823003ABA7C /* PearlAbstractStrings.h */,
DAFE45E015039823003ABA7C /* PearlAbstractStrings.m */,
DAFE45E315039823003ABA7C /* PearlCodeUtils.h */,
@ -2909,6 +2926,8 @@
DAFE45E815039823003ABA7C /* PearlDeviceUtils.m */,
DAFE45E915039823003ABA7C /* PearlInfoPlist.h */,
DAFE45EA15039823003ABA7C /* PearlInfoPlist.m */,
DA30E9D515723E6900A68B4C /* PearlLazy.h */,
DA30E9D615723E6900A68B4C /* PearlLazy.m */,
DAFE45EB15039823003ABA7C /* PearlLogger.h */,
DAFE45EC15039823003ABA7C /* PearlLogger.m */,
DAFE45ED15039823003ABA7C /* PearlMathUtils.h */,
@ -2940,6 +2959,7 @@
children = (
DA79A9BB1557DB6F00BAA07A /* libscryptenc-ios.a */,
DAFE45FD15039823003ABA7C /* Pearl-Crypto.h */,
DA30E9D115722EE500A68B4C /* Pearl-Crypto.m */,
DAFE45FE15039823003ABA7C /* PearlCryptUtils.h */,
DAFE45FF15039823003ABA7C /* PearlCryptUtils.m */,
DAFE460015039823003ABA7C /* PearlKeyChain.h */,
@ -2959,6 +2979,7 @@
children = (
DAFE460815039823003ABA7C /* Pearl-UIKit-Dependencies.h */,
DAFE460915039823003ABA7C /* Pearl-UIKit.h */,
DA30E9D315722EF400A68B4C /* Pearl-UIKit.m */,
DAFE460A15039823003ABA7C /* PearlAlert.h */,
DAFE460B15039823003ABA7C /* PearlAlert.m */,
DAFE4A60150399FF003ABA7C /* PearlAppDelegate.m */,
@ -3094,6 +3115,8 @@
DAFE4A5615039824003ABA7C /* PearlWebViewController.h in Headers */,
DAFE4A5815039824003ABA7C /* UIImage_PearlScaling.h in Headers */,
DAFE4A63150399FF003ABA7C /* PearlAppDelegate.h in Headers */,
DA30E9CE15722ECA00A68B4C /* NSBundle_PearlMutableInfo.h in Headers */,
DA30E9D715723E6900A68B4C /* PearlLazy.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -4141,6 +4164,11 @@
DAFE4A5715039824003ABA7C /* PearlWebViewController.m in Sources */,
DAFE4A5915039824003ABA7C /* UIImage_PearlScaling.m in Sources */,
DAFE4A62150399FF003ABA7C /* PearlAppDelegate.m in Sources */,
DA30E9CF15722ECA00A68B4C /* NSBundle_PearlMutableInfo.m in Sources */,
DA30E9D015722ECA00A68B4C /* Pearl.m in Sources */,
DA30E9D215722EE500A68B4C /* Pearl-Crypto.m in Sources */,
DA30E9D415722EF400A68B4C /* Pearl-UIKit.m in Sources */,
DA30E9D815723E6900A68B4C /* PearlLazy.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@ -63,14 +63,23 @@
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
buildConfiguration = "Production"
buildConfiguration = "AppStore"
debugDocumentVersioning = "YES">
<BuildableProductRunnable>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "DA5BFA43147E415C00F98B1E"
BuildableName = "MasterPassword.app"
BlueprintName = "MasterPassword"
ReferencedContainer = "container:MasterPassword-iOS.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Production"
buildConfiguration = "AppStore"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@ -42,6 +42,7 @@ static NSDateFormatter *rfc3339DateFormatter = nil;
if (managedObjectContext)
return managedObjectContext;
return [PearlLazy lazyObjectLoadedFrom:^id{
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
assert(coordinator);
@ -52,18 +53,26 @@ static NSDateFormatter *rfc3339DateFormatter = nil;
}];
return managedObjectContext;
}];
}
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
// Start loading the store.
[self storeManager];
return [PearlLazy lazyObjectLoadedFrom:^id{
// Wait until the storeManager is ready.
for(__block BOOL isReady = [self storeManager].isReady; !isReady;)
for(__block BOOL isReady = [self storeManager].isReady; !isReady;) {
[NSThread sleepForTimeInterval:0.1];
dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
isReady = [self storeManager].isReady;
});
}
assert([self storeManager].isReady);
return [self storeManager].persistentStoreCoordinator;
}];
}
- (UbiquityStoreManager *)storeManager {

View File

@ -148,6 +148,8 @@
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[[[NSBundle mainBundle] mutableLocalizedInfoDictionary] setObject:@"Master Password" forKey:@"CFBundleDisplayName"];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
#ifndef DEBUG
@try {
@ -212,9 +214,28 @@
NSString *apptentiveAPIKey = [self apptentiveAPIKey];
if ([apptentiveAPIKey length]) {
dbg(@"Initializing Apptentive");
ATConnect *connection = [ATConnect sharedConnection];
connection.shouldTakeScreenshot = NO;
connection.apiKey = apptentiveAPIKey;
[connection setApiKey:apptentiveAPIKey];
[connection setShouldTakeScreenshot:NO];
[connection addAdditionalInfoToFeedback:[PearlInfoPlist get].CFBundleVersion withKey:@"CFBundleVersion"];
ATAppRatingFlow *ratingsFlow = [ATAppRatingFlow sharedRatingFlowWithAppID:[PearlConfig get].iTunesID];
[[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationWillEnterForegroundNotification object:nil queue:nil
usingBlock:^(NSNotification *note) {
dispatch_async(dispatch_get_main_queue(), ^{
[ratingsFlow appDidEnterForeground:YES
viewController:self.navigationController];
});
}];
[[NSNotificationCenter defaultCenter] addObserverForName:MPNotificationKeySet object:nil queue:nil
usingBlock:^(NSNotification *note) {
dispatch_async(dispatch_get_main_queue(), ^{
[ratingsFlow userDidPerformSignificantEvent:YES
viewController:self.navigationController];
});
}];
[ratingsFlow appDidLaunch:YES viewController:self.navigationController];
}
}
@catch (NSException *exception) {
@ -288,14 +309,6 @@
@"https://youtrack.lyndir.com\n"
viewStyle:UIAlertViewStyleDefault tappedButtonBlock:nil
cancelTitle:nil otherTitles:[PearlStrings get].commonButtonOkay, nil];
#else
@try {
ATAppRatingFlow *sharedFlow = [ATAppRatingFlow sharedRatingFlowWithAppID:[PearlConfig get].iTunesID];
[sharedFlow appDidLaunch:YES viewController:self.navigationController];
}
@catch (NSException *exception) {
err(@"Apptentive: %@", exception);
}
#endif
[[UIApplication sharedApplication] setStatusBarHidden:NO
@ -378,9 +391,6 @@
[TestFlight passCheckpoint:MPTestFlightCheckpointActivated];
ATAppRatingFlow *sharedFlow = [ATAppRatingFlow sharedRatingFlowWithAppID:[PearlConfig get].iTunesID];
[sharedFlow appDidEnterForeground:YES viewController:self.navigationController];
[super applicationDidBecomeActive:application];
}

View File

@ -146,8 +146,6 @@
- (void)updateAnimated:(BOOL)animated {
[[MPAppDelegate get] saveContext];
dispatch_async(dispatch_get_main_queue(), ^{
if (animated)
[UIView animateWithDuration:0.3f animations:^{
@ -352,6 +350,7 @@
NSString *oldPassword = [self.activeElement.content description];
task();
NSString *newPassword = [self.activeElement.content description];
[[MPAppDelegate get] saveContext];
[self updateAnimated:YES];
// Show new and old password.

View File

@ -14,7 +14,6 @@
@interface MPSearchDelegate (Private)
- (void)configureCell:(UITableViewCell *)cell inTableView:(UITableView *)tableView atIndexPath:(NSIndexPath *)indexPath;
- (void)update;
@end
@ -38,10 +37,14 @@
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:NSStringFromClass([MPElementEntity class])];
fetchRequest.sortDescriptors = [NSArray arrayWithObject:[[NSSortDescriptor alloc] initWithKey:@"uses" ascending:NO]];
self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
self.fetchedResultsController = [PearlLazy lazyObjectLoadedFrom:^id{
NSFetchedResultsController *controller = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
managedObjectContext:[MPAppDelegate managedObjectContext]
sectionNameKeyPath:nil cacheName:nil];
self.fetchedResultsController.delegate = self;
controller.delegate = self;
return controller;
}];
self.tipView = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 320, 170)];
self.tipView.textAlignment = UITextAlignmentCenter;
@ -123,12 +126,8 @@
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString {
[self update];
if (!controller.active)
return NO;
}
- (void)update {
assert(self.query);
@ -138,7 +137,6 @@
NSError *error;
if (![self.fetchedResultsController performFetch:&error])
err(@"Couldn't fetch elements: %@", error);
[self.searchDisplayController.searchResultsTableView reloadData];
NSArray *subviews = self.searchDisplayController.searchBar.superview.subviews;
NSUInteger overlayIndex = [subviews indexOfObject:self.searchDisplayController.searchBar] + 1;
@ -149,6 +147,8 @@
[self.tipView removeFromSuperview];
[overlay addSubview:self.tipView];
}
return YES;
}
// See MP-14, also crashes easily on internal assertions etc..

View File

@ -152,9 +152,6 @@ typedef enum {
- (void)textFieldDidEndEditing:(UITextField *)textField {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
@try {
dispatch_async(dispatch_get_main_queue(), ^{
CABasicAnimation *rotate = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
rotate.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
rotate.fromValue = [NSNumber numberWithFloat:0];
@ -170,10 +167,11 @@ typedef enum {
}];
[self showMessage:@"Checking password..." state:MPLockscreenProgress];
});
if ([[MPAppDelegate get] tryMasterPassword:textField.text])
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
BOOL unlocked = [[MPAppDelegate get] tryMasterPassword:textField.text];
dispatch_async(dispatch_get_main_queue(), ^{
if (unlocked) {
[self showMessage:@"Success!" state:MPLockscreenSuccess];
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:NSStringFromClass([MPElementEntity class])];
@ -209,16 +207,14 @@ typedef enum {
cancelTitle:[PearlStrings get].commonButtonCancel
otherTitles:[PearlStrings get].commonButtonContinue, nil];
}
});
else
dispatch_async(dispatch_get_main_queue(), ^{
} else {
[self showMessage:@"Not valid." state:MPLockscreenError];
[UIView animateWithDuration:0.5f animations:^{
self.changeMPView.alpha = 1.0f;
}];
});
}
@finally {
dispatch_async(dispatch_get_main_queue(), ^{
[UIView animateWithDuration:0.3f animations:^{
self.spinner.alpha = 0.0f;
@ -226,7 +222,7 @@ typedef enum {
[self.spinner.layer removeAllAnimations];
}];
});
}
});
});
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 376 KiB