Add support for Answers and improved Fabric integration.
This commit is contained in:
@@ -333,12 +333,12 @@
|
||||
question.keyword = keyword;
|
||||
|
||||
if ([context saveToStore]) {
|
||||
if ([question.objectID isTemporaryID]) {
|
||||
NSError *error = nil;
|
||||
[context obtainPermanentIDsForObjects:@[ question ] error:&error];
|
||||
if (error)
|
||||
err( @"Failed to obtain permanent object ID: %@", [error fullDescription] );
|
||||
}
|
||||
// if ([question.objectID isTemporaryID]) {
|
||||
// NSError *error = nil;
|
||||
// [context obtainPermanentIDsForObjects:@[ question ] error:&error];
|
||||
// if (error)
|
||||
// MPError( error, @"Failed to obtain permanent object ID: %@" );
|
||||
// }
|
||||
|
||||
_questionOID = question.objectID;
|
||||
[self updateAnswerForQuestion:question ofSite:site];
|
||||
|
@@ -395,7 +395,7 @@ typedef NS_OPTIONS( NSUInteger, MPPasswordsTips ) {
|
||||
self.fetchedResultsController.fetchRequest.predicate =
|
||||
[NSPredicate predicateWithFormat:@"name LIKE[cd] %@ AND user == %@", queryPattern, [MPiOSAppDelegate get].activeUserOID];
|
||||
if (![self.fetchedResultsController performFetch:&error])
|
||||
err( @"Couldn't fetch sites: %@", [error fullDescription] );
|
||||
MPError( error, @"Couldn't fetch sites." );
|
||||
|
||||
PearlMainQueue( ^{
|
||||
[self.passwordCollectionView updateDataSource:_passwordCollectionSections
|
||||
|
@@ -39,6 +39,8 @@
|
||||
@interface MPStoreProductCell : UITableViewCell
|
||||
|
||||
@property(nonatomic) IBOutlet UILabel *priceLabel;
|
||||
@property(nonatomic) IBOutlet UILabel *titleLabel;
|
||||
@property(nonatomic) IBOutlet UILabel *descriptionLabel;
|
||||
@property(nonatomic) IBOutlet UIActivityIndicatorView *activityIndicator;
|
||||
@property(nonatomic) IBOutlet UIView *purchasedIndicator;
|
||||
|
||||
|
@@ -28,7 +28,7 @@ PearlEnum( MPDevelopmentFuelConsumption,
|
||||
@interface MPStoreViewController()<MPInAppDelegate>
|
||||
|
||||
@property(nonatomic, strong) NSNumberFormatter *currencyFormatter;
|
||||
@property(nonatomic, strong) NSArray *products;
|
||||
@property(nonatomic, strong) NSDictionary<NSString *, SKProduct *> *products;
|
||||
|
||||
@end
|
||||
|
||||
@@ -43,7 +43,7 @@ PearlEnum( MPDevelopmentFuelConsumption,
|
||||
];
|
||||
NSInteger storeVersion = [[NSUserDefaults standardUserDefaults] integerForKey:@"storeVersion"];
|
||||
for (; storeVersion < [storeVersions count]; ++storeVersion)
|
||||
[features appendFormat:@"%@\n", storeVersions[storeVersion]];
|
||||
[features appendFormat:@"%@\n", storeVersions[(NSUInteger)storeVersion]];
|
||||
if (![features length])
|
||||
return nil;
|
||||
|
||||
@@ -170,7 +170,7 @@ PearlEnum( MPDevelopmentFuelConsumption,
|
||||
|
||||
#pragma mark - MPInAppDelegate
|
||||
|
||||
- (void)updateWithProducts:(NSArray *)products {
|
||||
- (void)updateWithProducts:(NSDictionary<NSString *, SKProduct *> *)products {
|
||||
|
||||
self.products = products;
|
||||
|
||||
@@ -218,7 +218,7 @@ PearlEnum( MPDevelopmentFuelConsumption,
|
||||
|
||||
- (SKProduct *)productForCell:(MPStoreProductCell *)cell {
|
||||
|
||||
for (SKProduct *product in self.products)
|
||||
for (SKProduct *product in [self.products allValues])
|
||||
if ([self cellForProductIdentifier:product.productIdentifier] == cell)
|
||||
return product;
|
||||
|
||||
@@ -248,7 +248,7 @@ PearlEnum( MPDevelopmentFuelConsumption,
|
||||
[hideCells addObjectsFromArray:[self.allCellsBySection[0] array]];
|
||||
[hideCells addObject:self.loadingCell];
|
||||
|
||||
for (SKProduct *product in self.products) {
|
||||
for (SKProduct *product in [self.products allValues]) {
|
||||
[self showCellForProductWithIdentifier:MPProductGenerateLogins ifProduct:product showingCells:showCells];
|
||||
[self showCellForProductWithIdentifier:MPProductGenerateAnswers ifProduct:product showingCells:showCells];
|
||||
[self showCellForProductWithIdentifier:MPProductOSIntegration ifProduct:product showingCells:showCells];
|
||||
@@ -313,6 +313,8 @@ PearlEnum( MPDevelopmentFuelConsumption,
|
||||
BOOL purchased = [[MPiOSAppDelegate get] isFeatureUnlocked:productIdentifier];
|
||||
NSInteger quantity = [self quantityForProductIdentifier:productIdentifier];
|
||||
cell.priceLabel.text = purchased? @"": [self.currencyFormatter stringFromNumber:@([product.price floatValue] * quantity)];
|
||||
cell.titleLabel.text = product.localizedTitle;
|
||||
cell.descriptionLabel.text = product.localizedDescription;
|
||||
cell.purchasedIndicator.visible = purchased;
|
||||
}
|
||||
|
||||
|
@@ -16,6 +16,7 @@
|
||||
// LICENSE file. Alternatively, see <http://www.gnu.org/licenses/>.
|
||||
//==============================================================================
|
||||
|
||||
#import <Crashlytics/Answers.h>
|
||||
#import "MPUsersViewController.h"
|
||||
#import "MPEntities.h"
|
||||
#import "MPAvatarCell.h"
|
||||
@@ -224,6 +225,17 @@ typedef NS_ENUM( NSUInteger, MPActiveUserState ) {
|
||||
user.defaultType = user.algorithm.defaultType;
|
||||
user.avatar = newUserAvatar;
|
||||
user.name = newUserName;
|
||||
|
||||
if ([[MPConfig get].sendInfo boolValue]) {
|
||||
#ifdef CRASHLYTICS
|
||||
[Answers logSignUpWithMethod:@"Manual"
|
||||
success:@YES
|
||||
customAttributes:@{
|
||||
@"algorithm": @(user.algorithm.version),
|
||||
@"avatar" : @(user.avatar),
|
||||
}];
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
BOOL signedIn = [[MPiOSAppDelegate get] signInAsUser:user saveInContext:context
|
||||
@@ -719,7 +731,7 @@ referenceSizeForFooterInSection:(NSInteger)section {
|
||||
];
|
||||
NSArray *users = [mainContext executeFetchRequest:fetchRequest error:&error];
|
||||
if (!users) {
|
||||
err( @"Failed to load users: %@", [error fullDescription] );
|
||||
MPError( error, @"Failed to load users." );
|
||||
self.userIDs = nil;
|
||||
}
|
||||
|
||||
|
@@ -25,7 +25,6 @@
|
||||
|
||||
@property(nonatomic, strong) UIDocumentInteractionController *interactionController;
|
||||
|
||||
@property(nonatomic) UIBackgroundTaskIdentifier task;
|
||||
@end
|
||||
|
||||
@implementation MPiOSAppDelegate
|
||||
@@ -59,10 +58,9 @@
|
||||
[[Crashlytics sharedInstance] setUserIdentifier:[PearlKeyChain deviceIdentifier]];
|
||||
[[Crashlytics sharedInstance] setObjectValue:[PearlKeyChain deviceIdentifier] forKey:@"deviceIdentifier"];
|
||||
[[Crashlytics sharedInstance] setUserName:@"Anonymous"];
|
||||
[[Crashlytics sharedInstance] setObjectValue:@"Anonymous" forKey:@"username"];
|
||||
[Crashlytics startWithAPIKey:crashlyticsAPIKey];
|
||||
[[PearlLogger get] registerListener:^BOOL(PearlLogMessage *message) {
|
||||
PearlLogLevel level = PearlLogLevelInfo;
|
||||
PearlLogLevel level = PearlLogLevelWarn;
|
||||
if ([[MPConfig get].sendInfo boolValue])
|
||||
level = PearlLogLevelDebug;
|
||||
|
||||
@@ -83,9 +81,6 @@
|
||||
PearlAddNotificationObserver( MPCheckConfigNotification, nil, [NSOperationQueue mainQueue], ^(id self, NSNotification *note) {
|
||||
[self updateConfigKey:note.object];
|
||||
} );
|
||||
// PearlAddNotificationObserver( kIASKAppSettingChanged, nil, nil, ^(id self, NSNotification *note) {
|
||||
// [[NSNotificationCenter defaultCenter] postNotificationName:MPCheckConfigNotification object:note.object];
|
||||
// } );
|
||||
PearlAddNotificationObserver( NSUserDefaultsDidChangeNotification, nil, nil, ^(id self, NSNotification *note) {
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:MPCheckConfigNotification object:nil];
|
||||
} );
|
||||
@@ -155,7 +150,8 @@
|
||||
[[[NSURLSession sharedSession] dataTaskWithURL:url completionHandler:
|
||||
^(NSData *importedSitesData, NSURLResponse *response, NSError *error) {
|
||||
if (error)
|
||||
err( @"While reading imported sites from %@: %@", url, [error fullDescription] );
|
||||
MPError( error, @"While reading imported sites from %@.", url );
|
||||
|
||||
if (!importedSitesData) {
|
||||
[PearlAlert showError:strf( @"Master Password couldn't read the import sites.\n\n%@",
|
||||
[error localizedDescription]?: error )];
|
||||
@@ -483,7 +479,7 @@
|
||||
NSError *error = nil;
|
||||
if (![[exportedSites dataUsingEncoding:NSUTF8StringEncoding]
|
||||
writeToURL:exportURL options:NSDataWritingFileProtectionComplete error:&error])
|
||||
err( @"Failed to write export data to URL %@: %@", exportURL, [error fullDescription] );
|
||||
MPError( error, @"Failed to write export data to URL %@.", exportURL );
|
||||
else {
|
||||
self.interactionController = [UIDocumentInteractionController interactionControllerWithURL:exportURL];
|
||||
self.interactionController.UTI = @"com.lyndir.masterpassword.sites";
|
||||
@@ -574,7 +570,7 @@
|
||||
static NSDictionary *crashlyticsInfo = nil;
|
||||
if (crashlyticsInfo == nil)
|
||||
crashlyticsInfo = [[NSDictionary alloc] initWithContentsOfURL:
|
||||
[[NSBundle mainBundle] URLForResource:@"Crashlytics" withExtension:@"plist"]];
|
||||
[[NSBundle mainBundle] URLForResource:@"Fabric" withExtension:@"plist"]];
|
||||
|
||||
return crashlyticsInfo;
|
||||
}
|
||||
|
@@ -60,7 +60,7 @@
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>© 2011-2016 Lyndir</string>
|
||||
<string>© 2011-2017</string>
|
||||
<key>UIAppFonts</key>
|
||||
<array>
|
||||
<string>Exo2.0-Bold.otf</string>
|
||||
|
@@ -6,7 +6,7 @@
|
||||
<array>
|
||||
<dict>
|
||||
<key>FooterText</key>
|
||||
<string>Enable this setting to send us carefully anonymized information to help us diagnose and resolve issues you might experience in the future.</string>
|
||||
<string>Enable this setting to send carefully anonymized information to help us diagnose and resolve any issues you encounter in a future update.</string>
|
||||
<key>Title</key>
|
||||
<string></string>
|
||||
<key>Type</key>
|
||||
@@ -50,7 +50,7 @@
|
||||
<key>Key</key>
|
||||
<string>sendInfo</string>
|
||||
<key>DefaultValue</key>
|
||||
<false/>
|
||||
<true/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>FooterText</key>
|
||||
|
@@ -2620,8 +2620,10 @@ See </string>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<connections>
|
||||
<outlet property="activityIndicator" destination="cef-sc-aph" id="VmL-AX-R3f"/>
|
||||
<outlet property="descriptionLabel" destination="Ra0-yS-99P" id="99B-ao-lE6"/>
|
||||
<outlet property="priceLabel" destination="68f-wn-UlS" id="e99-ys-HtZ"/>
|
||||
<outlet property="purchasedIndicator" destination="FWu-V6-mLT" id="Zqt-GG-e5v"/>
|
||||
<outlet property="titleLabel" destination="Pax-1J-IZi" id="kVH-n6-mDs"/>
|
||||
</connections>
|
||||
</tableViewCell>
|
||||
<tableViewCell contentMode="scaleToFill" selectionStyle="default" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" shouldIndentWhileEditing="NO" reuseIdentifier="MPStoreProductCellGenerateAnswers" id="l1g-Ul-Vg8" userLabel="Generate Answers" customClass="MPStoreProductCell">
|
||||
@@ -2685,8 +2687,10 @@ See </string>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<connections>
|
||||
<outlet property="activityIndicator" destination="X2g-Go-2Hz" id="PvQ-bP-exW"/>
|
||||
<outlet property="descriptionLabel" destination="yRH-27-edZ" id="pfv-na-UM3"/>
|
||||
<outlet property="priceLabel" destination="9ct-IM-QKR" id="UTQ-L7-vbu"/>
|
||||
<outlet property="purchasedIndicator" destination="N9y-ue-L8d" id="Ppv-ay-M1J"/>
|
||||
<outlet property="titleLabel" destination="Kkl-gT-YAO" id="cHy-iU-oHr"/>
|
||||
</connections>
|
||||
</tableViewCell>
|
||||
<tableViewCell contentMode="scaleToFill" selectionStyle="default" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" shouldIndentWhileEditing="NO" reuseIdentifier="MPStoreProductCellOSIntegration" id="9Na-CL-jBq" userLabel="iOS Integration" customClass="MPStoreProductCell">
|
||||
@@ -2750,8 +2754,10 @@ See </string>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<connections>
|
||||
<outlet property="activityIndicator" destination="yUe-TX-fli" id="DH6-pK-fse"/>
|
||||
<outlet property="descriptionLabel" destination="riF-bB-x5g" id="3v9-6H-PAK"/>
|
||||
<outlet property="priceLabel" destination="3jH-eX-9N2" id="agT-az-dVU"/>
|
||||
<outlet property="purchasedIndicator" destination="ec8-P9-KPY" id="M39-bc-Ksp"/>
|
||||
<outlet property="titleLabel" destination="Zch-DS-J3I" id="cY2-FQ-q69"/>
|
||||
</connections>
|
||||
</tableViewCell>
|
||||
<tableViewCell contentMode="scaleToFill" selectionStyle="default" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" shouldIndentWhileEditing="NO" reuseIdentifier="MPStoreProductCellTouchID" id="8en-6R-GvR" userLabel="TouchID" customClass="MPStoreProductCell">
|
||||
@@ -2815,8 +2821,10 @@ See </string>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<connections>
|
||||
<outlet property="activityIndicator" destination="Dv5-t7-lL1" id="AFu-Dd-TgU"/>
|
||||
<outlet property="descriptionLabel" destination="Yxc-Lr-382" id="47I-83-lgP"/>
|
||||
<outlet property="priceLabel" destination="ZGg-O6-rsg" id="dAn-xu-gut"/>
|
||||
<outlet property="purchasedIndicator" destination="yZX-ns-8oV" id="7x0-eq-oSs"/>
|
||||
<outlet property="titleLabel" destination="e1D-jp-GBs" id="jFw-dm-vp6"/>
|
||||
</connections>
|
||||
</tableViewCell>
|
||||
<tableViewCell contentMode="scaleToFill" selectionStyle="default" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" shouldIndentWhileEditing="NO" reuseIdentifier="MPStoreProductCellFuel" id="le3-Q5-MSO" userLabel="Fuel" customClass="MPStoreProductCell">
|
||||
@@ -2908,7 +2916,9 @@ invested: 3.7 work hours</string>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<connections>
|
||||
<outlet property="activityIndicator" destination="eS4-59-Xny" id="kGW-fn-VqH"/>
|
||||
<outlet property="descriptionLabel" destination="fz2-AO-aGW" id="xkc-xV-Z6Y"/>
|
||||
<outlet property="priceLabel" destination="EbU-DV-fKF" id="pg2-8o-7We"/>
|
||||
<outlet property="titleLabel" destination="Jnv-uN-xeg" id="Kxi-RE-ipa"/>
|
||||
</connections>
|
||||
</tableViewCell>
|
||||
</cells>
|
||||
|
Reference in New Issue
Block a user