2
0

Type improvements and fixes.

[IMPROVED]  Cleaner handling of types in entities.
[FIXED]     Lots of little fixes from refactoring and AppCode
            inspections, throughout.
This commit is contained in:
Maarten Billemont 2012-06-05 00:55:02 +02:00
parent ba299d4674
commit 0491ba3f97
25 changed files with 207 additions and 150 deletions

View File

@ -3,6 +3,6 @@
<option name="myName" value="Project Default" />
<option name="myLocal" value="false" />
<inspection_tool class="LossyEncoding" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="SeveralTargetsMessage" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="UnusedLocalVariable" enabled="false" level="WARNING" enabled_by_default="false" />
</profile>
</component>

2
External/Pearl vendored

@ -1 +1 @@
Subproject commit f3e1830d55b29e840a58fde8a62d58ed4b5a6b86
Subproject commit 1ce39007b6018ac4991b4ec0ee5158ba019bcac1

View File

@ -8,6 +8,10 @@
/* Begin PBXBuildFile section */
DA04E33E14B1E70400ECA4F3 /* MobileCoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA04E33D14B1E70400ECA4F3 /* MobileCoreServices.framework */; };
DA076C75157D58E5008968D7 /* MPElementGeneratedEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = DA076C74157D58E5008968D7 /* MPElementGeneratedEntity.m */; };
DA076C78157D58E5008968D7 /* MPElementEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = DA076C77157D58E5008968D7 /* MPElementEntity.m */; };
DA076C7B157D58E5008968D7 /* MPElementStoredEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = DA076C7A157D58E5008968D7 /* MPElementStoredEntity.m */; };
DA076C7E157D58E6008968D7 /* MPUserEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = DA076C7D157D58E6008968D7 /* MPUserEntity.m */; };
DA0A1D0515690A9A0092735D /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = DA0A1D0315690A9A0092735D /* Default.png */; };
DA0A1D0615690A9A0092735D /* Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DA0A1D0415690A9A0092735D /* Default@2x.png */; };
DA0A1D1515690AF40092735D /* Icon-72@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DA0A1D1315690AF30092735D /* Icon-72@2x.png */; };
@ -709,10 +713,6 @@
DAC6327C1486809A0075AEA5 /* JRSwizzle.m in Sources */ = {isa = PBXBuildFile; fileRef = DAC6327A1486809A0075AEA5 /* JRSwizzle.m */; };
DAC632891486D9690075AEA5 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DAC632871486D95D0075AEA5 /* Security.framework */; };
DAC728CA157C247B00889EF2 /* MPPreferencesViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = DAC728C9157C247B00889EF2 /* MPPreferencesViewController.m */; };
DAC728E4157CAE5A00889EF2 /* MPElementEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = DAC728E3157CAE5A00889EF2 /* MPElementEntity.m */; };
DAC728E7157CAE5B00889EF2 /* MPUserEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = DAC728E6157CAE5B00889EF2 /* MPUserEntity.m */; };
DAC728EA157CAE5B00889EF2 /* MPElementGeneratedEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = DAC728E9157CAE5B00889EF2 /* MPElementGeneratedEntity.m */; };
DAC728ED157CAE5B00889EF2 /* MPElementStoredEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = DAC728EC157CAE5B00889EF2 /* MPElementStoredEntity.m */; };
DAC77CAE148291A600BCF976 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA5BFA4A147E415C00F98B1E /* Foundation.framework */; };
DACABB8515729E80008BA211 /* ApptentiveResources.bundle in Resources */ = {isa = PBXBuildFile; fileRef = DAAC35D6156BD51600C5FD93 /* ApptentiveResources.bundle */; };
DACABB861572A2A7008BA211 /* tip_alert_black.png in Resources */ = {isa = PBXBuildFile; fileRef = DAB8D6BA15036BF600CED3BC /* tip_alert_black.png */; };
@ -906,6 +906,14 @@
/* Begin PBXFileReference section */
DA04E33D14B1E70400ECA4F3 /* MobileCoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MobileCoreServices.framework; path = System/Library/Frameworks/MobileCoreServices.framework; sourceTree = SDKROOT; };
DA076C73157D58E5008968D7 /* MPElementGeneratedEntity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPElementGeneratedEntity.h; sourceTree = "<group>"; };
DA076C74157D58E5008968D7 /* MPElementGeneratedEntity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPElementGeneratedEntity.m; sourceTree = "<group>"; };
DA076C76157D58E5008968D7 /* MPElementEntity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPElementEntity.h; sourceTree = "<group>"; };
DA076C77157D58E5008968D7 /* MPElementEntity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPElementEntity.m; sourceTree = "<group>"; };
DA076C79157D58E5008968D7 /* MPElementStoredEntity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPElementStoredEntity.h; sourceTree = "<group>"; };
DA076C7A157D58E5008968D7 /* MPElementStoredEntity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPElementStoredEntity.m; sourceTree = "<group>"; };
DA076C7C157D58E6008968D7 /* MPUserEntity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPUserEntity.h; sourceTree = "<group>"; };
DA076C7D157D58E6008968D7 /* MPUserEntity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPUserEntity.m; sourceTree = "<group>"; };
DA0A1D0315690A9A0092735D /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Default.png; path = Resources/Default.png; sourceTree = SOURCE_ROOT; };
DA0A1D0415690A9A0092735D /* Default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Default@2x.png"; path = "Resources/Default@2x.png"; sourceTree = SOURCE_ROOT; };
DA0A1D0715690AD40092735D /* tip_arrow_banana.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = tip_arrow_banana.png; path = Resources/Tooltips/tip_arrow_banana.png; sourceTree = SOURCE_ROOT; };
@ -1698,14 +1706,6 @@
DAC632871486D95D0075AEA5 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; };
DAC728C8157C247B00889EF2 /* MPPreferencesViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPPreferencesViewController.h; sourceTree = "<group>"; };
DAC728C9157C247B00889EF2 /* MPPreferencesViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPPreferencesViewController.m; sourceTree = "<group>"; };
DAC728E2157CAE5A00889EF2 /* MPElementEntity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPElementEntity.h; sourceTree = "<group>"; };
DAC728E3157CAE5A00889EF2 /* MPElementEntity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPElementEntity.m; sourceTree = "<group>"; };
DAC728E5157CAE5B00889EF2 /* MPUserEntity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPUserEntity.h; sourceTree = "<group>"; };
DAC728E6157CAE5B00889EF2 /* MPUserEntity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPUserEntity.m; sourceTree = "<group>"; };
DAC728E8157CAE5B00889EF2 /* MPElementGeneratedEntity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPElementGeneratedEntity.h; sourceTree = "<group>"; };
DAC728E9157CAE5B00889EF2 /* MPElementGeneratedEntity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPElementGeneratedEntity.m; sourceTree = "<group>"; };
DAC728EB157CAE5B00889EF2 /* MPElementStoredEntity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPElementStoredEntity.h; sourceTree = "<group>"; };
DAC728EC157CAE5B00889EF2 /* MPElementStoredEntity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPElementStoredEntity.m; sourceTree = "<group>"; };
DAC77CAD148291A600BCF976 /* libPearl.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPearl.a; sourceTree = BUILT_PRODUCTS_DIR; };
DAC77CB1148291A600BCF976 /* Pearl-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Pearl-Prefix.pch"; sourceTree = "<group>"; };
DACABB8A1572A4A4008BA211 /* tip_basic_black_top_right.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = tip_basic_black_top_right.png; sourceTree = "<group>"; };
@ -1965,14 +1965,14 @@
isa = PBXGroup;
children = (
DAB8D43C15036BCF00CED3BC /* MasterPassword.xcdatamodeld */,
DAC728EB157CAE5B00889EF2 /* MPElementStoredEntity.h */,
DAC728EC157CAE5B00889EF2 /* MPElementStoredEntity.m */,
DAC728E8157CAE5B00889EF2 /* MPElementGeneratedEntity.h */,
DAC728E9157CAE5B00889EF2 /* MPElementGeneratedEntity.m */,
DAC728E5157CAE5B00889EF2 /* MPUserEntity.h */,
DAC728E6157CAE5B00889EF2 /* MPUserEntity.m */,
DAC728E2157CAE5A00889EF2 /* MPElementEntity.h */,
DAC728E3157CAE5A00889EF2 /* MPElementEntity.m */,
DA076C7C157D58E6008968D7 /* MPUserEntity.h */,
DA076C7D157D58E6008968D7 /* MPUserEntity.m */,
DA076C79157D58E5008968D7 /* MPElementStoredEntity.h */,
DA076C7A157D58E5008968D7 /* MPElementStoredEntity.m */,
DA076C76157D58E5008968D7 /* MPElementEntity.h */,
DA076C77157D58E5008968D7 /* MPElementEntity.m */,
DA076C73157D58E5008968D7 /* MPElementGeneratedEntity.h */,
DA076C74157D58E5008968D7 /* MPElementGeneratedEntity.m */,
DA0E07941577FE490008A67E /* MPEntities.h */,
DA0E07951577FE490008A67E /* MPEntities.m */,
DA600C2415054F3A008E9AB6 /* MPAppDelegate_Key.h */,
@ -4164,10 +4164,10 @@
DA4426091557C1990052177D /* MPAppDelegate_Store.m in Sources */,
DA0E07961577FE490008A67E /* MPEntities.m in Sources */,
DAC728CA157C247B00889EF2 /* MPPreferencesViewController.m in Sources */,
DAC728E4157CAE5A00889EF2 /* MPElementEntity.m in Sources */,
DAC728E7157CAE5B00889EF2 /* MPUserEntity.m in Sources */,
DAC728EA157CAE5B00889EF2 /* MPElementGeneratedEntity.m in Sources */,
DAC728ED157CAE5B00889EF2 /* MPElementStoredEntity.m in Sources */,
DA076C75157D58E5008968D7 /* MPElementGeneratedEntity.m in Sources */,
DA076C78157D58E5008968D7 /* MPElementEntity.m in Sources */,
DA076C7B157D58E5008968D7 /* MPElementStoredEntity.m in Sources */,
DA076C7E157D58E6008968D7 /* MPUserEntity.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@ -6,7 +6,6 @@
// Copyright (c) 2011 Lyndir. All rights reserved.
//
#import "MPConfig.h"
#import "MPAppDelegate_Key.h"
@implementation MPAppDelegate_Shared (Key)
@ -41,7 +40,7 @@ static NSDictionary *keyQuery(MPUserEntity *user) {
- (void)loadSavedKey {
if ([self.activeUser.saveKey boolValue]) {
if (self.activeUser.saveKey) {
// Key should be saved in keychain. Load it.
self.key = [PearlKeyChain dataOfItemForQuery:keyQuery(self.activeUser)];
inf(@"Looking for key in keychain: %@.", self.key? @"found": @"missing");
@ -97,7 +96,7 @@ static NSDictionary *keyQuery(MPUserEntity *user) {
- (void)storeSavedKey {
if ([self.activeUser.saveKey boolValue]) {
if (self.activeUser.saveKey) {
NSData *existingKey = [PearlKeyChain dataOfItemForQuery:keyQuery(self.activeUser)];
if (![existingKey isEqualToData:self.key]) {

View File

@ -7,8 +7,6 @@
//
#import "MPAppDelegate_Store.h"
#import "MPEntities.h"
#import "MPConfig.h"
@implementation MPAppDelegate_Shared (Store)
@ -329,8 +327,8 @@ static NSDateFormatter *rfc3339DateFormatter = nil;
}
for (NSArray *siteElements in importedSiteElements) {
NSDate *lastUsed = [rfc3339DateFormatter dateFromString:[siteElements objectAtIndex:0]];
NSInteger uses = [[siteElements objectAtIndex:1] integerValue];
MPElementType type = (unsigned)[[siteElements objectAtIndex:2] integerValue];
NSUInteger uses = (unsigned)[[siteElements objectAtIndex:1] integerValue];
MPElementType type = (MPElementType)[[siteElements objectAtIndex:2] integerValue];
NSString *name = [siteElements objectAtIndex:3];
NSString *exportContent = [siteElements objectAtIndex:4];
@ -339,8 +337,8 @@ static NSDateFormatter *rfc3339DateFormatter = nil;
inManagedObjectContext:self.managedObjectContext];
element.name = name;
element.user = user;
element.type = [NSNumber numberWithUnsignedInteger:type];
element.uses = [NSNumber numberWithUnsignedInteger:uses];
element.type = type;
element.uses = uses;
element.lastUsed = lastUsed;
if ([exportContent length])
[element importContent:exportContent];
@ -382,11 +380,11 @@ static NSDateFormatter *rfc3339DateFormatter = nil;
// Sites.
for (MPElementEntity *element in self.activeUser.elements) {
NSDate *lastUsed = element.lastUsed;
NSNumber *uses = element.uses;
MPElementType type = (unsigned)element.type;
NSString *name = element.name;
NSString *content = nil;
NSDate *lastUsed = element.lastUsed;
NSUInteger uses = element.uses;
MPElementType type = element.type;
NSString *name = element.name;
NSString *content = nil;
// Determine the content to export.
if (!(type & MPElementFeatureDevicePrivate)) {

View File

@ -6,6 +6,8 @@
// Copyright (c) 2012 Lyndir. All rights reserved.
//
#import "Pearl.h"
@interface MPConfig : PearlConfig
@property (nonatomic, retain) NSNumber *rememberLogin;

View File

@ -16,8 +16,8 @@
@property (nonatomic, retain) id content;
@property (nonatomic, retain) NSDate * lastUsed;
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) NSNumber * type;
@property (nonatomic, retain) NSNumber * uses;
@property (nonatomic, retain) NSNumber * type_;
@property (nonatomic, retain) NSNumber * uses_;
@property (nonatomic, retain) MPUserEntity *user;
@end

View File

@ -15,8 +15,8 @@
@dynamic content;
@dynamic lastUsed;
@dynamic name;
@dynamic type;
@dynamic uses;
@dynamic type_;
@dynamic uses_;
@dynamic user;
@end

View File

@ -13,6 +13,6 @@
@interface MPElementGeneratedEntity : MPElementEntity
@property (nonatomic, retain) NSNumber * counter;
@property (nonatomic, retain) NSNumber * counter_;
@end

View File

@ -11,6 +11,6 @@
@implementation MPElementGeneratedEntity
@dynamic counter;
@dynamic counter_;
@end

View File

@ -14,8 +14,24 @@
@interface MPElementEntity (MP)
- (NSNumber *)use;
@property (assign) MPElementType type;
@property (assign) NSUInteger uses;
- (NSUInteger)use;
- (NSString *)exportContent;
- (void)importContent:(NSString *)content;
@end
@interface MPElementGeneratedEntity (MP)
@property (assign) NSUInteger counter;
@end
@interface MPUserEntity (MP)
@property (assign) NSUInteger avatar;
@property (assign) BOOL saveKey;
@end

View File

@ -12,12 +12,31 @@
@implementation MPElementEntity (MP)
- (NSNumber *)use {
- (MPElementType)type {
return (MPElementType)[self.type_ unsignedIntegerValue];
}
- (void)setType:(MPElementType)type {
self.type_ = PearlUnsignedInteger(type);
}
- (NSUInteger)uses {
return [self.uses_ unsignedIntegerValue];
}
- (void)setUses:(NSUInteger)anUses {
self.uses_ = PearlUnsignedInteger(anUses);
}
- (NSUInteger)use {
self.lastUsed = [NSDate date];
self.uses = [NSNumber numberWithUnsignedInteger:[self.uses unsignedIntegerValue] + 1];
return self.uses;
return ++self.uses;
}
- (id)content {
@ -49,9 +68,19 @@
@implementation MPElementGeneratedEntity (MP)
- (NSUInteger)counter {
return [self.counter_ unsignedIntegerValue];
}
- (void)setCounter:(NSUInteger)aCounter {
self.counter_ = PearlUnsignedInteger(aCounter);
}
- (id)content {
if (!([self.type unsignedIntegerValue] & MPElementTypeClassGenerated)) {
if (!(self.type & MPElementTypeClassGenerated)) {
err(@"Corrupt element: %@, type: %d is not in MPElementTypeClassGenerated", self.name, self.type);
return nil;
}
@ -59,7 +88,7 @@
if (![self.name length])
return nil;
return MPCalculateContent([self.type unsignedIntegerValue], self.name, [MPAppDelegate get].key, [self.counter unsignedIntegerValue]);
return MPCalculateContent(self.type, self.name, [MPAppDelegate get].key, self.counter);
}
@end
@ -78,10 +107,10 @@
- (id)content {
assert([self.type unsignedIntegerValue] & MPElementTypeClassStored);
assert(self.type & MPElementTypeClassStored);
NSData *encryptedContent;
if ([self.type unsignedIntegerValue] & MPElementFeatureDevicePrivate)
if (self.type & MPElementFeatureDevicePrivate)
encryptedContent = [PearlKeyChain dataOfItemForQuery:[MPElementStoredEntity queryForDevicePrivateElementNamed:self.name]];
else
encryptedContent = self.contentObject;
@ -96,7 +125,7 @@
NSData *encryptedContent = [[content description] encryptWithSymmetricKey:[[MPAppDelegate get] keyWithLength:PearlCryptKeySize]
padding:YES];
if ([self.type unsignedIntegerValue] & MPElementFeatureDevicePrivate) {
if (self.type & MPElementFeatureDevicePrivate) {
[PearlKeyChain addOrUpdateItemForQuery:[MPElementStoredEntity queryForDevicePrivateElementNamed:self.name]
withAttributes:[NSDictionary dictionaryWithObjectsAndKeys:
encryptedContent, (__bridge id)kSecValueData,
@ -120,3 +149,27 @@
}
@end
@implementation MPUserEntity (MP)
- (NSUInteger)avatar {
return [self.avatar_ unsignedIntegerValue];
}
- (void)setAvatar:(NSUInteger)anAvatar {
self.avatar_ = PearlUnsignedInteger(anAvatar);
}
- (BOOL)saveKey {
return [self.saveKey_ boolValue];
}
- (void)setSaveKey:(BOOL)aSaveKey {
self.saveKey_ = [NSNumber numberWithBool:aSaveKey];
}
@end

View File

@ -62,7 +62,7 @@ NSString *NSStringFromMPElementType(MPElementType type) {
return @"Device Private Password";
default:
[NSException raise:NSInternalInconsistencyException format:@"Type not supported: %d", type];
Throw(@"Type not supported: %d", type);
}
}
@ -94,7 +94,7 @@ Class ClassFromMPElementType(MPElementType type) {
return [MPElementStoredEntity class];
default:
[NSException raise:NSInternalInconsistencyException format:@"Type not supported: %d", type];
Throw(@"Type not supported: %d", type);
}
}

View File

@ -13,11 +13,11 @@
@interface MPUserEntity : NSManagedObject
@property (nonatomic, retain) NSNumber * avatar_;
@property (nonatomic, retain) NSData * keyID;
@property (nonatomic, retain) NSDate * lastUsed;
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) NSNumber * saveKey;
@property (nonatomic, retain) NSNumber * avatar;
@property (nonatomic, retain) NSNumber * saveKey_;
@property (nonatomic, retain) NSSet *elements;
@end

View File

@ -12,11 +12,11 @@
@implementation MPUserEntity
@dynamic avatar_;
@dynamic keyID;
@dynamic lastUsed;
@dynamic name;
@dynamic saveKey;
@dynamic avatar;
@dynamic saveKey_;
@dynamic elements;
@end

View File

@ -4,22 +4,22 @@
<attribute name="content" optional="YES" transient="YES" attributeType="Transformable" syncable="YES"/>
<attribute name="lastUsed" attributeType="Date" syncable="YES"/>
<attribute name="name" attributeType="String" minValueString="1" indexed="YES" syncable="YES" isSyncIdentityProperty="YES"/>
<attribute name="type" attributeType="Integer 16" defaultValueString="16" syncable="YES"/>
<attribute name="uses" attributeType="Integer 16" defaultValueString="0" syncable="YES"/>
<attribute name="type_" attributeType="Integer 16" defaultValueString="16" syncable="YES"/>
<attribute name="uses_" attributeType="Integer 16" defaultValueString="0" syncable="YES"/>
<relationship name="user" minCount="1" maxCount="1" deletionRule="Nullify" destinationEntity="MPUserEntity" inverseName="elements" inverseEntity="MPUserEntity" syncable="YES"/>
</entity>
<entity name="MPElementGeneratedEntity" representedClassName="MPElementGeneratedEntity" parentEntity="MPElementEntity" syncable="YES">
<attribute name="counter" optional="YES" attributeType="Integer 32" defaultValueString="1" syncable="YES"/>
<attribute name="counter_" optional="YES" attributeType="Integer 32" defaultValueString="1" syncable="YES"/>
</entity>
<entity name="MPElementStoredEntity" representedClassName="MPElementStoredEntity" parentEntity="MPElementEntity" syncable="YES">
<attribute name="contentObject" optional="YES" attributeType="Transformable" storedInTruthFile="YES" syncable="YES"/>
</entity>
<entity name="MPUserEntity" representedClassName="MPUserEntity" syncable="YES">
<attribute name="avatar" optional="YES" attributeType="Integer 16" defaultValueString="0" syncable="YES"/>
<attribute name="avatar_" optional="YES" attributeType="Integer 16" defaultValueString="0" syncable="YES"/>
<attribute name="keyID" optional="YES" attributeType="Binary" syncable="YES"/>
<attribute name="lastUsed" optional="YES" attributeType="Date" syncable="YES"/>
<attribute name="name" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="saveKey" optional="YES" attributeType="Boolean" syncable="YES"/>
<attribute name="saveKey_" optional="YES" attributeType="Boolean" syncable="YES"/>
<relationship name="elements" optional="YES" toMany="YES" deletionRule="Cascade" destinationEntity="MPElementEntity" inverseName="user" inverseEntity="MPElementEntity" syncable="YES"/>
</entity>
<elements>

View File

@ -10,7 +10,6 @@
#import "MPAppDelegate_Key.h"
#import "MPAppDelegate_Store.h"
#import "MPMainViewController.h"
#import "IASKSettingsReader.h"
#import "LocalyticsSession.h"
#import "TestFlight.h"
@ -19,16 +18,16 @@
@interface MPAppDelegate ()
- (NSString *)testFlightInfo;
- (NSDictionary *)testFlightInfo;
- (NSString *)testFlightToken;
- (NSString *)crashlyticsInfo;
- (NSDictionary *)crashlyticsInfo;
- (NSString *)crashlyticsAPIKey;
- (NSString *)apptentiveInfo;
- (NSDictionary *)apptentiveInfo;
- (NSString *)apptentiveAPIKey;
- (NSString *)localyticsInfo;
- (NSDictionary *)localyticsInfo;
- (NSString *)localyticsKey;
@end
@ -86,11 +85,11 @@
@"making the result safe from falling in the wrong hands.\n\n"
@"If all your passwords are shown and somebody else finds the export, "
@"they could gain access to all your sites!"
viewStyle:UIAlertViewStyleDefault initAlert:nil tappedButtonBlock:^(UIAlertView *alert, NSInteger buttonIndex) {
if (buttonIndex == [alert firstOtherButtonIndex] + 0)
viewStyle:UIAlertViewStyleDefault initAlert:nil tappedButtonBlock:^(UIAlertView *alert_, NSInteger buttonIndex_) {
if (buttonIndex_ == [alert_ firstOtherButtonIndex] + 0)
// Safe Export
[self exportShowPasswords:NO];
if (buttonIndex == [alert firstOtherButtonIndex] + 1)
if (buttonIndex_ == [alert_ firstOtherButtonIndex] + 1)
// Safe Export
[self exportShowPasswords:YES];
} cancelTitle:[PearlStrings get].commonButtonCancel otherTitles:@"Safe Export", @"Show Passwords", nil];
@ -315,11 +314,11 @@
dispatch_group_enter(confirmationGroup);
dispatch_async(dispatch_get_main_queue(), ^{
[PearlAlert showAlertWithTitle:@"Import Sites?"
message:PearlLocalize(@"Import %d sites, overwriting %d existing sites?", importCount, deleteCount)
message:PearlString(@"Import %d sites, overwriting %d existing sites?", importCount, deleteCount)
viewStyle:UIAlertViewStyleDefault
initAlert:nil
tappedButtonBlock:^(UIAlertView *alert, NSInteger buttonIndex) {
if (buttonIndex != [alert cancelButtonIndex])
tappedButtonBlock:^(UIAlertView *alert_, NSInteger buttonIndex_) {
if (buttonIndex_ != [alert_ cancelButtonIndex])
confirmation = YES;
dispatch_group_leave(confirmationGroup);
@ -462,7 +461,7 @@
@"Apple can never see any of your passwords."
viewStyle:UIAlertViewStyleDefault
initAlert:nil
tappedButtonBlock:^(UIAlertView *alert, NSInteger buttonIndex) {
tappedButtonBlock:^(UIAlertView *alert_, NSInteger buttonIndex_) {
[self ubiquityStoreManager:manager didSwitchToiCloud:iCloudEnabled];
}
cancelTitle:[PearlStrings get].commonButtonThanks otherTitles:nil];
@ -553,8 +552,6 @@
#ifdef DEBUG
return NullToNil([[self localyticsInfo] valueForKeyPath:@"Key.development"]);
#elif defined(LITE)
return NullToNil([[self localyticsInfo] valueForKeyPath:@"Key.distribution.lite"]);
#else
return NullToNil([[self localyticsInfo] valueForKeyPath:@"Key.distribution"]);
#endif

View File

@ -22,7 +22,7 @@
[super viewDidLoad];
[PearlUIUtils autoSizeContent:self.scrollView];
[self.scrollView autoSizeContent];
}
- (void)viewWillDisappear:(BOOL)animated {

View File

@ -10,8 +10,6 @@
#import "MPAppDelegate.h"
#import "MPAppDelegate_Key.h"
#import "MPAppDelegate_Store.h"
#import "MPEntities.h"
#import "IASKAppSettingsViewController.h"
#import "ATConnect.h"
#import <MobileCoreServices/MobileCoreServices.h>
@ -95,7 +93,7 @@
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5.0f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[UIView animateWithDuration:0.2f animations:^{
self.actionsTipContainer.alpha = 0;
} completion:^(BOOL finished) {
} completion:^(BOOL finished_) {
if (![self.activeElement.name length])
[UIView animateWithDuration:animated? 0.3f: 0 animations:^{
self.searchTipContainer.alpha = 1;
@ -156,18 +154,18 @@
[self setHelpChapter:self.activeElement? @"2": @"1"];
self.siteName.text = self.activeElement.name;
self.passwordCounter.alpha = [self.activeElement.type unsignedIntegerValue] & MPElementTypeClassGenerated? 0.5f: 0;
self.passwordIncrementer.alpha = [self.activeElement.type unsignedIntegerValue] & MPElementTypeClassGenerated? 0.5f: 0;
self.passwordEdit.alpha = [self.activeElement.type unsignedIntegerValue] & MPElementTypeClassStored? 0.5f: 0;
self.passwordCounter.alpha = self.activeElement.type & MPElementTypeClassGenerated? 0.5f: 0;
self.passwordIncrementer.alpha = self.activeElement.type & MPElementTypeClassGenerated? 0.5f: 0;
self.passwordEdit.alpha = self.activeElement.type & MPElementTypeClassStored? 0.5f: 0;
[self.typeButton setTitle:NSStringFromMPElementType((unsigned)self.activeElement.type)
[self.typeButton setTitle:NSStringFromMPElementType(self.activeElement.type)
forState:UIControlStateNormal];
self.typeButton.alpha = NSStringFromMPElementType((unsigned)self.activeElement.type).length? 1: 0;
self.typeButton.alpha = NSStringFromMPElementType(self.activeElement.type).length? 1: 0;
self.contentField.enabled = NO;
if ([self.activeElement isKindOfClass:[MPElementGeneratedEntity class]])
self.passwordCounter.text = [NSString stringWithFormat:@"%u", ((MPElementGeneratedEntity *) self.activeElement).counter];
self.passwordCounter.text = PearlString(@"%u", ((MPElementGeneratedEntity *) self.activeElement).counter);
self.contentField.text = @"";
if (self.activeElement.name && ![self.activeElement isDeleted])
@ -221,8 +219,8 @@
- (void)webViewDidFinishLoad:(UIWebView *)webView {
NSString *error = [self.helpView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"setClass('%@');",
ClassNameFromMPElementType((unsigned)self.activeElement.type)]];
NSString *error = [self.helpView stringByEvaluatingJavaScriptFromString:
PearlString(@"setClass('%@');", ClassNameFromMPElementType(self.activeElement.type))];
if (error.length)
err(@"helpView.setClass: %@", error);
}
@ -279,8 +277,7 @@
if (!self.activeElement)
return;
[[UIPasteboard generalPasteboard] setValue:self.activeElement.content
forPasteboardType:(id)kUTTypeUTF8PlainText];
[UIPasteboard generalPasteboard].string = [self.activeElement.content description];
[self showContentTip:@"Copied!" withIcon:nil];
@ -299,7 +296,7 @@
@"You will then need to update your account's old password to this newly generated password.\n\n"
@"You can reset the counter by holding down on this button."
do:^{
PearlUnsignedIntegerOp([((MPElementGeneratedEntity *) self.activeElement) counter], +1);
++((MPElementGeneratedEntity *) self.activeElement).counter;
}];
[TestFlight passCheckpoint:MPTestFlightCheckpointIncrementPasswordCounter];
@ -313,7 +310,7 @@
if (![self.activeElement isKindOfClass:[MPElementGeneratedEntity class]])
// Not of a type that supports a password counter.
return;
if ([((MPElementGeneratedEntity *)self.activeElement).counter unsignedIntegerValue] == 1)
if (((MPElementGeneratedEntity *)self.activeElement).counter == 1)
// Counter has initial value, no point resetting.
return;
@ -322,7 +319,7 @@
@"If you continue, the site's password will change back to its original value. "
@"You will then need to update your account's password back to this original value."
do:^{
((MPElementGeneratedEntity *) self.activeElement).counter = PearlUnsignedInteger(1);
((MPElementGeneratedEntity *) self.activeElement).counter = 1;
}];
[TestFlight passCheckpoint:MPTestFlightCheckpointResetPasswordCounter];
@ -351,17 +348,18 @@
// Show new and old password.
if ([oldPassword length] && ![oldPassword isEqualToString:newPassword])
[self showAlertWithTitle:@"Password Changed!" message:PearlLocalize(@"The password for %@ has changed.\n\n"
@"IMPORTANT:\n"
@"Don't forget to update the site with your new password! "
@"Your old password was:\n"
@"%@", self.activeElement.name, oldPassword)];
[self showAlertWithTitle:@"Password Changed!"
message:PearlString(@"The password for %@ has changed.\n\n"
@"IMPORTANT:\n"
@"Don't forget to update the site with your new password! "
@"Your old password was:\n"
@"%@", self.activeElement.name, oldPassword)];
}
- (IBAction)editPassword {
if ([self.activeElement.type unsignedIntegerValue] & MPElementTypeClassStored) {
if (self.activeElement.type & MPElementTypeClassStored) {
self.contentField.enabled = YES;
[self.contentField becomeFirstResponder];
}
@ -439,7 +437,7 @@
- (MPElementType)selectedType {
return (unsigned)self.activeElement.type;
return self.activeElement.type;
}
- (void)didSelectType:(MPElementType)type {
@ -450,7 +448,7 @@
@"You will need to update your account's old password to the new one."
do:^{
// Update password type.
if (ClassFromMPElementType(type) != ClassFromMPElementType((unsigned)self.activeElement.type))
if (ClassFromMPElementType(type) != ClassFromMPElementType(self.activeElement.type))
// Type requires a different class of element. Recreate the element.
[[MPAppDelegate managedObjectContext] performBlockAndWait:^{
MPElementEntity *newElement = [NSEntityDescription insertNewObjectForEntityForName:ClassNameFromMPElementType(type)
@ -464,7 +462,7 @@
self.activeElement = newElement;
}];
self.activeElement.type = PearlUnsignedInteger(type);
self.activeElement.type = type;
[TestFlight passCheckpoint:[NSString stringWithFormat:MPTestFlightCheckpointSelectType, NSStringFromMPElementType(type)]];
@ -479,13 +477,13 @@
if (element) {
self.activeElement = element;
if ([[self.activeElement use] unsignedIntegerValue] == 1)
if ([self.activeElement use] == 1)
[self showAlertWithTitle:@"New Site" message:
PearlLocalize(@"You've just created a password for %@.\n\n"
@"IMPORTANT:\n"
@"Go to %@ and set or change the password for your account to the password above.\n"
@"Do this right away: if you forget, you may have trouble remembering which password to use to log into the site later on.",
self.activeElement.name, self.activeElement.name)];
PearlString(@"You've just created a password for %@.\n\n"
@"IMPORTANT:\n"
@"Go to %@ and set or change the password for your account to the password above.\n"
@"Do this right away: if you forget, you may have trouble remembering which password to use to log into the site later on.",
self.activeElement.name, self.activeElement.name)];
[[MPAppDelegate get] saveContext];
if ([[MPiOSConfig get].firstRun boolValue])

View File

@ -25,10 +25,10 @@
avatar.tag = avatarIndex++;
[avatar onSelect:^(BOOL selected) {
[MPAppDelegate get].activeUser.avatar = PearlInteger(avatar.tag);
[self.avatarScrollView enumerateSubviews:^(UIView *subview, BOOL *stop, BOOL *recurse) {
UIButton *avatar = (UIButton *)subview;
avatar.selected = ([[MPAppDelegate get].activeUser.avatar integerValue] == avatar.tag);
[MPAppDelegate get].activeUser.avatar = (unsigned)avatar.tag;
[self.avatarScrollView enumerateSubviews:^(UIView *subview_, BOOL *stop_, BOOL *recurse_) {
UIButton *avatar_ = (UIButton *)subview_;
avatar_.selected = ([MPAppDelegate get].activeUser.avatar == (unsigned)avatar_.tag);
} recurse:NO];
} options:0];
} recurse:NO];
@ -38,7 +38,7 @@
- (void)viewWillAppear:(BOOL)animated {
[PearlUIUtils autoSizeContent:self.avatarScrollView];
[self.avatarScrollView autoSizeContent];
[super viewWillAppear:animated];
}

View File

@ -9,7 +9,6 @@
#import "MPSearchDelegate.h"
#import "MPAppDelegate.h"
#import "MPAppDelegate_Store.h"
#import "MPElementGeneratedEntity.h"
@interface MPSearchDelegate (Private)
@ -219,10 +218,10 @@
__block BOOL hasExactQueryMatch = NO;
[sections enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
id<NSFetchedResultsSectionInfo> sectionInfo = obj;
[[sectionInfo objects] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
if ([[obj name] isEqualToString:self.query]) {
[[sectionInfo objects] enumerateObjectsUsingBlock:^(id obj_, NSUInteger idx_, BOOL *stop_) {
if ([[obj_ name] isEqualToString:self.query]) {
hasExactQueryMatch = YES;
*stop = YES;
*stop_ = YES;
}
}];
if (hasExactQueryMatch)
@ -233,14 +232,14 @@
++sectionCount;
}
return (signed)sectionCount;
return (NSInteger)sectionCount;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSArray *sections = [self.fetchedResultsController sections];
if (section < (signed)[sections count])
return (signed)[[sections objectAtIndex:(unsigned)section] numberOfObjects];
if (section < (NSInteger)[sections count])
return (NSInteger)[[sections objectAtIndex:(unsigned)section] numberOfObjects];
return 1;
}
@ -275,7 +274,7 @@
- (void)configureCell:(UITableViewCell *)cell inTableView:(UITableView *)tableView atIndexPath:(NSIndexPath *)indexPath {
if (indexPath.section < (signed)[[self.fetchedResultsController sections] count]) {
if (indexPath.section < (NSInteger)[[self.fetchedResultsController sections] count]) {
MPElementEntity *element = [self.fetchedResultsController objectAtIndexPath:indexPath];
cell.textLabel.text = element.name;
@ -290,14 +289,14 @@
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.section < (signed)[[self.fetchedResultsController sections] count])
if (indexPath.section < (NSInteger)[[self.fetchedResultsController sections] count])
[self.delegate didSelectElement:[self.fetchedResultsController objectAtIndexPath:indexPath]];
else {
// "New" section.
NSString *siteName = self.query;
[PearlAlert showAlertWithTitle:@"New Site"
message:PearlLocalize(@"Do you want to create a new site named:\n%@", siteName)
message:PearlString(@"Do you want to create a new site named:\n%@", siteName)
viewStyle:UIAlertViewStyleDefault
initAlert:nil
tappedButtonBlock:^(UIAlertView *alert, NSInteger buttonIndex) {
@ -309,7 +308,7 @@
[self.fetchedResultsController.managedObjectContext performBlock:^{
MPElementGeneratedEntity *element = [NSEntityDescription insertNewObjectForEntityForName:NSStringFromClass([MPElementGeneratedEntity class])
inManagedObjectContext:self.fetchedResultsController.managedObjectContext];
assert([element isKindOfClass:ClassFromMPElementType((unsigned)element.type)]);
assert([element isKindOfClass:ClassFromMPElementType(element.type)]);
assert([MPAppDelegate get].activeUser.keyID);
element.name = siteName;
@ -325,7 +324,7 @@
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
if (section < (signed)[[self.fetchedResultsController sections] count])
if (section < (NSInteger)[[self.fetchedResultsController sections] count])
return [[[self.fetchedResultsController sections] objectAtIndex:(unsigned)section] name];
return @"";
@ -343,7 +342,7 @@
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.section < (signed)[[self.fetchedResultsController sections] count]) {
if (indexPath.section < (NSInteger)[[self.fetchedResultsController sections] count]) {
if (editingStyle == UITableViewCellEditingStyleDelete)
[self.fetchedResultsController.managedObjectContext performBlock:^{
MPElementEntity *element = [self.fetchedResultsController objectAtIndexPath:indexPath];

View File

@ -101,10 +101,8 @@
return MPElementTypeGeneratedPIN;
default:
[NSException raise:NSInternalInconsistencyException
format:@"Unsupported row: %d, when selecting generated element type.", indexPath.row];
Throw(@"Unsupported row: %d, when selecting generated element type.", indexPath.row);
}
break;
}
case 1: {
@ -116,18 +114,13 @@
return MPElementTypeStoredDevicePrivate;
default:
[NSException raise:NSInternalInconsistencyException
format:@"Unsupported row: %d, when selecting stored element type.", indexPath.row];
Throw(@"Unsupported row: %d, when selecting stored element type.", indexPath.row);
}
break;
}
default:
[NSException raise:NSInternalInconsistencyException
format:@"Unsupported section: %d, when selecting element type.", indexPath.section];
Throw(@"Unsupported section: %d, when selecting element type.", indexPath.section);
}
@throw nil;
}
- (void)viewDidUnload {

View File

@ -12,7 +12,6 @@
#import "MPAppDelegate.h"
#import "MPAppDelegate_Key.h"
#import "MPAppDelegate_Store.h"
#import "MPEntities.h"
@interface MPUnlockViewController ()
@ -107,11 +106,11 @@
// Create avatars.
for (MPUserEntity *user in users)
[self setupAvatar:[PearlUIUtils copyOf:self.userButtonTemplate] forUser:user];
[self setupAvatar:[PearlUIUtils copyOf:self.userButtonTemplate] forUser:nil];
[self setupAvatar:[self.userButtonTemplate clone] forUser:user];
[self setupAvatar:[self.userButtonTemplate clone] forUser:nil];
// Scroll view's content changed, update its content size.
[PearlUIUtils autoSizeContent:self.usersView ignoreHidden:YES ignoreInvisible:YES limitPadding:NO ignoreSubviews:nil];
[self.usersView autoSizeContentIgnoreHidden:YES ignoreInvisible:YES limitPadding:NO ignoreSubviews:nil];
[self updateLayoutAnimated:YES allowScroll:YES completion:nil];
@ -338,7 +337,7 @@
CABasicAnimation *rotate = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
rotate.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
rotate.fromValue = [NSNumber numberWithFloat:0];
rotate.toValue = [NSNumber numberWithFloat:2 * M_PI];
rotate.toValue = [NSNumber numberWithDouble:2 * M_PI];
rotate.repeatCount = MAXFLOAT;
rotate.duration = 3.0;

View File

@ -6,8 +6,6 @@
// Copyright (c) 2011 Lyndir. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "MPAppDelegate.h"
int main(int argc, char *argv[])

View File

@ -4,10 +4,15 @@
<dict>
<key>MPElementGeneratedEntity</key>
<dict>
<key>Secure Password</key>
<array>
<string>aonxxxxxxxxxxxxxxxxx</string>
<string>axxxxxxxxxxxxxxxxxon</string>
</array>
<key>Long Password</key>
<array>
<string>CvcvnoCvcvCvcv</string>
<string>CvcvCvcvnoCvcv</string>
<string>CvcvnoCvcvCvcv</string>
<string>CvcvCvcvCvcvno</string>
</array>
<key>Medium Password</key>
@ -48,7 +53,7 @@
<string>0123456789</string>
<key>o</key>
<string>!@#$%^&amp;*()</string>
<key>X</key>
<key>x</key>
<string>AEIOUaeiouBCDFGHJKLMNPQRSTVWXYZbcdfghjklmnpqrstvwxyz0123456789!@#$%^&amp;*()</string>
</dict>
</dict>