diff --git a/External/Crashlytics.framework/Versions/A/Crashlytics b/External/Crashlytics.framework/Versions/A/Crashlytics index f3e3faa1..b59b18d9 100644 Binary files a/External/Crashlytics.framework/Versions/A/Crashlytics and b/External/Crashlytics.framework/Versions/A/Crashlytics differ diff --git a/External/Crashlytics.framework/Versions/A/Resources/Info.plist b/External/Crashlytics.framework/Versions/A/Resources/Info.plist index fe73cd9e..4f309f16 100644 --- a/External/Crashlytics.framework/Versions/A/Resources/Info.plist +++ b/External/Crashlytics.framework/Versions/A/Resources/Info.plist @@ -15,13 +15,13 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 2.1.2 + 2.1.3 CFBundleSupportedPlatforms iPhoneOS CFBundleVersion - 11 + 13 DTPlatformName iphoneos MinimumOSVersion diff --git a/External/Crashlytics.framework/run b/External/Crashlytics.framework/run index 9dbe108d..bf7d3a20 100755 Binary files a/External/Crashlytics.framework/run and b/External/Crashlytics.framework/run differ diff --git a/External/LoveLyndir b/External/LoveLyndir index 3f1a90f0..e2edbb3d 160000 --- a/External/LoveLyndir +++ b/External/LoveLyndir @@ -1 +1 @@ -Subproject commit 3f1a90f03de13362c1f9e3c275af2b085979efae +Subproject commit e2edbb3d7757b8f25cefe763d32ce86ff3f1ebae diff --git a/External/Pearl b/External/Pearl index 83b2f97b..7f176902 160000 --- a/External/Pearl +++ b/External/Pearl @@ -1 +1 @@ -Subproject commit 83b2f97b96c563699f0474a3e2510ef11c0cffb5 +Subproject commit 7f176902dc2aba84ce607c0ada42b28645d4f436 diff --git a/MasterPassword/ObjC/MPAppDelegate_Key.m b/MasterPassword/ObjC/MPAppDelegate_Key.m index 7e26c534..7e119ec5 100644 --- a/MasterPassword/ObjC/MPAppDelegate_Key.m +++ b/MasterPassword/ObjC/MPAppDelegate_Key.m @@ -166,7 +166,7 @@ static NSDictionary *keyQuery(MPUserEntity *user) { MPKey *recoverKey = newKey; #ifdef PEARL_UIKIT - PearlAlert *activityAlert = [PearlAlert showActivityWithTitle:PearlString( @"Migrating %ld sites...", (long)[user.elements count] )]; + PearlOverlay *activityOverlay = [PearlOverlay showOverlayWithTitle:PearlString( @"Migrating %ld sites...", (long)[user.elements count] )]; #endif for (MPElementEntity *element in user.elements) { @@ -216,7 +216,7 @@ static NSDictionary *keyQuery(MPUserEntity *user) { [moc saveToStore]; #ifdef PEARL_UIKIT - [activityAlert cancelAlertAnimated:YES]; + [activityOverlay cancelOverlayAnimated:YES]; #endif } diff --git a/MasterPassword/ObjC/MPAppDelegate_Store.m b/MasterPassword/ObjC/MPAppDelegate_Store.m index b0263246..79793f8c 100644 --- a/MasterPassword/ObjC/MPAppDelegate_Store.m +++ b/MasterPassword/ObjC/MPAppDelegate_Store.m @@ -441,8 +441,8 @@ PearlAssociatedObjectProperty(NSManagedObjectContext*, MainManagedObjectContext, } - (MPImportResult)importSites:(NSString *)importedSitesString - askImportPassword:(NSString *(^)(NSString *userName))importPassword - askUserPassword:(NSString *(^)(NSString *userName, NSUInteger importCount, NSUInteger deleteCount))userPassword + askImportPassword:(NSString *(^)(NSString *userName))askImportPassword + askUserPassword:(NSString *(^)(NSString *userName, NSUInteger importCount, NSUInteger deleteCount))askUserPassword saveInContext:(NSManagedObjectContext *)context { // Compile patterns. @@ -566,29 +566,32 @@ PearlAssociatedObjectProperty(NSManagedObjectContext*, MainManagedObjectContext, err(@"Lookup of existing sites failed for site: %@, user: %@, error: %@", name, user.userID, error); return MPImportResultInternalError; } - else if (existingSites.count) - dbg(@"Existing sites: %@", existingSites); - - [elementsToDelete addObjectsFromArray:existingSites]; - [importedSiteElements addObject:@[ lastUsed, uses, type, version, name, exportContent ]]; - dbg(@"Will import site: lastUsed=%@, uses=%@, type=%@, version=%@, name=%@, exportContent=%@", - lastUsed, uses, type, version, name, exportContent); + if ([existingSites count]) { + dbg(@"Existing sites: %@", existingSites); + [elementsToDelete addObjectsFromArray:existingSites]; + } } + [importedSiteElements addObject:@[ lastUsed, uses, type, version, name, exportContent ]]; + dbg(@"Will import site: lastUsed=%@, uses=%@, type=%@, version=%@, name=%@, exportContent=%@", + lastUsed, uses, type, version, name, exportContent); } // Ask for confirmation to import these sites and the master password of the user. inf(@"Importing %lu sites, deleting %lu sites, for user: %@", (unsigned long)[importedSiteElements count], (unsigned long)[elementsToDelete count], [MPUserEntity idFor:importUserName]); - NSString *userMasterPassword = userPassword( user.name, [importedSiteElements count], [elementsToDelete count] ); + NSString *userMasterPassword = askUserPassword( user? user.name: importUserName, [importedSiteElements count], [elementsToDelete count] ); if (!userMasterPassword) { inf(@"Import cancelled."); return MPImportResultCancelled; } - MPKey *userKey = [MPAlgorithmDefault keyForPassword:userMasterPassword ofUserNamed:user.name]; - if (![userKey.keyID isEqualToData:user.keyID]) + MPKey *userKey = [MPAlgorithmDefault keyForPassword:userMasterPassword ofUserNamed:user? user.name: importUserName]; + if (user && ![userKey.keyID isEqualToData:user.keyID]) return MPImportResultInvalidPassword; __block MPKey *importKey = userKey; - if ([importKey.keyID isEqualToData:importKeyID]) - importKey = nil; + if (![importKey.keyID isEqualToData:importKeyID]) + importKey = [importAlgorithm keyForPassword:askImportPassword( importUserName ) ofUserNamed:importUserName]; + if (![importKey.keyID isEqualToData:importKeyID]) + return MPImportResultInvalidPassword; + // Delete existing sites. if (elementsToDelete.count) @@ -628,14 +631,8 @@ PearlAssociatedObjectProperty(NSManagedObjectContext*, MainManagedObjectContext, if ([exportContent length]) { if (clearText) [element.algorithm importClearTextContent:exportContent intoElement:element usingKey:userKey]; - else { - if (!importKey) - importKey = [importAlgorithm keyForPassword:importPassword( user.name ) ofUserNamed:user.name]; - if (![importKey.keyID isEqualToData:importKeyID]) - return MPImportResultInvalidPassword; - + else [element.algorithm importProtectedContent:exportContent protectedByKey:importKey intoElement:element usingKey:userKey]; - } } dbg(@"Created Element: %@", [element debugDescription]); @@ -647,6 +644,10 @@ PearlAssociatedObjectProperty(NSManagedObjectContext*, MainManagedObjectContext, inf(@"Import completed successfully."); MPCheckpoint( MPCheckpointSitesImported, nil ); + [[NSNotificationCenter defaultCenter] postNotificationName:MPSitesImportedNotification object:nil userInfo:@{ + MPSitesImportedNotificationUserKey: user + }]; + return MPImportResultSuccess; } diff --git a/MasterPassword/ObjC/MPTypes.h b/MasterPassword/ObjC/MPTypes.h index b38700d1..3c026352 100644 --- a/MasterPassword/ObjC/MPTypes.h +++ b/MasterPassword/ObjC/MPTypes.h @@ -76,6 +76,9 @@ typedef enum { #define MPKeyForgottenNotification @"MPKeyForgottenNotification" #define MPElementUpdatedNotification @"MPElementUpdatedNotification" #define MPCheckConfigNotification @"MPCheckConfigNotification" +#define MPSitesImportedNotification @"MPSitesImportedNotification" + +#define MPSitesImportedNotificationUserKey @"MPSitesImportedNotificationUserKey" static void MPCheckpoint(NSString *checkpoint, NSDictionary *attributes) { diff --git a/MasterPassword/ObjC/iOS/MPElementListAllViewController.m b/MasterPassword/ObjC/iOS/MPElementListAllViewController.m index 971d7310..fe3dedef 100644 --- a/MasterPassword/ObjC/iOS/MPElementListAllViewController.m +++ b/MasterPassword/ObjC/iOS/MPElementListAllViewController.m @@ -85,11 +85,11 @@ if (buttonIndex == [alert cancelButtonIndex]) return; - PearlAlert *activity = [PearlAlert showActivityWithTitle:@"Upgrading Sites"]; + PearlOverlay *activity = [PearlOverlay showOverlayWithTitle:@"Upgrading Sites"]; [self performUpgradeAllWithCompletion:^(BOOL success, NSDictionary *changes) { dispatch_async( dispatch_get_main_queue(), ^{ [self showUpgradeChanges:changes]; - [activity cancelAlertAnimated:YES]; + [activity cancelOverlayAnimated:YES]; } ); }]; } cancelTitle:[PearlStrings get].commonButtonCancel otherTitles:[PearlStrings get].commonButtonContinue, nil]; diff --git a/MasterPassword/ObjC/iOS/MPLogsViewController.h b/MasterPassword/ObjC/iOS/MPLogsViewController.h index 025ed9e6..823c41e5 100644 --- a/MasterPassword/ObjC/iOS/MPLogsViewController.h +++ b/MasterPassword/ObjC/iOS/MPLogsViewController.h @@ -22,7 +22,7 @@ @interface MPLogsViewController : UIViewController @property (weak, nonatomic) IBOutlet UITextView *logView; @property (weak, nonatomic) IBOutlet UISegmentedControl *levelControl; -@property(nonatomic, strong) PearlAlert *switchCloudStoreProgress; + - (IBAction)action:(id)sender; - (IBAction)toggleLevelControl:(UISegmentedControl *)sender; - (IBAction)refresh:(UIBarButtonItem *)sender; diff --git a/MasterPassword/ObjC/iOS/MPLogsViewController.m b/MasterPassword/ObjC/iOS/MPLogsViewController.m index a4b41974..81bb8c04 100644 --- a/MasterPassword/ObjC/iOS/MPLogsViewController.m +++ b/MasterPassword/ObjC/iOS/MPLogsViewController.m @@ -19,14 +19,11 @@ #import "MPLogsViewController.h" #import "MPiOSAppDelegate.h" #import "MPAppDelegate_Store.h" -#import "MPAppDelegate_Key.h" @implementation MPLogsViewController { - PearlAlert *switchCloudStoreProgress; + PearlOverlay *_switchCloudStoreProgress; } -@synthesize switchCloudStoreProgress; - - (void)viewDidLoad { [super viewDidLoad]; @@ -36,7 +33,7 @@ ^(NSNotification *note) { dispatch_async( dispatch_get_main_queue(), ^{ self.levelControl.selectedSegmentIndex = [[MPiOSConfig get].traceMode boolValue]? 1: 0; - }); + } ); }]; } @@ -57,6 +54,7 @@ return; if (buttonIndex == sheet.firstOtherButtonIndex) { + // Switch [PearlAlert showAlertWithTitle:@"Switching iCloud Store" message: @"WARNING: This is an advanced operation and should only be done if you're having trouble with iCloud." viewStyle:UIAlertViewStyleDefault initAlert:nil @@ -64,14 +62,44 @@ if (buttonIndex_ == alert.cancelButtonIndex) return; - switchCloudStoreProgress = [PearlAlert showActivityWithTitle:@"Enumerating Stores"]; + _switchCloudStoreProgress = [PearlOverlay showOverlayWithTitle:@"Enumerating Stores"]; dispatch_async( dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0 ), ^{ [self switchCloudStore]; } ); - } cancelTitle:[PearlStrings get].commonButtonCancel otherTitles:[PearlStrings get].commonButtonContinue, nil]; + } cancelTitle:[PearlStrings get].commonButtonCancel otherTitles:[PearlStrings get].commonButtonContinue, nil]; + } + + if (buttonIndex == sheet.firstOtherButtonIndex + 1) { + // Rebuild + [PearlAlert showAlertWithTitle:@"Rebuilding iCloud Store" message: + @"WARNING: This is an advanced operation and should only be done if you're having trouble with iCloud.\n" + @"Your local iCloud data will be removed and redownloaded from iCloud." + viewStyle:UIAlertViewStyleDefault initAlert:nil + tappedButtonBlock:^(UIAlertView *alert, NSInteger buttonIndex_) { + if (buttonIndex_ == alert.cancelButtonIndex) + return; + + [[MPiOSAppDelegate get].storeManager deleteCloudContainerLocalOnly:YES]; + } + cancelTitle:[PearlStrings get].commonButtonCancel otherTitles:[PearlStrings get].commonButtonContinue, nil]; + } + + if (buttonIndex == sheet.firstOtherButtonIndex + 2) { + // Wipe + [PearlAlert showAlertWithTitle:@"Wiping iCloud Clean" message: + @"WARNING: This is an advanced operation and should only be done if you're having trouble with iCloud.\n" + @"All your iCloud data will be permanently lost. This is a clean slate!" + viewStyle:UIAlertViewStyleDefault initAlert:nil + tappedButtonBlock:^(UIAlertView *alert, NSInteger buttonIndex_) { + if (buttonIndex_ == alert.cancelButtonIndex) + return; + + [[MPiOSAppDelegate get].storeManager deleteCloudContainerLocalOnly:NO]; + } + cancelTitle:[PearlStrings get].commonButtonCancel otherTitles:[PearlStrings get].commonButtonContinue, nil]; } } cancelTitle:[PearlStrings get].commonButtonCancel - destructiveTitle:nil otherTitles:@"Switch iCloud Store", nil]; + destructiveTitle:nil otherTitles:@"Switch iCloud Store", @"Rebuild iCloud Container", @"Wipe iCloud Clean", nil]; } - (void)switchCloudStore { @@ -144,7 +172,7 @@ }]; }]; dispatch_async( dispatch_get_main_queue(), ^{ - [switchCloudStoreProgress cancelAlertAnimated:YES]; + [_switchCloudStoreProgress cancelOverlayAnimated:YES]; [self.navigationController pushViewController:vc animated:YES]; } ); } @@ -162,7 +190,7 @@ return; [MPiOSConfig get].traceMode = @YES; - } cancelTitle:[PearlStrings get].commonButtonCancel otherTitles:@"Enable Trace", nil]; + } cancelTitle:[PearlStrings get].commonButtonCancel otherTitles:@"Enable Trace", nil]; } else [MPiOSConfig get].traceMode = @NO; @@ -182,7 +210,7 @@ viewStyle:UIAlertViewStyleDefault initAlert:nil tappedButtonBlock:^(UIAlertView *alert, NSInteger buttonIndex) { [[MPiOSAppDelegate get] openFeedbackWithLogs:YES forVC:self]; - } cancelTitle:[PearlStrings get].commonButtonOkay otherTitles:nil]; + } cancelTitle:[PearlStrings get].commonButtonOkay otherTitles:nil]; } else [[MPiOSAppDelegate get] openFeedbackWithLogs:YES forVC:self]; diff --git a/MasterPassword/ObjC/iOS/MPUnlockViewController.m b/MasterPassword/ObjC/iOS/MPUnlockViewController.m index 7ce93ea4..f12ff28d 100644 --- a/MasterPassword/ObjC/iOS/MPUnlockViewController.m +++ b/MasterPassword/ObjC/iOS/MPUnlockViewController.m @@ -175,6 +175,11 @@ ^(NSNotification *note) { [self updateUsers]; }]; + [[NSNotificationCenter defaultCenter] addObserverForName:MPSitesImportedNotification object:nil + queue:[NSOperationQueue mainQueue] usingBlock: + ^(NSNotification *note) { + [self updateUsers]; + }]; [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationWillResignActiveNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock: ^(NSNotification *note) { diff --git a/MasterPassword/ObjC/iOS/MPiOSAppDelegate.m b/MasterPassword/ObjC/iOS/MPiOSAppDelegate.m index 914caf8b..176ac7d4 100644 --- a/MasterPassword/ObjC/iOS/MPiOSAppDelegate.m +++ b/MasterPassword/ObjC/iOS/MPiOSAppDelegate.m @@ -257,7 +257,7 @@ if (!importedSitesData) return; - PearlAlert *activityAlert = [PearlAlert showActivityWithTitle:@"Importing"]; + PearlOverlay *activityOverlay = [PearlOverlay showOverlayWithTitle:@"Importing"]; NSString *importedSitesString = [[NSString alloc] initWithData:importedSitesData encoding:NSUTF8StringEncoding]; MPImportResult result = [self importSites:importedSitesString askImportPassword:^NSString *(NSString *userName) { @@ -294,7 +294,7 @@ dispatch_async( dispatch_get_main_queue(), ^{ [PearlAlert showAlertWithTitle:PearlString( @"Master Password for\n%@", userName ) message:PearlString( @"Imports %lu sites, overwriting %lu.", - (unsigned long)importCount, (unsigned long)deleteCount ) + (unsigned long)importCount, (unsigned long)deleteCount ) viewStyle:UIAlertViewStyleSecureTextInput initAlert:nil tappedButtonBlock:^(UIAlertView *alert_, NSInteger buttonIndex_) { @try { @@ -329,7 +329,7 @@ break; } - [activityAlert cancelAlertAnimated:YES]; + [activityOverlay cancelOverlayAnimated:YES]; } ); return YES; @@ -469,12 +469,12 @@ attachments:(logs ? [[PearlEMailAttachment alloc] - initWithContent:[[[PearlLogger get] formatMessagesWithLevel:logLevel] - dataUsingEncoding:NSUTF8StringEncoding] - mimeType:@"text/plain" - fileName:PearlString( @"%@-%@.log", - [[NSDateFormatter rfc3339DateFormatter] stringFromDate:[NSDate date]], - [PearlKeyChain deviceIdentifier] )] + initWithContent:[[[PearlLogger get] formatMessagesWithLevel:logLevel] + dataUsingEncoding:NSUTF8StringEncoding] + mimeType:@"text/plain" + fileName:PearlString( @"%@-%@.log", + [[NSDateFormatter rfc3339DateFormatter] stringFromDate:[NSDate date]], + [PearlKeyChain deviceIdentifier] )] : nil), nil] showComposerForVC:viewController]; } @@ -500,8 +500,8 @@ if (buttonIndex_ == [alert_ firstOtherButtonIndex] + 1) // Show Passwords [self exportShowPasswords:YES]; - } cancelTitle:[PearlStrings get].commonButtonCancel otherTitles:@"Safe Export", @"Show Passwords", nil]; - } otherTitles:nil]; + } cancelTitle:[PearlStrings get].commonButtonCancel otherTitles:@"Safe Export", @"Show Passwords", nil]; + } otherTitles:nil]; } - (void)exportShowPasswords:(BOOL)showPasswords { @@ -761,32 +761,32 @@ __weak MPiOSAppDelegate *wSelf = self; [self.handleCloudContentAlert cancelAlertAnimated:NO]; - self.handleCloudContentAlert = [PearlAlert showActivityWithTitle:@"iCloud Sync Problem" message: - @"Waiting for your other device to auto‑correct the problem..." - initAlert:^(UIAlertView *alert) { - [alert addButtonWithTitle:@"Fix Now"]; - [alert addButtonWithTitle:@"Turn Off"]; - }]; - - self.handleCloudContentAlert.tappedButtonBlock = ^(UIAlertView *alert, NSInteger buttonIndex) { - if (buttonIndex == [alert firstOtherButtonIndex]) - wSelf.fixCloudContentAlert = [PearlAlert showAlertWithTitle:@"Fix iCloud Now" message: - @"This problem can be auto‑corrected by opening the app on another device where you recently made changes.\n" - @"You can fix the problem from this device anyway, but recent changes from another device might get lost.\n\n" - @"You can also turn iCloud off for now." - viewStyle:UIAlertViewStyleDefault initAlert:nil tappedButtonBlock: - ^(UIAlertView *alert_, NSInteger buttonIndex_) { - if (buttonIndex_ == alert_.cancelButtonIndex) - [wSelf showCloudContentAlert]; - if (buttonIndex_ == [alert_ firstOtherButtonIndex]) - [wSelf.storeManager rebuildCloudContentFromCloudStoreOrLocalStore:YES]; - if (buttonIndex_ == [alert_ firstOtherButtonIndex] + 1) - [MPiOSConfig get].iCloudEnabled = NO; - } cancelTitle:[PearlStrings get].commonButtonBack - otherTitles:@"Fix Anyway", @"Turn Off", nil]; - if (buttonIndex == [alert firstOtherButtonIndex] + 1) - [MPiOSConfig get].iCloudEnabled = NO; - }; + // TODO: Add the activity indicator back. + self.handleCloudContentAlert = [PearlAlert showAlertWithTitle:@"iCloud Sync Problem" + message:@"Waiting for your other device to auto‑correct the problem..." + viewStyle:UIAlertViewStyleDefault initAlert:nil tappedButtonBlock: + ^(UIAlertView *alert, NSInteger buttonIndex) { + if (buttonIndex == [alert firstOtherButtonIndex]) + wSelf.fixCloudContentAlert = [PearlAlert showAlertWithTitle:@"Fix iCloud Now" message: + @"This problem can be auto‑corrected by opening the app on another device where you recently made changes.\n" + @"You can fix the problem from this device anyway, but recent changes from another device might get lost.\n\n" + @"You can also turn iCloud off for now." + viewStyle:UIAlertViewStyleDefault + initAlert:nil tappedButtonBlock: + ^(UIAlertView *alert_, NSInteger buttonIndex_) { + if (buttonIndex_ == alert_.cancelButtonIndex) + [wSelf showCloudContentAlert]; + if (buttonIndex_ == [alert_ firstOtherButtonIndex]) + [wSelf.storeManager rebuildCloudContentFromCloudStoreOrLocalStore:YES]; + if (buttonIndex_ == [alert_ firstOtherButtonIndex] + 1) + [MPiOSConfig get].iCloudEnabled = @NO; + } + cancelTitle:[PearlStrings get].commonButtonBack + otherTitles:@"Fix Anyway", + @"Turn Off", nil]; + if (buttonIndex == [alert firstOtherButtonIndex] + 1) + [MPiOSConfig get].iCloudEnabled = @NO; + } cancelTitle:nil otherTitles:@"Fix Now", @"Turn Off", nil]; } diff --git a/MasterPassword/ObjC/iOS/MasterPassword-iOS.xcodeproj/project.pbxproj b/MasterPassword/ObjC/iOS/MasterPassword-iOS.xcodeproj/project.pbxproj index 490093f4..3b2ec1a7 100644 --- a/MasterPassword/ObjC/iOS/MasterPassword-iOS.xcodeproj/project.pbxproj +++ b/MasterPassword/ObjC/iOS/MasterPassword-iOS.xcodeproj/project.pbxproj @@ -8,6 +8,7 @@ /* Begin PBXBuildFile section */ 93D3922A53E41A54832E90D9 /* PearlOverlay.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D390FADEB325D8D54A957D /* PearlOverlay.m */; }; + 93D39233C3EDD9A947ABA52D /* LLButtonView.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39BF6BCBDFFE844E7D34C /* LLButtonView.m */; }; 93D39262A8A97DB748213309 /* PearlEMail.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D393BB973253D4BAAC84AA /* PearlEMail.m */; }; 93D392EC39DA43C46C692C12 /* NSDictionary+Indexing.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D393B97158D7BE9332EA53 /* NSDictionary+Indexing.h */; }; 93D3932889B6B4206E66A6D6 /* PearlEMail.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D39F7C9F47BF6387FBC5C3 /* PearlEMail.h */; }; @@ -19,6 +20,7 @@ 93D399A3008C590EE104F856 /* NSURL+UbiquityStoreManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D3970B24FC0B53D989F7E3 /* NSURL+UbiquityStoreManager.m */; }; 93D399BBC0A7EC746CB1B19B /* MPLogsViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D391943675426839501BB8 /* MPLogsViewController.h */; }; 93D39C34FE35830EF5BE1D2A /* NSArray+Indexing.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D396D04E57792A54D437AC /* NSArray+Indexing.h */; }; + 93D39C8AD8EAB747856B3A8C /* LLModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D3923B42DA2DA18F287092 /* LLModel.m */; }; 93D39E281E3658B30550CB55 /* NSDictionary+Indexing.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39AA1EE2E1E7B81372240 /* NSDictionary+Indexing.m */; }; 93D39EC9C559D2922B048CFE /* NSURL+UbiquityStoreManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D3957F61D8AFE3B6580C32 /* NSURL+UbiquityStoreManager.h */; }; 93D39F8A9254177891F38705 /* MPSetupViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39A28369954D147E239BA /* MPSetupViewController.m */; }; @@ -62,6 +64,7 @@ DA672D3014F9413D004A189C /* libPearl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DAC77CAD148291A600BCF976 /* libPearl.a */; }; DA69540617D975D900BF294E /* icon_gears.png in Resources */ = {isa = PBXBuildFile; fileRef = DABD37841711E29500CF925C /* icon_gears.png */; }; DA69540717D975D900BF294E /* icon_gears@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DABD37851711E29500CF925C /* icon_gears@2x.png */; }; + DA70EC801811B13C00F65DB2 /* StoreKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA70EC7F1811B13C00F65DB2 /* StoreKit.framework */; }; DA829E52159847E0002417D3 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA5BFA4A147E415C00F98B1E /* Foundation.framework */; }; DA829E6215984832002417D3 /* libFontReplacer.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DA829E51159847E0002417D3 /* libFontReplacer.a */; }; DA945C8717E3F3FD0053236B /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DA945C8617E3F3FD0053236B /* Images.xcassets */; }; @@ -265,7 +268,6 @@ DADEF41C1810D2940052CA3E /* love-lyndir.heart.red.png in Resources */ = {isa = PBXBuildFile; fileRef = DADEF4101810D2940052CA3E /* love-lyndir.heart.red.png */; }; DADEF41D1810D2940052CA3E /* love-lyndir.heart.red@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DADEF4111810D2940052CA3E /* love-lyndir.heart.red@2x.png */; }; DADEF4231810D5530052CA3E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA5BFA4A147E415C00F98B1E /* Foundation.framework */; }; - DADEF4461810D5850052CA3E /* LLButtonView.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D3944D91A78331DB509193 /* LLButtonView.m */; }; DADEF4471810D5850052CA3E /* LLToggleViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39C8E26B06F01566785B7 /* LLToggleViewController.m */; }; DADEF44B1810E7F30052CA3E /* love-lyndir.picker.png in Resources */ = {isa = PBXBuildFile; fileRef = DADEF4491810E7F30052CA3E /* love-lyndir.picker.png */; }; DADEF44C1810E7F30052CA3E /* love-lyndir.picker@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DADEF44A1810E7F30052CA3E /* love-lyndir.picker@2x.png */; }; @@ -409,24 +411,27 @@ /* Begin PBXFileReference section */ 93D39067C0AFDC581794E2B8 /* NSArray+Indexing.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSArray+Indexing.m"; sourceTree = ""; }; + 93D390A66F69AB1CDB0BFF93 /* LLModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LLModel.h; sourceTree = ""; }; 93D390FADEB325D8D54A957D /* PearlOverlay.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PearlOverlay.m; sourceTree = ""; }; 93D391943675426839501BB8 /* MPLogsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPLogsViewController.h; sourceTree = ""; }; + 93D3923B42DA2DA18F287092 /* LLModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LLModel.m; sourceTree = ""; }; 93D393B97158D7BE9332EA53 /* NSDictionary+Indexing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSDictionary+Indexing.h"; sourceTree = ""; }; 93D393BB973253D4BAAC84AA /* PearlEMail.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PearlEMail.m; sourceTree = ""; }; 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 = ""; }; - 93D3943B25D2BC7BA4691553 /* LLButtonView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LLButtonView.h; sourceTree = ""; }; - 93D3944D91A78331DB509193 /* LLButtonView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LLButtonView.m; sourceTree = ""; }; 93D3956915634581E737B38C /* PearlNavigationController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PearlNavigationController.m; sourceTree = ""; }; 93D3957F61D8AFE3B6580C32 /* NSURL+UbiquityStoreManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSURL+UbiquityStoreManager.h"; sourceTree = ""; }; 93D396D04E57792A54D437AC /* NSArray+Indexing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSArray+Indexing.h"; sourceTree = ""; }; 93D3970B24FC0B53D989F7E3 /* NSURL+UbiquityStoreManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSURL+UbiquityStoreManager.m"; sourceTree = ""; }; 93D39730673227EFF6DEFF19 /* MPSetupViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPSetupViewController.h; sourceTree = ""; }; 93D3979190DACEBD1F6AE9F4 /* MPLogsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPLogsViewController.m; sourceTree = ""; }; + 93D3983278751A530262F64E /* LLConfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LLConfig.h; sourceTree = ""; }; 93D398567FD02DB2647B8CF3 /* PearlNavigationController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PearlNavigationController.h; sourceTree = ""; }; 93D39A28369954D147E239BA /* MPSetupViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPSetupViewController.m; sourceTree = ""; }; 93D39A3CC4D8330831FC8CB4 /* LLToggleViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LLToggleViewController.h; sourceTree = ""; }; 93D39AA1EE2E1E7B81372240 /* NSDictionary+Indexing.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSDictionary+Indexing.m"; sourceTree = ""; }; + 93D39BA6C5CB452973918B7D /* LLButtonView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LLButtonView.h; sourceTree = ""; }; + 93D39BF6BCBDFFE844E7D34C /* LLButtonView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LLButtonView.m; sourceTree = ""; }; 93D39C8E26B06F01566785B7 /* LLToggleViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LLToggleViewController.m; sourceTree = ""; }; 93D39F7C9F47BF6387FBC5C3 /* PearlEMail.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PearlEMail.h; sourceTree = ""; }; DA04E33D14B1E70400ECA4F3 /* MobileCoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MobileCoreServices.framework; path = System/Library/Frameworks/MobileCoreServices.framework; sourceTree = SDKROOT; }; @@ -466,6 +471,7 @@ DA6701DD16406B7300B61001 /* Social.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Social.framework; path = System/Library/Frameworks/Social.framework; sourceTree = SDKROOT; }; DA6701DF16406BB400B61001 /* AdSupport.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AdSupport.framework; path = System/Library/Frameworks/AdSupport.framework; sourceTree = SDKROOT; }; DA672D2E14F92C6B004A189C /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; }; + DA70EC7F1811B13C00F65DB2 /* StoreKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = StoreKit.framework; path = System/Library/Frameworks/StoreKit.framework; sourceTree = SDKROOT; }; DA829E51159847E0002417D3 /* libFontReplacer.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libFontReplacer.a; sourceTree = BUILT_PRODUCTS_DIR; }; DA945C8617E3F3FD0053236B /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; DA95D5F014DF0B1E008D1B94 /* MessageUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MessageUI.framework; path = System/Library/Frameworks/MessageUI.framework; sourceTree = SDKROOT; }; @@ -1454,6 +1460,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + DA70EC801811B13C00F65DB2 /* StoreKit.framework in Frameworks */, DADEF4231810D5530052CA3E /* Foundation.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1509,6 +1516,7 @@ DA5BFA47147E415C00F98B1E /* Frameworks */ = { isa = PBXGroup; children = ( + DA70EC7F1811B13C00F65DB2 /* StoreKit.framework */, DABD3FC617122ADD00CF925C /* libscrypt-bin-ios.a */, DA6701DF16406BB400B61001 /* AdSupport.framework */, DA6701DD16406B7300B61001 /* Social.framework */, @@ -2514,11 +2522,14 @@ DADEF4041810D2940052CA3E /* ObjC */ = { isa = PBXGroup; children = ( - 93D3944D91A78331DB509193 /* LLButtonView.m */, - 93D3943B25D2BC7BA4691553 /* LLButtonView.h */, 93D39C8E26B06F01566785B7 /* LLToggleViewController.m */, 93D39A3CC4D8330831FC8CB4 /* LLToggleViewController.h */, DADEF4481810D5A70052CA3E /* LoveLyndir.storyboard */, + 93D3923B42DA2DA18F287092 /* LLModel.m */, + 93D390A66F69AB1CDB0BFF93 /* LLModel.h */, + 93D3983278751A530262F64E /* LLConfig.h */, + 93D39BF6BCBDFFE844E7D34C /* LLButtonView.m */, + 93D39BA6C5CB452973918B7D /* LLButtonView.h */, ); path = ObjC; sourceTree = ""; @@ -3546,7 +3557,8 @@ buildActionMask = 2147483647; files = ( DADEF4471810D5850052CA3E /* LLToggleViewController.m in Sources */, - DADEF4461810D5850052CA3E /* LLButtonView.m in Sources */, + 93D39C8AD8EAB747856B3A8C /* LLModel.m in Sources */, + 93D39233C3EDD9A947ABA52D /* LLButtonView.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -4138,18 +4150,21 @@ DADEF43E1810D5540052CA3E /* Debug-iOS */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ENABLE_OBJC_ARC = YES; }; name = "Debug-iOS"; }; DADEF43F1810D5540052CA3E /* AdHoc-iOS */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ENABLE_OBJC_ARC = YES; }; name = "AdHoc-iOS"; }; DADEF4401810D5540052CA3E /* AppStore-iOS */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ENABLE_OBJC_ARC = YES; }; name = "AppStore-iOS"; }; @@ -4298,6 +4313,7 @@ DADEF4401810D5540052CA3E /* AppStore-iOS */, ); defaultConfigurationIsVisible = 0; + defaultConfigurationName = "AdHoc-iOS"; }; DAE1EF4617ED112700BC0086 /* Build configuration list for PBXNativeTarget "DCIntrospect" */ = { isa = XCConfigurationList;