2
0

Fixed a few crashes.

[UPDATED]   A nil type is never OK.  Crash early if it is so.
[UPDATED]   Set crashlytics identifiers using its userIdentifier and userName property for good metadata.
[FIXED]     Make sure the MOC has a PSC with stores when returning it.
[FIXED]     Don't reset the store for just any open error! Only if it's actually incompatible.
[IMPROVED]  Remove timestamps from Crashlytics and TestFlight logs, they already provide them.
[FIXED]     Avoid crashes in some odd cases where there's no type set.
This commit is contained in:
Maarten Billemont 2012-08-24 10:12:15 +02:00
parent 7921734740
commit b9ccee398e
9 changed files with 351 additions and 322 deletions

@ -1 +1 @@
Subproject commit a7b028ff80cd4768be686a9ef2067dfd31989ce0
Subproject commit 8c7894a983f1c1e0795a6e3d5ee7a223a5e01a54

View File

@ -153,7 +153,7 @@
- (Class)classOfType:(MPElementType)type {
if (!type)
return nil;
Throw(@"No type given.");
switch (type) {
case MPElementTypeGeneratedMaximum:

View File

@ -148,7 +148,8 @@ static NSDictionary *keyQuery(MPUserEntity *user) {
@try {
if ([[MPiOSConfig get].sendInfo boolValue]) {
[TestFlight addCustomEnvironmentInformation:user.userID forKey:@"username"];
[[Crashlytics sharedInstance] setObjectValue:user.userID forKey:@"username"];
[Crashlytics setObjectValue:user.userID forKey:@"username"];
[Crashlytics setUserName:user.userID];
}
}
@catch (id exception) {

View File

@ -29,8 +29,7 @@
if (managedObjectModel)
return managedObjectModel;
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"MasterPassword" withExtension:@"momd"];
return managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
return managedObjectModel = [NSManagedObjectModel mergedModelFromBundles:nil];
}
- (NSManagedObjectContext *)managedObjectContextIfReady {
@ -39,15 +38,21 @@
return nil;
static NSManagedObjectContext *managedObjectContext = nil;
if (managedObjectContext)
return managedObjectContext;
if (!managedObjectContext) {
managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
[managedObjectContext performBlockAndWait:^{
managedObjectContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy;
managedObjectContext.persistentStoreCoordinator = [self storeManager].persistentStoreCoordinator;
managedObjectContext.undoManager = [NSUndoManager new];
}];
}
if (![managedObjectContext.persistentStoreCoordinator.persistentStores count])
[managedObjectContext performBlockAndWait:^{
managedObjectContext.persistentStoreCoordinator = [self storeManager].persistentStoreCoordinator;
}];
if (![self storeManager].isReady)
return nil;
return managedObjectContext;
}
@ -62,7 +67,9 @@
localStoreURL:[[self applicationFilesDirectory] URLByAppendingPathComponent:@"MasterPassword.sqlite"]
containerIdentifier:@"HL3Q45LX9N.com.lyndir.lhunath.MasterPassword.shared"
#if TARGET_OS_IPHONE
additionalStoreOptions:@{NSPersistentStoreFileProtectionKey: NSFileProtectionComplete}
additionalStoreOptions:@{
NSPersistentStoreFileProtectionKey: NSFileProtectionComplete
}
#else
additionalStoreOptions:nil
#endif
@ -132,8 +139,9 @@
#ifdef TESTFLIGHT_SDK_VERSION
[TestFlight passCheckpoint:iCloudEnabled? MPCheckpointCloudEnabled: MPCheckpointCloudDisabled];
#endif
[[LocalyticsSession sharedLocalyticsSession] tagEvent:MPCheckpointCloud
attributes:@{@"enabled": iCloudEnabled? @"YES": @"NO"}];
[[LocalyticsSession sharedLocalyticsSession] tagEvent:MPCheckpointCloud attributes:@{
@"enabled": iCloudEnabled? @"YES": @"NO"
}];
[MPConfig get].iCloud = @(iCloudEnabled);
}
@ -154,7 +162,10 @@
case UbiquityStoreManagerErrorCauseClearStore:
break;
case UbiquityStoreManagerErrorCauseOpenLocalStore: {
wrn(@"Local store could not be opened, resetting it.");
wrn(@"Local store could not be opened: %@", error);
if (error.code == NSMigrationMissingSourceModelError) {
wrn(@"Resetting the local store.");
#ifdef TESTFLIGHT_SDK_VERSION
[TestFlight passCheckpoint:MPCheckpointLocalStoreIncompatible];
@ -164,9 +175,15 @@
[manager hardResetLocalStorage];
Throw(@"Local store was reset, application must be restarted to use it.");
} else
// Try again.
[self storeManager].persistentStoreCoordinator;
}
case UbiquityStoreManagerErrorCauseOpenCloudStore: {
wrn(@"iCloud store could not be opened, resetting it.");
wrn(@"iCloud store could not be opened: %@", error);
if (error.code == NSMigrationMissingSourceModelError) {
wrn(@"Resetting the iCloud store.");
#ifdef TESTFLIGHT_SDK_VERSION
[TestFlight passCheckpoint:MPCheckpointCloudStoreIncompatible];
@ -175,6 +192,9 @@
manager.hardResetEnabled = YES;
[manager hardResetCloudStorage];
break;
} else
// Try again.
[self storeManager].persistentStoreCoordinator;
}
}
}
@ -366,7 +386,8 @@
// Create new site.
__block MPImportResult result = MPImportResultSuccess;
[self.managedObjectContextIfReady performBlockAndWait:^{
MPElementEntity *element = [NSEntityDescription insertNewObjectForEntityForName:[MPAlgorithmForVersion(version) classNameOfType:type]
MPElementEntity *element = [NSEntityDescription insertNewObjectForEntityForName:[MPAlgorithmForVersion(
version) classNameOfType:type]
inManagedObjectContext:self.managedObjectContextIfReady];
element.name = name;
element.user = user;

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model name="" userDefinedModelVersionIdentifier="" type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="1487" systemVersion="12A269" minimumToolsVersion="Automatic" macOSVersion="Automatic" iOSVersion="Automatic">
<model name="" userDefinedModelVersionIdentifier="" type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="1807" systemVersion="12A269" minimumToolsVersion="Automatic" macOSVersion="Automatic" iOSVersion="Automatic">
<entity name="MPElementEntity" representedClassName="MPElementEntity" isAbstract="YES" syncable="YES">
<attribute name="content" optional="YES" transient="YES" attributeType="Transformable" syncable="YES"/>
<attribute name="lastUsed" attributeType="Date" indexed="YES" syncable="YES"/>
@ -32,9 +32,9 @@
<relationship name="elements" optional="YES" toMany="YES" deletionRule="Cascade" destinationEntity="MPElementEntity" inverseName="user" inverseEntity="MPElementEntity" syncable="YES"/>
</entity>
<elements>
<element name="MPElementEntity" positionX="160" positionY="192" width="128" height="180"/>
<element name="MPElementGeneratedEntity" positionX="160" positionY="192" width="128" height="60"/>
<element name="MPElementStoredEntity" positionX="160" positionY="192" width="128" height="60"/>
<element name="MPUserEntity" positionX="160" positionY="192" width="128" height="150"/>
<element name="MPElementEntity" positionX="0" positionY="0" width="0" height="0"/>
<element name="MPElementGeneratedEntity" positionX="0" positionY="0" width="0" height="0"/>
<element name="MPElementStoredEntity" positionX="0" positionY="0" width="0" height="0"/>
<element name="MPUserEntity" positionX="0" positionY="0" width="0" height="0"/>
</elements>
</model>

View File

@ -54,9 +54,10 @@
NSString *testFlightToken = [self testFlightToken];
if ([testFlightToken length]) {
inf(@"Initializing TestFlight");
[TestFlight addCustomEnvironmentInformation:@"Anonymous" forKey:@"username"];
[TestFlight setDeviceIdentifier:[(id)[UIDevice currentDevice] uniqueIdentifier]];
// [TestFlight setDeviceIdentifier:[PearlKeyChain deviceIdentifier]];
//[TestFlight setDeviceIdentifier[PearlKeyChain deviceIdentifier]];
[TestFlight addCustomEnvironmentInformation:@"Anonymous" forKey:@"username"];
[TestFlight addCustomEnvironmentInformation:[PearlKeyChain deviceIdentifier] forKey:@"deviceIdentifier"];
[TestFlight setOptions:[NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:NO], @"logToConsole",
[NSNumber numberWithBool:NO], @"logToSTDERR",
@ -68,7 +69,7 @@
level = PearlLogLevelInfo;
if (message.level >= level)
TFLog(@"%@", message);
TFLog(@"%@", [message messageDescription]);
return YES;
}];
@ -87,16 +88,18 @@
#if defined (DEBUG) || defined (ADHOC)
[Crashlytics sharedInstance].debugMode = YES;
#endif
[[Crashlytics sharedInstance] setObjectValue:@"Anonymous" forKey:@"username"];
[[Crashlytics sharedInstance] setObjectValue:[PearlKeyChain deviceIdentifier] forKey:@"deviceIdentifier"];
[Crashlytics startWithAPIKey:crashlyticsAPIKey afterDelay:0];
[Crashlytics setUserIdentifier:[PearlKeyChain deviceIdentifier]];
[Crashlytics setObjectValue:[PearlKeyChain deviceIdentifier] forKey:@"deviceIdentifier"];
[Crashlytics setUserName:@"Anonymous"];
[Crashlytics setObjectValue:@"Anonymous" forKey:@"username"];
[Crashlytics startWithAPIKey:crashlyticsAPIKey];
[[PearlLogger get] registerListener:^BOOL(PearlLogMessage *message) {
PearlLogLevel level = PearlLogLevelWarn;
if ([[MPiOSConfig get].sendInfo boolValue])
level = PearlLogLevelInfo;
if (message.level >= level)
CLSLog(@"%@", message);
CLSLog(@"%@", [message messageDescription]);
return YES;
}];

View File

@ -357,6 +357,11 @@
[self.fetchedResultsController.managedObjectContext performBlock:^{
MPElementType type = [MPAppDelegate get].activeUser.defaultType;
if (!type) {
// Really shouldn't happen, but a few people crashed on this anyway. Uhh. Data store corruption? Old bugs?
type = [MPAppDelegate get].activeUser.defaultType = MPElementTypeGeneratedLong;
}
MPElementEntity *element = [NSEntityDescription insertNewObjectForEntityForName:[MPAlgorithmDefault classNameOfType:type]
inManagedObjectContext:self.fetchedResultsController.managedObjectContext];
assert([MPAppDelegate get].activeUser);

File diff suppressed because it is too large Load Diff

View File

@ -6,7 +6,7 @@
<array>
<dict>
<key>FooterText</key>
<string>If you&apos;re experiencing problems, enabling this will send us details that can help diagnose and resolve them. Great care has been taken to guarantee no private information is ever sent.</string>
<string>If you&apos;re experiencing problems, enabling this will send us details that can help diagnose and resolve them. You will remain completely anonymous amongst the other thousands of users. No sensitive information is ever sent.</string>
<key>Title</key>
<string></string>
<key>Type</key>