From 68e6106ee79593f5725784c2f59300074a85cc87 Mon Sep 17 00:00:00 2001 From: Maarten Billemont Date: Sun, 21 Sep 2014 10:29:18 -0400 Subject: [PATCH] Extract In-App logic into app delegate category & improvements to import file handling and advanced export + store fixes. --- External/Pearl | 2 +- MasterPassword/ObjC/MPAlgorithmV0.m | 1 + MasterPassword/ObjC/MPAppDelegate_Key.m | 6 ++ MasterPassword/ObjC/MPAppDelegate_Shared.h | 7 +- MasterPassword/ObjC/MPAppDelegate_Shared.m | 12 ++- .../ObjC/Mac/MasterPassword-Info.plist | 27 +++--- MasterPassword/ObjC/iOS/MPPasswordCell.m | 1 + .../ObjC/iOS/MPStoreViewController.m | 34 +++---- MasterPassword/ObjC/iOS/MPiOSAppDelegate.h | 4 - MasterPassword/ObjC/iOS/MPiOSAppDelegate.m | 95 +++++++------------ .../ObjC/iOS/MasterPassword-Info.plist | 21 ++-- .../project.pbxproj | 10 +- 12 files changed, 98 insertions(+), 122 deletions(-) diff --git a/External/Pearl b/External/Pearl index be82c9b4..4afc758c 160000 --- a/External/Pearl +++ b/External/Pearl @@ -1 +1 @@ -Subproject commit be82c9b4bfe8a58c72d1cc10d1a02e2d419edb38 +Subproject commit 4afc758ce467cf75f2594512e2be3125c45d640c diff --git a/MasterPassword/ObjC/MPAlgorithmV0.m b/MasterPassword/ObjC/MPAlgorithmV0.m index ced1ae4c..f6aaff81 100644 --- a/MasterPassword/ObjC/MPAlgorithmV0.m +++ b/MasterPassword/ObjC/MPAlgorithmV0.m @@ -18,6 +18,7 @@ #import "MPAlgorithmV0.h" #import "MPEntities.h" #import "MPAppDelegate_Shared.h" +#import "MPAppDelegate_InApp.h" #include #include diff --git a/MasterPassword/ObjC/MPAppDelegate_Key.m b/MasterPassword/ObjC/MPAppDelegate_Key.m index 4ca48c0c..3822a993 100644 --- a/MasterPassword/ObjC/MPAppDelegate_Key.m +++ b/MasterPassword/ObjC/MPAppDelegate_Key.m @@ -9,6 +9,12 @@ #import "MPAppDelegate_Key.h" #import "MPAppDelegate_Store.h" +@interface MPAppDelegate_Shared() + +@property(strong, nonatomic) MPKey *key; + +@end + @implementation MPAppDelegate_Shared(Key) static NSDictionary *keyQuery(MPUserEntity *user) { diff --git a/MasterPassword/ObjC/MPAppDelegate_Shared.h b/MasterPassword/ObjC/MPAppDelegate_Shared.h index 0689ebc6..1e5f75d2 100644 --- a/MasterPassword/ObjC/MPAppDelegate_Shared.h +++ b/MasterPassword/ObjC/MPAppDelegate_Shared.h @@ -9,14 +9,13 @@ #import "MPEntities.h" #if TARGET_OS_IPHONE - @interface MPAppDelegate_Shared : PearlAppDelegate #else @interface MPAppDelegate_Shared : NSObject #endif -@property(strong, nonatomic) MPKey *key; -@property(strong, nonatomic) NSManagedObjectID *activeUserOID; +@property(strong, nonatomic, readonly) MPKey *key; +@property(strong, nonatomic, readonly) NSManagedObjectID *activeUserOID; + (instancetype)get; @@ -24,6 +23,4 @@ - (MPUserEntity *)activeUserInContext:(NSManagedObjectContext *)context; - (void)setActiveUser:(MPUserEntity *)activeUser; -- (BOOL)isPurchased:(NSString *)productIdentifier; - @end diff --git a/MasterPassword/ObjC/MPAppDelegate_Shared.m b/MasterPassword/ObjC/MPAppDelegate_Shared.m index 7d4e7227..3c075cd5 100644 --- a/MasterPassword/ObjC/MPAppDelegate_Shared.m +++ b/MasterPassword/ObjC/MPAppDelegate_Shared.m @@ -10,6 +10,13 @@ #import "MPAppDelegate_Store.h" #import "MPAppDelegate_Key.h" +@interface MPAppDelegate_Shared () + +@property(strong, nonatomic) MPKey *key; +@property(strong, nonatomic) NSManagedObjectID *activeUserOID; + +@end + @implementation MPAppDelegate_Shared + (MPAppDelegate_Shared *)get { @@ -50,9 +57,4 @@ self.activeUserOID = activeUser.objectID; } -- (BOOL)isPurchased:(NSString *)productIdentifier { - - return [[NSUserDefaults standardUserDefaults] objectForKey:productIdentifier] != nil; -} - @end diff --git a/MasterPassword/ObjC/Mac/MasterPassword-Info.plist b/MasterPassword/ObjC/Mac/MasterPassword-Info.plist index e6df7def..0acabfa0 100644 --- a/MasterPassword/ObjC/Mac/MasterPassword-Info.plist +++ b/MasterPassword/ObjC/Mac/MasterPassword-Info.plist @@ -19,6 +19,10 @@ CFBundleTypeIconFiles + CFBundleTypeMIMETypes + + text/plain + CFBundleTypeName Master Password sites CFBundleTypeRole @@ -27,8 +31,10 @@ Owner LSItemContentTypes - com.lyndir.lhunath.MasterPassword.sites + com.lyndir.masterpassword.sites + LSTypeIsPackage + 0 CFBundleExecutable @@ -47,19 +53,6 @@ [auto] CFBundleSignature ???? - CFBundleURLTypes - - - CFBundleTypeRole - Editor - CFBundleURLName - com.lyndir.lhunath.MasterPassword - CFBundleURLSchemes - - com.lyndir.lhunath.MasterPassword - - - CFBundleVersion [auto] LSApplicationCategoryType @@ -77,12 +70,16 @@ UTExportedTypeDeclarations + UTTypeConformsTo + + public.utf8-plain-text + UTTypeDescription Master Password sites UTTypeIconFile UTTypeIdentifier - com.lyndir.lhunath.MasterPassword.sites + com.lyndir.masterpassword.sites UTTypeSize320IconFile UTTypeSize64IconFile diff --git a/MasterPassword/ObjC/iOS/MPPasswordCell.m b/MasterPassword/ObjC/iOS/MPPasswordCell.m index dfffe6dd..938a707b 100644 --- a/MasterPassword/ObjC/iOS/MPPasswordCell.m +++ b/MasterPassword/ObjC/iOS/MPPasswordCell.m @@ -20,6 +20,7 @@ #import "MPiOSAppDelegate.h" #import "MPAppDelegate_Store.h" #import "UIColor+Expanded.h" +#import "MPAppDelegate_InApp.h" @interface MPPasswordCell() diff --git a/MasterPassword/ObjC/iOS/MPStoreViewController.m b/MasterPassword/ObjC/iOS/MPStoreViewController.m index ee87f15d..d6c613f8 100644 --- a/MasterPassword/ObjC/iOS/MPStoreViewController.m +++ b/MasterPassword/ObjC/iOS/MPStoreViewController.m @@ -14,6 +14,7 @@ #import "UIColor+Expanded.h" #import "MPPasswordsViewController.h" #import "MPCoachmarkViewController.h" +#import "MPAppDelegate_InApp.h" @interface MPStoreViewController() @@ -53,7 +54,7 @@ [self updateWithProducts:to]; } ); }]; - [[MPiOSAppDelegate get] observeKeyPath:@"productTransactions" withBlock:^(id from, id to, NSKeyValueChange cause, id _self) { + [[MPiOSAppDelegate get] observeKeyPath:@"paymentTransactions" withBlock:^(id from, id to, NSKeyValueChange cause, id _self) { if (NSNullToNil( to )) PearlMainQueue( ^{ [self updateWithTransactions:to]; @@ -63,6 +64,8 @@ queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) { [self updateWithProducts:[MPiOSAppDelegate get].products]; }]; + + [[MPiOSAppDelegate get] updateProducts]; } #pragma mark - UITableViewDelegate @@ -70,6 +73,10 @@ - (MPStoreProductCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { MPStoreProductCell *cell = (MPStoreProductCell *)[super tableView:tableView cellForRowAtIndexPath:indexPath]; + if (indexPath.section == 0) + cell.selectionStyle = [[MPiOSAppDelegate get] isPurchased:[self productForCell:cell].productIdentifier]? + UITableViewCellSelectionStyleDefault: UITableViewCellSelectionStyleNone; + if (cell.selectionStyle != UITableViewCellSelectionStyleNone) { cell.selectedBackgroundView = [[UIView alloc] initWithFrame:cell.bounds]; cell.selectedBackgroundView.backgroundColor = [UIColor colorWithRGBAHex:0x78DDFB33]; @@ -80,24 +87,19 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { + if (![SKPaymentQueue canMakePayments]) { + [PearlAlert showAlertWithTitle:@"Store Not Set Up" message: + @"Try logging using the App Store or from Settings." + viewStyle:UIAlertViewStyleDefault initAlert:nil + tappedButtonBlock:nil cancelTitle:@"Thanks" otherTitles:nil]; + return; + } + MPStoreProductCell *cell = (MPStoreProductCell *)[self tableView:tableView cellForRowAtIndexPath:indexPath]; SKProduct *product = [self productForCell:cell]; - if (product && [SKPaymentQueue canMakePayments]) { - SKPayment *payment = nil; - if (cell == self.generateLoginCell) - payment = [SKPayment paymentWithProduct:product]; - if (cell == self.generateAnswersCell) { - } - if (cell == self.advancedExportCell) { - } - if (cell == self.iOSIntegrationCell) { - } - if (cell == self.touchIDCell) { - } - - [[SKPaymentQueue defaultQueue] addPayment:payment]; - } + if (product) + [[SKPaymentQueue defaultQueue] addPayment:[SKPayment paymentWithProduct:product]]; [tableView deselectRowAtIndexPath:indexPath animated:YES]; } diff --git a/MasterPassword/ObjC/iOS/MPiOSAppDelegate.h b/MasterPassword/ObjC/iOS/MPiOSAppDelegate.h index 345766c6..afeff347 100644 --- a/MasterPassword/ObjC/iOS/MPiOSAppDelegate.h +++ b/MasterPassword/ObjC/iOS/MPiOSAppDelegate.h @@ -14,10 +14,6 @@ @interface MPiOSAppDelegate : MPAppDelegate_Shared -@property(nonatomic, strong) NSArray /* SKProduct */ *products; - -@property(nonatomic, strong) NSArray *productTransactions; - - (void)showFeedbackWithLogs:(BOOL)logs forVC:(UIViewController *)viewController; - (void)openFeedbackWithLogs:(BOOL)logs forVC:(UIViewController *)viewController; diff --git a/MasterPassword/ObjC/iOS/MPiOSAppDelegate.m b/MasterPassword/ObjC/iOS/MPiOSAppDelegate.m index 70e15b4b..a83ed010 100644 --- a/MasterPassword/ObjC/iOS/MPiOSAppDelegate.m +++ b/MasterPassword/ObjC/iOS/MPiOSAppDelegate.m @@ -7,17 +7,20 @@ // #import +#import #import "MPiOSAppDelegate.h" #import "MPAppDelegate_Key.h" #import "MPAppDelegate_Store.h" #import "IASKSettingsReader.h" +#import "MPAppDelegate_InApp.h" -@interface MPiOSAppDelegate() +@interface MPiOSAppDelegate() @property(nonatomic, weak) PearlAlert *handleCloudDisabledAlert; @property(nonatomic, weak) PearlAlert *handleCloudContentAlert; @property(nonatomic, weak) PearlAlert *fixCloudContentAlert; @property(nonatomic, weak) PearlOverlay *storeLoadingOverlay; +@property(nonatomic, strong) UIDocumentInteractionController *interactionController; @end @implementation MPiOSAppDelegate @@ -148,12 +151,6 @@ @"legal" : @"YES", #endif } ); - - [[SKPaymentQueue defaultQueue] addTransactionObserver:self]; - SKProductsRequest *productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:[[NSSet alloc] initWithObjects: - MPProductGenerateLogins, nil]]; - productsRequest.delegate = self; - [productsRequest start]; } @catch (id exception) { err( @"During Post-Startup: %@", exception ); @@ -282,53 +279,6 @@ [super applicationDidBecomeActive:application]; } -#pragma mark - SKProductsRequestDelegate - -- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response { - - inf( @"products: %@, invalid: %@", response.products, response.invalidProductIdentifiers ); - self.products = response.products; -} - -- (void)request:(SKRequest *)request didFailWithError:(NSError *)error { - - err( @"StoreKit request (%@) failed: %@", request, error ); -} - -- (void)requestDidFinish:(SKRequest *)request { - - dbg( @"StoreKit request (%@) finished.", request ); -} - -#pragma mark - SKPaymentTransactionObserver - -- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions { - - for (SKPaymentTransaction *transaction in transactions) { - dbg( @"transaction updated: %@", transaction ); - switch (transaction.transactionState) { - case SKPaymentTransactionStatePurchased: - case SKPaymentTransactionStateRestored: { - inf( @"purchased: %@", transaction.payment.productIdentifier ); - [[NSUserDefaults standardUserDefaults] setObject:transaction.transactionIdentifier - forKey:transaction.payment.productIdentifier]; - break; - } - case SKPaymentTransactionStatePurchasing: - case SKPaymentTransactionStateFailed: - case SKPaymentTransactionStateDeferred: - break; - } - } - - self.productTransactions = transactions; -} - -- (void)paymentQueue:(SKPaymentQueue *)queue restoreCompletedTransactionsFailedWithError:(NSError *)error { - - err( @"StoreKit restore failed: %@", error ); -} - #pragma mark - Behavior - (void)showReview { @@ -464,12 +414,30 @@ NSDateFormatter *exportDateFormatter = [NSDateFormatter new]; [exportDateFormatter setDateFormat:@"yyyy'-'MM'-'dd"]; - [PearlEMail sendEMailTo:nil fromVC:viewController subject:@"Master Password Export" body:message - attachments:[[PearlEMailAttachment alloc] initWithContent:[exportedSites dataUsingEncoding:NSUTF8StringEncoding] - mimeType:@"text/plain" fileName: - strf( @"%@ (%@).mpsites", [self activeUserForMainThread].name, - [exportDateFormatter stringFromDate:[NSDate date]] )], - nil]; + NSString *exportFileName = strf( @"%@ (%@).mpsites", + [self activeUserForMainThread].name, [exportDateFormatter stringFromDate:[NSDate date]] ); + if (![[MPiOSAppDelegate get] isPurchased:MPProductAdvancedExport]) + [PearlEMail sendEMailTo:nil fromVC:viewController subject:@"Master Password Export" body:message + attachments:[[PearlEMailAttachment alloc] initWithContent:[exportedSites dataUsingEncoding:NSUTF8StringEncoding] + mimeType:@"text/plain" fileName:exportFileName], + nil]; + else { + NSURL *applicationSupportURL = [[[NSFileManager defaultManager] URLsForDirectory:NSApplicationSupportDirectory + inDomains:NSUserDomainMask] lastObject]; + NSURL *exportURL = [[applicationSupportURL + URLByAppendingPathComponent:[NSBundle mainBundle].bundleIdentifier isDirectory:YES] + URLByAppendingPathComponent:exportFileName isDirectory:NO]; + NSError *error = nil; + if (![[exportedSites dataUsingEncoding:NSUTF8StringEncoding] + writeToURL:exportURL options:NSDataWritingFileProtectionComplete error:&error]) + err( @"Failed to write export data to URL %@: %@", exportURL, error ); + else { + self.interactionController = [UIDocumentInteractionController interactionControllerWithURL:exportURL]; + self.interactionController.UTI = @"com.lyndir.masterpassword.sites"; + self.interactionController.delegate = self; + [self.interactionController presentOpenInMenuFromRect:CGRectZero inView:viewController.view animated:YES]; + } + } } - (void)changeMasterPasswordFor:(MPUserEntity *)user saveInContext:(NSManagedObjectContext *)moc didResetBlock:(void ( ^ )(void))didReset { @@ -501,6 +469,13 @@ otherTitles:[PearlStrings get].commonButtonContinue, nil]; } +#pragma mark - UIDocumentInteractionControllerDelegate + +- (void)documentInteractionController:(UIDocumentInteractionController *)controller didEndSendingToApplication:(NSString *)application { + +// self.interactionController = nil; +} + #pragma mark - PearlConfigDelegate - (void)didUpdateConfigForKey:(SEL)configKey fromValue:(id)value { diff --git a/MasterPassword/ObjC/iOS/MasterPassword-Info.plist b/MasterPassword/ObjC/iOS/MasterPassword-Info.plist index a42280b3..5ae970b9 100644 --- a/MasterPassword/ObjC/iOS/MasterPassword-Info.plist +++ b/MasterPassword/ObjC/iOS/MasterPassword-Info.plist @@ -21,7 +21,7 @@ Owner LSItemContentTypes - com.lyndir.lhunath.MasterPassword.sites + com.lyndir.masterpassword.sites @@ -39,19 +39,6 @@ [auto] CFBundleSignature ???? - CFBundleURLTypes - - - CFBundleTypeRole - Editor - CFBundleURLName - com.lyndir.lhunath.MasterPassword - CFBundleURLSchemes - - com.lyndir.lhunath.MasterPassword - - - CFBundleVersion [auto] LSRequiresIPhoneOS @@ -109,10 +96,14 @@ UTExportedTypeDeclarations + UTTypeConformsTo + + public.utf8-plain-text + UTTypeDescription Master Password sites UTTypeIdentifier - com.lyndir.lhunath.MasterPassword.sites + com.lyndir.masterpassword.sites UTTypeSize320IconFile UTTypeSize64IconFile diff --git a/MasterPassword/ObjC/iOS/MasterPassword-iOS.xcodeproj/project.pbxproj b/MasterPassword/ObjC/iOS/MasterPassword-iOS.xcodeproj/project.pbxproj index 5bc11516..12930910 100644 --- a/MasterPassword/ObjC/iOS/MasterPassword-iOS.xcodeproj/project.pbxproj +++ b/MasterPassword/ObjC/iOS/MasterPassword-iOS.xcodeproj/project.pbxproj @@ -42,6 +42,7 @@ 93D39B8F90F58A5D158DDBA3 /* MPPasswordsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D3924EE15017F8A12CB436 /* MPPasswordsViewController.m */; }; 93D39BA1EA3CAAC8A220B4A6 /* MPAppSettingsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D3916C1D8F1427DFBDEBCA /* MPAppSettingsViewController.m */; }; 93D39C34FE35830EF5BE1D2A /* NSArray+Indexing.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D396D04E57792A54D437AC /* NSArray+Indexing.h */; }; + 93D39D38356F59DBEF934D70 /* MPAppDelegate_InApp.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D394C78C7B879C9AD9152C /* MPAppDelegate_InApp.m */; }; 93D39D47FC623E91FC39D20C /* UICollectionView+PearlReloadFromArray.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D3908DF8EABBD952065DC0 /* UICollectionView+PearlReloadFromArray.m */; }; 93D39D596A2E376D6F6F5DA1 /* MPCombinedViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D393310223DDB35218467A /* MPCombinedViewController.m */; }; 93D39D8F78978196D6ABDEDE /* MPNavigationController.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39CC01630D0421205C4C4 /* MPNavigationController.m */; }; @@ -408,6 +409,7 @@ 93D394077F8FAB8167647187 /* Twitter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Twitter.framework; path = System/Library/Frameworks/Twitter.framework; sourceTree = SDKROOT; }; 93D3942A356B639724157982 /* PearlOverlay.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PearlOverlay.h; sourceTree = ""; }; 93D394482BB07F90E8FD1314 /* UIResponder+PearlFirstResponder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIResponder+PearlFirstResponder.h"; sourceTree = ""; }; + 93D394C78C7B879C9AD9152C /* MPAppDelegate_InApp.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPAppDelegate_InApp.m; sourceTree = ""; }; 93D3956915634581E737B38C /* PearlNavigationController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PearlNavigationController.m; sourceTree = ""; }; 93D3957D76F71A652716EECC /* MPStoreViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPStoreViewController.m; sourceTree = ""; }; 93D396D04E57792A54D437AC /* NSArray+Indexing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSArray+Indexing.h"; sourceTree = ""; }; @@ -440,6 +442,7 @@ 93D39C86E984EC65DA5ACB1D /* MPAppSettingsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPAppSettingsViewController.h; sourceTree = ""; }; 93D39CC01630D0421205C4C4 /* MPNavigationController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPNavigationController.m; sourceTree = ""; }; 93D39CDD434AFD6E1B0DA359 /* MPEmergencyViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPEmergencyViewController.h; sourceTree = ""; }; + 93D39CECA10BCCB0BA581BF1 /* MPAppDelegate_InApp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPAppDelegate_InApp.h; sourceTree = ""; }; 93D39CF8ADF4542CDC4CD385 /* MPCombinedViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPCombinedViewController.h; sourceTree = ""; }; 93D39D8A953779B35403AF6E /* PearlUICollectionView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PearlUICollectionView.m; sourceTree = ""; }; 93D39DA27D768B53C8B1330C /* MPAvatarCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPAvatarCell.h; sourceTree = ""; }; @@ -1370,6 +1373,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + DA04E33E14B1E70400ECA4F3 /* MobileCoreServices.framework in Frameworks */, DAE2725A19C93B8E007C5262 /* StoreKit.framework in Frameworks */, DAE2725919C93B80007C5262 /* libInAppSettingsKit.a in Frameworks */, DA6701E016406BB400B61001 /* AdSupport.framework in Frameworks */, @@ -1381,7 +1385,6 @@ DA672D2F14F92C6B004A189C /* libz.dylib in Frameworks */, DAEBC45314F6364500987BF6 /* QuartzCore.framework in Frameworks */, DA95D5F214DF0B2C008D1B94 /* MessageUI.framework in Frameworks */, - DA04E33E14B1E70400ECA4F3 /* MobileCoreServices.framework in Frameworks */, DA48856019A5A82E000C2D79 /* Crashlytics.framework in Frameworks */, DAC632891486D9690075AEA5 /* Security.framework in Frameworks */, DA72BD7919C137DE00E6ACFE /* libopensslcrypto-ios-dev.a in Frameworks */, @@ -2292,6 +2295,8 @@ DABD3BD01711E2DC00CF925C /* MasterPassword.xcdatamodeld */, 93D399F244BB522A317811BB /* MPFixable.h */, 93D39A813CA9D7E192261ED2 /* MPFixable.m */, + 93D394C78C7B879C9AD9152C /* MPAppDelegate_InApp.m */, + 93D39CECA10BCCB0BA581BF1 /* MPAppDelegate_InApp.h */, ); name = ObjC; path = ..; @@ -3231,6 +3236,9 @@ 93D394982CBD25D46692DD7C /* MPWebViewController.m in Sources */, 93D39D8F78978196D6ABDEDE /* MPNavigationController.m in Sources */, 93D3939661CE37180AF7CD6A /* MPStoreViewController.m in Sources */, + DA9521AB19CEA3DE002E3AD5 /* MPSiteQuestion.m in Sources */, + 93D39D38356F59DBEF934D70 /* MPAppDelegate_InApp.m in Sources */, + 93D390C1B93F9D3AE37DD0A5 /* MPAnswersViewController.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; };