Add support for Answers and improved Fabric integration.
This commit is contained in:
parent
07e55140ac
commit
6d9be3fdfe
@ -42,7 +42,6 @@
|
||||
93D398ECD7D1A0DEDDADF516 /* MPEmergencyViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39ACBA9F4878B6A1CC33B /* MPEmergencyViewController.m */; };
|
||||
93D399246DC90F50913A1287 /* UIResponder+PearlFirstResponder.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39A1DDFA09AE2E14D26DC /* UIResponder+PearlFirstResponder.m */; };
|
||||
93D3992FA1546E01F498F665 /* PearlNavigationController.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D398567FD02DB2647B8CF3 /* PearlNavigationController.h */; };
|
||||
93D399433EA75E50656040CB /* Twitter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 93D394077F8FAB8167647187 /* Twitter.framework */; };
|
||||
93D39943D01E70DAC3B0DF76 /* mpw-util.c in Sources */ = {isa = PBXBuildFile; fileRef = 93D396C311C3725870343EE0 /* mpw-util.c */; };
|
||||
93D399D7E08A142776A74CB8 /* MPOverlayViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D395105935859D71679931 /* MPOverlayViewController.m */; };
|
||||
93D399E4BC1E092A8C8B12AE /* NSOrderedSetOrArray.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D39FBF8FCEB4C106272334 /* NSOrderedSetOrArray.h */; };
|
||||
@ -87,6 +86,9 @@
|
||||
DA0CC5361EAB99BA009A8ED9 /* IASKTextField.m in Sources */ = {isa = PBXBuildFile; fileRef = DA0CC5241EAB99BA009A8ED9 /* IASKTextField.m */; };
|
||||
DA0CC5371EAB99BA009A8ED9 /* IASKTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = DA0CC5261EAB99BA009A8ED9 /* IASKTextView.m */; };
|
||||
DA0CC5381EAB99BA009A8ED9 /* IASKTextViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = DA0CC5281EAB99BA009A8ED9 /* IASKTextViewCell.m */; };
|
||||
DA0CC53B1EB57B5C009A8ED9 /* Fabric.plist in Resources */ = {isa = PBXBuildFile; fileRef = DA0CC53A1EB57B5C009A8ED9 /* Fabric.plist */; };
|
||||
DA0CC5411EB57BD4009A8ED9 /* Fabric.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA0CC53F1EB57B91009A8ED9 /* Fabric.framework */; };
|
||||
DA0CC5421EB57BD4009A8ED9 /* Crashlytics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DAA141191922FED80032B392 /* Crashlytics.framework */; };
|
||||
DA24EBAE19DAD08900FF010B /* tip_basic_black_top.png in Resources */ = {isa = PBXBuildFile; fileRef = DABD38941711E29700CF925C /* tip_basic_black_top.png */; };
|
||||
DA24EBAF19DAD08C00FF010B /* tip_basic_black_top@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DABD38951711E29700CF925C /* tip_basic_black_top@2x.png */; };
|
||||
DA24EBE819DAD6DE00FF010B /* Icon-320.png in Resources */ = {isa = PBXBuildFile; fileRef = DA24EBE619DAD6DE00FF010B /* Icon-320.png */; };
|
||||
@ -114,7 +116,6 @@
|
||||
DA29993219C9132F00AF7DF1 /* thumb_generated_login@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = DA29993119C9132F00AF7DF1 /* thumb_generated_login@3x.png */; };
|
||||
DA29993319C9214600AF7DF1 /* icon_star-hollow.png in Resources */ = {isa = PBXBuildFile; fileRef = DABD382A1711E29600CF925C /* icon_star-hollow.png */; };
|
||||
DA29993419C9214600AF7DF1 /* icon_star-hollow@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DABD382B1711E29600CF925C /* icon_star-hollow@2x.png */; };
|
||||
DA2C3D611BD95EEE001137B3 /* Fabric.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA2C3D601BD95EEE001137B3 /* Fabric.framework */; };
|
||||
DA2C3D631BD96126001137B3 /* libc++.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = DA2C3D621BD96126001137B3 /* libc++.tbd */; };
|
||||
DA2C3D651BD9612F001137B3 /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = DA2C3D641BD9612F001137B3 /* libz.tbd */; };
|
||||
DA2CA4DD18D28859007798F8 /* NSArray+Pearl.m in Sources */ = {isa = PBXBuildFile; fileRef = DA2CA4D918D28859007798F8 /* NSArray+Pearl.m */; };
|
||||
@ -165,7 +166,6 @@
|
||||
DA45224A190628A1008F650A /* icon_wrench@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DABD386B1711E29700CF925C /* icon_wrench@2x.png */; };
|
||||
DA45224B190628B2008F650A /* icon_gear.png in Resources */ = {isa = PBXBuildFile; fileRef = DABD37821711E29500CF925C /* icon_gear.png */; };
|
||||
DA45224C190628B2008F650A /* icon_gear@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DABD37831711E29500CF925C /* icon_gear@2x.png */; };
|
||||
DA48856019A5A82E000C2D79 /* Crashlytics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DAA141191922FED80032B392 /* Crashlytics.framework */; };
|
||||
DA4DA1D91564471A00F6F596 /* libjrswizzle.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DAC6326C148680650075AEA5 /* libjrswizzle.a */; };
|
||||
DA4DA1DA1564471F00F6F596 /* libuicolor-utilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DAC6325D1486805C0075AEA5 /* libuicolor-utilities.a */; };
|
||||
DA5A09DF171A70E4005284AB /* play.png in Resources */ = {isa = PBXBuildFile; fileRef = DA5A09DD171A70E4005284AB /* play.png */; };
|
||||
@ -335,7 +335,6 @@
|
||||
DAC77CAE148291A600BCF976 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA5BFA4A147E415C00F98B1E /* Foundation.framework */; };
|
||||
DAC8DF47192831E100BA7D71 /* icon_key.png in Resources */ = {isa = PBXBuildFile; fileRef = DABD379A1711E29600CF925C /* icon_key.png */; };
|
||||
DAC8DF48192831E100BA7D71 /* icon_key@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DABD379B1711E29600CF925C /* icon_key@2x.png */; };
|
||||
DACA296F1705DF81002C6C22 /* Crashlytics.plist in Resources */ = {isa = PBXBuildFile; fileRef = DACA269A1705DF81002C6C22 /* Crashlytics.plist */; };
|
||||
DACA29731705E1A8002C6C22 /* ciphers.plist in Resources */ = {isa = PBXBuildFile; fileRef = DACA29711705E1A8002C6C22 /* ciphers.plist */; };
|
||||
DACA29741705E1A8002C6C22 /* dictionary.lst in Resources */ = {isa = PBXBuildFile; fileRef = DACA29721705E1A8002C6C22 /* dictionary.lst */; };
|
||||
DACA298D1705E2BD002C6C22 /* JRSwizzle.h in Headers */ = {isa = PBXBuildFile; fileRef = DACA29771705E2BD002C6C22 /* JRSwizzle.h */; };
|
||||
@ -667,6 +666,8 @@
|
||||
DA0CC5261EAB99BA009A8ED9 /* IASKTextView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IASKTextView.m; sourceTree = "<group>"; };
|
||||
DA0CC5271EAB99BA009A8ED9 /* IASKTextViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IASKTextViewCell.h; sourceTree = "<group>"; };
|
||||
DA0CC5281EAB99BA009A8ED9 /* IASKTextViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IASKTextViewCell.m; sourceTree = "<group>"; };
|
||||
DA0CC53A1EB57B5C009A8ED9 /* Fabric.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Fabric.plist; sourceTree = "<group>"; };
|
||||
DA0CC53F1EB57B91009A8ED9 /* Fabric.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Fabric.framework; sourceTree = "<group>"; };
|
||||
DA24EBB219DAD4D000FF010B /* Icon-60.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-60.png"; sourceTree = "<group>"; };
|
||||
DA24EBB319DAD4D000FF010B /* Icon-60@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-60@2x.png"; sourceTree = "<group>"; };
|
||||
DA24EBB419DAD4D000FF010B /* Icon-60@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-60@3x.png"; sourceTree = "<group>"; };
|
||||
@ -1496,7 +1497,6 @@
|
||||
DAC632871486D95D0075AEA5 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; };
|
||||
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; name = "Pearl-Prefix.pch"; path = "../../Source/Pearl/Pearl-Prefix.pch"; sourceTree = "<group>"; };
|
||||
DACA269A1705DF81002C6C22 /* Crashlytics.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Crashlytics.plist; sourceTree = "<group>"; };
|
||||
DACA29711705E1A8002C6C22 /* ciphers.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = ciphers.plist; sourceTree = "<group>"; };
|
||||
DACA29721705E1A8002C6C22 /* dictionary.lst */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = dictionary.lst; sourceTree = "<group>"; };
|
||||
DACA29771705E2BD002C6C22 /* JRSwizzle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JRSwizzle.h; sourceTree = "<group>"; };
|
||||
@ -1623,6 +1623,7 @@
|
||||
DA2C3D651BD9612F001137B3 /* libz.tbd in Frameworks */,
|
||||
DA2C3D631BD96126001137B3 /* libc++.tbd in Frameworks */,
|
||||
DAA1761B19D86D0D0044227B /* libAttributedMarkdown.a in Frameworks */,
|
||||
DA0CC5421EB57BD4009A8ED9 /* Crashlytics.framework in Frameworks */,
|
||||
DA32D03E19D11293004F3F0E /* libKCOrderedAccessorFix.a in Frameworks */,
|
||||
DA04E33E14B1E70400ECA4F3 /* MobileCoreServices.framework in Frameworks */,
|
||||
DAE2725A19C93B8E007C5262 /* StoreKit.framework in Frameworks */,
|
||||
@ -1634,15 +1635,13 @@
|
||||
DA672D3014F9413D004A189C /* libPearl.a in Frameworks */,
|
||||
DAEBC45314F6364500987BF6 /* QuartzCore.framework in Frameworks */,
|
||||
DA95D5F214DF0B2C008D1B94 /* MessageUI.framework in Frameworks */,
|
||||
DA48856019A5A82E000C2D79 /* Crashlytics.framework in Frameworks */,
|
||||
DAC632891486D9690075AEA5 /* Security.framework in Frameworks */,
|
||||
DA5BFA49147E415C00F98B1E /* UIKit.framework in Frameworks */,
|
||||
DA0979171E9A81EE00F0BFE8 /* libsodium.a in Frameworks */,
|
||||
DA5BFA4B147E415C00F98B1E /* Foundation.framework in Frameworks */,
|
||||
DA5BFA4D147E415C00F98B1E /* CoreGraphics.framework in Frameworks */,
|
||||
DA5BFA4F147E415C00F98B1E /* CoreData.framework in Frameworks */,
|
||||
93D399433EA75E50656040CB /* Twitter.framework in Frameworks */,
|
||||
DA2C3D611BD95EEE001137B3 /* Fabric.framework in Frameworks */,
|
||||
DA0CC5411EB57BD4009A8ED9 /* Fabric.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@ -1861,6 +1860,14 @@
|
||||
path = Views;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
DA0CC5391EB57B5C009A8ED9 /* Fabric */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
DA0CC53A1EB57B5C009A8ED9 /* Fabric.plist */,
|
||||
);
|
||||
path = Fabric;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
DA24EBB019DAD4D000FF010B /* ios */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -2022,6 +2029,7 @@
|
||||
DAA141181922FED80032B392 /* iOS */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
DA0CC53F1EB57B91009A8ED9 /* Fabric.framework */,
|
||||
DAA141191922FED80032B392 /* Crashlytics.framework */,
|
||||
);
|
||||
path = iOS;
|
||||
@ -2908,7 +2916,7 @@
|
||||
DACA23B41705DF7D002C6C22 /* Resources */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
DACA26991705DF81002C6C22 /* Crashlytics */,
|
||||
DA0CC5391EB57B5C009A8ED9 /* Fabric */,
|
||||
DACA29701705E1A8002C6C22 /* Data */,
|
||||
DAE1EF2417E942DE00BC0086 /* Localizable.strings */,
|
||||
DABD360D1711E29400CF925C /* Media */,
|
||||
@ -2916,14 +2924,6 @@
|
||||
path = Resources;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
DACA26991705DF81002C6C22 /* Crashlytics */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
DACA269A1705DF81002C6C22 /* Crashlytics.plist */,
|
||||
);
|
||||
path = Crashlytics;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
DACA29701705E1A8002C6C22 /* Data */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -3287,7 +3287,7 @@
|
||||
DA5BFA41147E415C00F98B1E /* Frameworks */,
|
||||
DA5BFA42147E415C00F98B1E /* Resources */,
|
||||
DA6556E314D55F3000841C99 /* Run Script: GIT version -> Info.plist */,
|
||||
DAD3125D155288AA00A3F9ED /* Run Script: Crashlytics */,
|
||||
DAD3125D155288AA00A3F9ED /* Run Script: Fabric */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
@ -3548,7 +3548,7 @@
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
DAFE4A5A1503982E003ABA7C /* Pearl.strings in Resources */,
|
||||
DACA296F1705DF81002C6C22 /* Crashlytics.plist in Resources */,
|
||||
DA0CC53B1EB57B5C009A8ED9 /* Fabric.plist in Resources */,
|
||||
DACA29731705E1A8002C6C22 /* ciphers.plist in Resources */,
|
||||
DA32D04F19D2F59B004F3F0E /* meter_fuel@2x.png in Resources */,
|
||||
DACA29741705E1A8002C6C22 /* dictionary.lst in Resources */,
|
||||
@ -3778,19 +3778,19 @@
|
||||
shellScript = "exec Scripts/genassets";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
DAD3125D155288AA00A3F9ED /* Run Script: Crashlytics */ = {
|
||||
DAD3125D155288AA00A3F9ED /* Run Script: Fabric */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
name = "Run Script: Crashlytics";
|
||||
name = "Run Script: Fabric";
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = "/bin/bash -e";
|
||||
shellScript = "[[ $DEPLOYMENT_LOCATION != YES ]] && exit\n\napiKey=$(/usr/libexec/PlistBuddy -c \"Print :'API Key'\" Resources/Crashlytics/Crashlytics.plist)\n[[ $apiKey ]] && External/iOS/Crashlytics.framework/run \"$apiKey\"";
|
||||
shellScript = "[[ $DEPLOYMENT_LOCATION != YES ]] && exit\n\napiKey=$(/usr/libexec/PlistBuddy -c \"Print :'API Key'\" Resources/Fabric/Fabric.plist)\n[[ $apiKey ]] && External/iOS/Fabric.framework/run \"$apiKey\"";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
/* End PBXShellScriptBuildPhase section */
|
||||
@ -4147,7 +4147,6 @@
|
||||
);
|
||||
GCC_PREFIX_HEADER = "Source/MasterPassword-Prefix.pch";
|
||||
INFOPLIST_FILE = "Source/iOS/MasterPassword-Info.plist";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
LIBRARY_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)/External/libsodium/libsodium-ios/lib",
|
||||
@ -4263,6 +4262,7 @@
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
"CRASHLYTICS=1",
|
||||
);
|
||||
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
|
||||
GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES;
|
||||
@ -4412,7 +4412,6 @@
|
||||
);
|
||||
GCC_PREFIX_HEADER = "Source/MasterPassword-Prefix.pch";
|
||||
INFOPLIST_FILE = "Source/iOS/MasterPassword-Info.plist";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
LIBRARY_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)/External/libsodium/libsodium-ios/lib",
|
||||
@ -4440,7 +4439,6 @@
|
||||
);
|
||||
GCC_PREFIX_HEADER = "Source/MasterPassword-Prefix.pch";
|
||||
INFOPLIST_FILE = "Source/iOS/MasterPassword-Info.plist";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
LIBRARY_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)/External/libsodium/libsodium-ios/lib",
|
||||
|
@ -27,6 +27,7 @@
|
||||
DA09745B1E99582900F0BFE8 /* mpw-tests.c in Sources */ = {isa = PBXBuildFile; fileRef = DA0974571E99582200F0BFE8 /* mpw-tests.c */; };
|
||||
DA09745E1E99586600F0BFE8 /* libxml2.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = DA09745D1E99586600F0BFE8 /* libxml2.tbd */; };
|
||||
DA0979681E9A834C00F0BFE8 /* libsodium.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DA0979571E9A824700F0BFE8 /* libsodium.a */; };
|
||||
DA0CC53E1EB57B69009A8ED9 /* Fabric.plist in Resources */ = {isa = PBXBuildFile; fileRef = DA0CC53D1EB57B69009A8ED9 /* Fabric.plist */; };
|
||||
DA1000801998A4C6002B873F /* openssl in Headers */ = {isa = PBXBuildFile; fileRef = DAE8E65719867AF500416A0F /* openssl */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
DA16B341170661DB000A0EAB /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA16B340170661DB000A0EAB /* Carbon.framework */; };
|
||||
DA16B342170661E0000A0EAB /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DAC632871486D95D0075AEA5 /* Security.framework */; };
|
||||
@ -148,7 +149,6 @@
|
||||
DACA27381705DF81002C6C22 /* menu-icon.png in Resources */ = {isa = PBXBuildFile; fileRef = DACA24581705DF7D002C6C22 /* menu-icon.png */; };
|
||||
DACA29671705DF81002C6C22 /* SourceCodePro-ExtraLight.otf in Resources */ = {isa = PBXBuildFile; fileRef = DACA268E1705DF81002C6C22 /* SourceCodePro-ExtraLight.otf */; };
|
||||
DACA29681705DF81002C6C22 /* SourceCodePro-Black.otf in Resources */ = {isa = PBXBuildFile; fileRef = DACA268F1705DF81002C6C22 /* SourceCodePro-Black.otf */; };
|
||||
DACA296F1705DF81002C6C22 /* Crashlytics.plist in Resources */ = {isa = PBXBuildFile; fileRef = DACA269A1705DF81002C6C22 /* Crashlytics.plist */; };
|
||||
DACA29731705E1A8002C6C22 /* ciphers.plist in Resources */ = {isa = PBXBuildFile; fileRef = DACA29711705E1A8002C6C22 /* ciphers.plist */; };
|
||||
DACA29741705E1A8002C6C22 /* dictionary.lst in Resources */ = {isa = PBXBuildFile; fileRef = DACA29721705E1A8002C6C22 /* dictionary.lst */; };
|
||||
DACA298D1705E2BD002C6C22 /* JRSwizzle.h in Headers */ = {isa = PBXBuildFile; fileRef = DACA29771705E2BD002C6C22 /* JRSwizzle.h */; };
|
||||
@ -350,6 +350,7 @@
|
||||
DA0979531E9A824700F0BFE8 /* version.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = version.h; sourceTree = "<group>"; };
|
||||
DA0979541E9A824700F0BFE8 /* sodium.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sodium.h; sourceTree = "<group>"; };
|
||||
DA0979571E9A824700F0BFE8 /* libsodium.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libsodium.a; sourceTree = "<group>"; };
|
||||
DA0CC53D1EB57B69009A8ED9 /* Fabric.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Fabric.plist; sourceTree = "<group>"; };
|
||||
DA16B340170661DB000A0EAB /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = System/Library/Frameworks/Carbon.framework; sourceTree = SDKROOT; };
|
||||
DA16B343170661EE000A0EAB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
|
||||
DA2508F019511D3600AC23F1 /* MPPasswordWindowController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MPPasswordWindowController.xib; sourceTree = "<group>"; };
|
||||
@ -911,7 +912,6 @@
|
||||
DACA24581705DF7D002C6C22 /* menu-icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "menu-icon.png"; sourceTree = "<group>"; };
|
||||
DACA268E1705DF81002C6C22 /* SourceCodePro-ExtraLight.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "SourceCodePro-ExtraLight.otf"; sourceTree = "<group>"; };
|
||||
DACA268F1705DF81002C6C22 /* SourceCodePro-Black.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "SourceCodePro-Black.otf"; sourceTree = "<group>"; };
|
||||
DACA269A1705DF81002C6C22 /* Crashlytics.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Crashlytics.plist; sourceTree = "<group>"; };
|
||||
DACA29711705E1A8002C6C22 /* ciphers.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = ciphers.plist; sourceTree = "<group>"; };
|
||||
DACA29721705E1A8002C6C22 /* dictionary.lst */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = dictionary.lst; sourceTree = "<group>"; };
|
||||
DACA29771705E2BD002C6C22 /* JRSwizzle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JRSwizzle.h; sourceTree = "<group>"; };
|
||||
@ -1132,6 +1132,14 @@
|
||||
path = lib;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
DA0CC53C1EB57B69009A8ED9 /* Fabric */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
DA0CC53D1EB57B69009A8ED9 /* Fabric.plist */,
|
||||
);
|
||||
path = Fabric;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
DA2508F819513C1400AC23F1 /* Other Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -1772,8 +1780,8 @@
|
||||
DACA23B41705DF7D002C6C22 /* Resources */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
DA0CC53C1EB57B69009A8ED9 /* Fabric */,
|
||||
DA09745F1E995EB500F0BFE8 /* mpw_tests.xml */,
|
||||
DACA26991705DF81002C6C22 /* Crashlytics */,
|
||||
DACA29701705E1A8002C6C22 /* Data */,
|
||||
DACA23B51705DF7D002C6C22 /* Media */,
|
||||
);
|
||||
@ -1856,14 +1864,6 @@
|
||||
path = Fonts;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
DACA26991705DF81002C6C22 /* Crashlytics */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
DACA269A1705DF81002C6C22 /* Crashlytics.plist */,
|
||||
);
|
||||
path = Crashlytics;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
DACA29701705E1A8002C6C22 /* Data */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -2086,7 +2086,7 @@
|
||||
DA5BFA42147E415C00F98B1E /* Resources */,
|
||||
DAD9B5EE1762CA3A001835F9 /* Copy LoginHelper */,
|
||||
DA6556E314D55F3000841C99 /* Run Script: GIT version -> Info.plist */,
|
||||
DAD3125D155288AA00A3F9ED /* Run Script: Crashlytics */,
|
||||
DAD3125D155288AA00A3F9ED /* Run Script: Fabric */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
@ -2295,13 +2295,13 @@
|
||||
DACA27331705DF81002C6C22 /* avatar-12@2x.png in Resources */,
|
||||
DACA27341705DF81002C6C22 /* avatar-2@2x.png in Resources */,
|
||||
DA60717D195D040500CA98B5 /* icon_gear@2x.png in Resources */,
|
||||
DA0CC53E1EB57B69009A8ED9 /* Fabric.plist in Resources */,
|
||||
DACA27351705DF81002C6C22 /* avatar-11.png in Resources */,
|
||||
DACA27361705DF81002C6C22 /* avatar-0@2x.png in Resources */,
|
||||
DACA27371705DF81002C6C22 /* avatar-10@2x.png in Resources */,
|
||||
DACA27381705DF81002C6C22 /* menu-icon.png in Resources */,
|
||||
DACA29671705DF81002C6C22 /* SourceCodePro-ExtraLight.otf in Resources */,
|
||||
DACA29681705DF81002C6C22 /* SourceCodePro-Black.otf in Resources */,
|
||||
DACA296F1705DF81002C6C22 /* Crashlytics.plist in Resources */,
|
||||
DACA29731705E1A8002C6C22 /* ciphers.plist in Resources */,
|
||||
DACA29741705E1A8002C6C22 /* dictionary.lst in Resources */,
|
||||
DA5E5D081724A667003798D8 /* MasterPassword.entitlements in Resources */,
|
||||
@ -2359,19 +2359,19 @@
|
||||
shellPath = "/bin/sh -e";
|
||||
shellScript = "exec Scripts/updatePlist";
|
||||
};
|
||||
DAD3125D155288AA00A3F9ED /* Run Script: Crashlytics */ = {
|
||||
DAD3125D155288AA00A3F9ED /* Run Script: Fabric */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
name = "Run Script: Crashlytics";
|
||||
name = "Run Script: Fabric";
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = "/bin/sh -e";
|
||||
shellScript = "[[ $DEPLOYMENT_LOCATION != YES ]] && exit\n\napiKey=$(/usr/libexec/PlistBuddy -c \"Print :'API Key'\" Resources/Crashlytics/Crashlytics.plist)\n[[ $apiKey ]] && External/Mac/Fabric.framework/run \"$apiKey\" 410fb41450e3a2e50fa8357682d812ecd3e1846f2141a99bdb9d3a6a981ad69c";
|
||||
shellScript = "[[ $DEPLOYMENT_LOCATION != YES ]] && exit\n\napiKey=$(/usr/libexec/PlistBuddy -c \"Print :'API Key'\" Resources/Fabric/Fabric.plist)\n[[ $apiKey ]] && External/Mac/Fabric.framework/run \"$apiKey\" 410fb41450e3a2e50fa8357682d812ecd3e1846f2141a99bdb9d3a6a981ad69c";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
/* End PBXShellScriptBuildPhase section */
|
||||
|
@ -55,14 +55,14 @@ setSettingWithTitle "Copyright" "$(getPlistWithKey NSHumanReadableCopyright)"
|
||||
|
||||
if [[ $DEPLOYMENT_LOCATION = YES ]]; then
|
||||
# This build is a release. Do some release checks.
|
||||
crashlyticsPlist="$BUILT_PRODUCTS_DIR/$UNLOCALIZED_RESOURCES_FOLDER_PATH/Crashlytics.plist"
|
||||
fabricPlist="$BUILT_PRODUCTS_DIR/$UNLOCALIZED_RESOURCES_FOLDER_PATH/Fabric.plist"
|
||||
passed=1
|
||||
[[ $description != *-dirty ]] || \
|
||||
{ passed=0; err 'ERROR: Cannot release a dirty version, first commit any changes.'; }
|
||||
[[ $build == 0 ]] || \
|
||||
{ passed=0; err 'ERROR: Commit is not tagged for release, first tag accordingly.'; }
|
||||
[[ -r "$crashlyticsPlist" && $(PlistBuddy -c "Print :'API Key'" "$crashlyticsPlist" 2>/dev/null) ]] || \
|
||||
{ passed=0; err 'ERROR: Cannot release: Crashlytics API key is missing.'; }
|
||||
[[ -r "$fabricPlist" && $(PlistBuddy -c "Print :'API Key'" "$fabricPlist" 2>/dev/null) ]] || \
|
||||
{ passed=0; err 'ERROR: Cannot release: Fabric API key is missing.'; }
|
||||
(( passed )) || \
|
||||
{ ftl "Failed to pass release checks. Fix the above errors and re-try. Aborting."; exit 1; }
|
||||
fi
|
||||
|
@ -93,7 +93,7 @@ NSOperationQueue *_mpwQueue = nil;
|
||||
migrationRequest.predicate = [NSPredicate predicateWithFormat:@"version_ < %d AND user == %@", self.version, user];
|
||||
NSArray *migrationSites = [moc executeFetchRequest:migrationRequest error:&error];
|
||||
if (!migrationSites) {
|
||||
err( @"While looking for sites to migrate: %@", [error fullDescription] );
|
||||
MPError( error, @"While looking for sites to migrate." );
|
||||
return NO;
|
||||
}
|
||||
|
||||
|
@ -29,7 +29,7 @@
|
||||
|
||||
@protocol MPInAppDelegate
|
||||
|
||||
- (void)updateWithProducts:(NSArray /* SKProduct */ *)products;
|
||||
- (void)updateWithProducts:(NSDictionary<NSString *, SKProduct *> *)products;
|
||||
- (void)updateWithTransaction:(SKPaymentTransaction *)transaction;
|
||||
|
||||
@end
|
||||
|
@ -23,7 +23,8 @@
|
||||
|
||||
@implementation MPAppDelegate_Shared(InApp)
|
||||
|
||||
PearlAssociatedObjectProperty( NSArray*, Products, products );
|
||||
PearlAssociatedObjectProperty( NSDictionary*, Products, products );
|
||||
|
||||
PearlAssociatedObjectProperty( NSMutableArray*, ProductObservers, productObservers );
|
||||
|
||||
- (void)registerProductsObserver:(id<MPInAppDelegate>)delegate {
|
||||
@ -101,11 +102,25 @@ PearlAssociatedObjectProperty( NSMutableArray*, ProductObservers, productObserve
|
||||
}
|
||||
#endif
|
||||
|
||||
for (SKProduct *product in self.products)
|
||||
for (SKProduct *product in [self.products allValues])
|
||||
if ([product.productIdentifier isEqualToString:productIdentifier]) {
|
||||
SKMutablePayment *payment = [SKMutablePayment paymentWithProduct:product];
|
||||
if (payment) {
|
||||
payment.quantity = quantity;
|
||||
[[self paymentQueue] addPayment:payment];
|
||||
|
||||
if ([[MPConfig get].sendInfo boolValue]) {
|
||||
#ifdef CRASHLYTICS
|
||||
[Answers logAddToCartWithPrice:product.price currency:product.priceLocale.currencyCode itemName:product.localizedTitle
|
||||
itemType:@"InApp" itemId:product.productIdentifier
|
||||
customAttributes:nil];
|
||||
[Answers logStartCheckoutWithPrice:product.price currency:product.priceLocale.currencyCode itemCount:@(quantity)
|
||||
customAttributes:@{
|
||||
@"products": @[ productIdentifier ],
|
||||
}];
|
||||
#endif
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -114,8 +129,13 @@ PearlAssociatedObjectProperty( NSMutableArray*, ProductObservers, productObserve
|
||||
|
||||
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response {
|
||||
|
||||
inf( @"products: %@, invalid: %@", response.products, response.invalidProductIdentifiers );
|
||||
self.products = response.products;
|
||||
if ([response.invalidProductIdentifiers count])
|
||||
inf( @"Invalid products: %@", response.invalidProductIdentifiers );
|
||||
|
||||
NSMutableDictionary *products = [NSMutableDictionary dictionaryWithCapacity:[response.products count]];
|
||||
for (SKProduct *product in response.products)
|
||||
products[product.productIdentifier] = product;
|
||||
self.products = products;
|
||||
|
||||
for (id<MPInAppDelegate> productObserver in self.productObservers)
|
||||
[productObserver updateWithProducts:self.products];
|
||||
@ -123,6 +143,8 @@ PearlAssociatedObjectProperty( NSMutableArray*, ProductObservers, productObserve
|
||||
|
||||
- (void)request:(SKRequest *)request didFailWithError:(NSError *)error {
|
||||
|
||||
MPError( error, @"StoreKit request (%@) failed.", request );
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
[PearlAlert showAlertWithTitle:@"Purchase Failed" message:
|
||||
strf( @"%@\n\n%@", error.localizedDescription,
|
||||
@ -131,7 +153,6 @@ PearlAssociatedObjectProperty( NSMutableArray*, ProductObservers, productObserve
|
||||
cancelTitle:@"OK" otherTitles:nil];
|
||||
#else
|
||||
#endif
|
||||
err( @"StoreKit request (%@) failed: %@", request, [error fullDescription] );
|
||||
}
|
||||
|
||||
- (void)requestDidFinish:(SKRequest *)request {
|
||||
@ -147,21 +168,37 @@ PearlAssociatedObjectProperty( NSMutableArray*, ProductObservers, productObserve
|
||||
dbg( @"transaction updated: %@ -> %d", transaction.payment.productIdentifier, (int)(transaction.transactionState) );
|
||||
switch (transaction.transactionState) {
|
||||
case SKPaymentTransactionStatePurchased: {
|
||||
inf( @"purchased: %@", transaction.payment.productIdentifier );
|
||||
inf( @"Purchased: %@", transaction.payment.productIdentifier );
|
||||
NSMutableDictionary *attributes = [NSMutableDictionary new];
|
||||
|
||||
if ([transaction.payment.productIdentifier isEqualToString:MPProductFuel]) {
|
||||
float currentFuel = [[MPiOSConfig get].developmentFuelRemaining floatValue];
|
||||
float purchasedFuel = transaction.payment.quantity / MP_FUEL_HOURLY_RATE;
|
||||
[MPiOSConfig get].developmentFuelRemaining = @(currentFuel + purchasedFuel);
|
||||
if (![MPiOSConfig get].developmentFuelChecked || currentFuel < DBL_EPSILON)
|
||||
[MPiOSConfig get].developmentFuelChecked = [NSDate date];
|
||||
[attributes addEntriesFromDictionary:@{
|
||||
@"currentFuel" : @(currentFuel),
|
||||
@"purchasedFuel": @(purchasedFuel),
|
||||
}];
|
||||
}
|
||||
|
||||
[[NSUserDefaults standardUserDefaults] setObject:transaction.transactionIdentifier
|
||||
forKey:transaction.payment.productIdentifier];
|
||||
[queue finishTransaction:transaction];
|
||||
|
||||
if ([[MPConfig get].sendInfo boolValue]) {
|
||||
#ifdef CRASHLYTICS
|
||||
SKProduct *product = self.products[transaction.payment.productIdentifier];
|
||||
[Answers logPurchaseWithPrice:product.price currency:product.priceLocale.currencyCode success:@YES
|
||||
itemName:product.localizedTitle itemType:@"InApp" itemId:product.productIdentifier
|
||||
customAttributes:attributes];
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SKPaymentTransactionStateRestored: {
|
||||
inf( @"restored: %@", transaction.payment.productIdentifier );
|
||||
inf( @"Restored: %@", transaction.payment.productIdentifier );
|
||||
[[NSUserDefaults standardUserDefaults] setObject:transaction.transactionIdentifier
|
||||
forKey:transaction.payment.productIdentifier];
|
||||
[queue finishTransaction:transaction];
|
||||
@ -173,6 +210,18 @@ PearlAssociatedObjectProperty( NSMutableArray*, ProductObservers, productObserve
|
||||
case SKPaymentTransactionStateFailed:
|
||||
err( @"Transaction failed: %@, reason: %@", transaction.payment.productIdentifier, [transaction.error fullDescription] );
|
||||
[queue finishTransaction:transaction];
|
||||
|
||||
if ([[MPConfig get].sendInfo boolValue]) {
|
||||
#ifdef CRASHLYTICS
|
||||
SKProduct *product = self.products[transaction.payment.productIdentifier];
|
||||
[Answers logPurchaseWithPrice:product.price currency:product.priceLocale.currencyCode success:@YES
|
||||
itemName:product.localizedTitle itemType:@"InApp" itemId:product.productIdentifier
|
||||
customAttributes:@{
|
||||
@"state" : @"Failed",
|
||||
@"reason": [transaction.error fullDescription],
|
||||
}];
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@ -185,7 +234,7 @@ PearlAssociatedObjectProperty( NSMutableArray*, ProductObservers, productObserve
|
||||
|
||||
- (void)paymentQueue:(SKPaymentQueue *)queue restoreCompletedTransactionsFailedWithError:(NSError *)error {
|
||||
|
||||
err( @"StoreKit restore failed: %@", [error fullDescription] );
|
||||
MPError( error, @"StoreKit restore failed." );
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -16,12 +16,13 @@
|
||||
// LICENSE file. Alternatively, see <http://www.gnu.org/licenses/>.
|
||||
//==============================================================================
|
||||
|
||||
#import <Crashlytics/Answers.h>
|
||||
#import "MPAppDelegate_Key.h"
|
||||
#import "MPAppDelegate_Store.h"
|
||||
|
||||
@interface MPAppDelegate_Shared()
|
||||
|
||||
@property(strong, nonatomic) MPKey *key;
|
||||
@property(strong, atomic) MPKey *key;
|
||||
|
||||
@end
|
||||
|
||||
@ -177,6 +178,14 @@ static NSDictionary *createKeyQuery(MPUserEntity *user, BOOL newItem, MPKeyOrigi
|
||||
else
|
||||
dbg( @"Automatic login failed for user: %@", user.userID );
|
||||
|
||||
if ([[MPConfig get].sendInfo boolValue]) {
|
||||
#ifdef CRASHLYTICS
|
||||
[Answers logLoginWithMethod:password? @"Password": @"Automatic" success:@NO customAttributes:@{
|
||||
@"algorithm": @(user.algorithm.version),
|
||||
}];
|
||||
#endif
|
||||
}
|
||||
|
||||
return NO;
|
||||
}
|
||||
inf( @"Logged in user: %@", user.userID );
|
||||
@ -198,8 +207,11 @@ static NSDictionary *createKeyQuery(MPUserEntity *user, BOOL newItem, MPKeyOrigi
|
||||
@try {
|
||||
if ([[MPConfig get].sendInfo boolValue]) {
|
||||
#ifdef CRASHLYTICS
|
||||
[[Crashlytics sharedInstance] setObjectValue:user.userID forKey:@"username"];
|
||||
[[Crashlytics sharedInstance] setUserName:user.userID];
|
||||
|
||||
[Answers logLoginWithMethod:password? @"Password": @"Automatic" success:@YES customAttributes:@{
|
||||
@"algorithm": @(user.algorithm.version),
|
||||
}];
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -26,9 +26,9 @@
|
||||
|
||||
#endif
|
||||
|
||||
@property(strong, nonatomic, readonly) MPKey *key;
|
||||
@property(strong, nonatomic, readonly) NSManagedObjectID *activeUserOID;
|
||||
@property(strong, nonatomic, readonly) NSPersistentStoreCoordinator *storeCoordinator;
|
||||
@property(strong, atomic, readonly) MPKey *key;
|
||||
@property(strong, atomic, readonly) NSManagedObjectID *activeUserOID;
|
||||
@property(strong, atomic, readonly) NSPersistentStoreCoordinator *storeCoordinator;
|
||||
|
||||
+ (instancetype)get;
|
||||
|
||||
|
@ -23,9 +23,9 @@
|
||||
|
||||
@interface MPAppDelegate_Shared()
|
||||
|
||||
@property(strong, nonatomic) MPKey *key;
|
||||
@property(strong, nonatomic) NSManagedObjectID *activeUserOID;
|
||||
@property(strong, nonatomic) NSPersistentStoreCoordinator *storeCoordinator;
|
||||
@property(strong, atomic) MPKey *key;
|
||||
@property(strong, atomic) NSManagedObjectID *activeUserOID;
|
||||
@property(strong, atomic) NSPersistentStoreCoordinator *storeCoordinator;
|
||||
|
||||
@end
|
||||
|
||||
@ -76,12 +76,13 @@
|
||||
|
||||
NSError *error;
|
||||
if (activeUser.objectID.isTemporaryID && ![activeUser.managedObjectContext obtainPermanentIDsForObjects:@[ activeUser ] error:&error])
|
||||
err( @"Failed to obtain a permanent object ID after setting active user: %@", [error fullDescription] );
|
||||
MPError( error, @"Failed to obtain a permanent object ID after setting active user." );
|
||||
|
||||
self.activeUserOID = activeUser.objectID;
|
||||
}
|
||||
|
||||
- (void)handleCoordinatorError:(NSError *)error {
|
||||
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -237,7 +237,7 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
|
||||
NSURL *localStoreURL = [self localStoreURL];
|
||||
if (![[NSFileManager defaultManager] createDirectoryAtURL:[localStoreURL URLByDeletingLastPathComponent]
|
||||
withIntermediateDirectories:YES attributes:nil error:&error]) {
|
||||
err( @"Couldn't create our application support directory: %@", [error fullDescription] );
|
||||
MPError( error, @"Couldn't create our application support directory." );
|
||||
return;
|
||||
}
|
||||
if (![self.storeCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:[self localStoreURL]
|
||||
@ -246,7 +246,7 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
|
||||
NSInferMappingModelAutomaticallyOption : @YES,
|
||||
STORE_OPTIONS
|
||||
} error:&error]) {
|
||||
err( @"Failed to open store: %@", [error fullDescription] );
|
||||
MPError( error, @"Failed to open store." );
|
||||
self.storeCorrupted = @YES;
|
||||
[self handleCoordinatorError:error];
|
||||
return;
|
||||
@ -255,12 +255,15 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
PearlAddNotificationObserver( UIApplicationWillResignActiveNotification, UIApp, [NSOperationQueue mainQueue],
|
||||
#else
|
||||
PearlAddNotificationObserver( NSApplicationWillResignActiveNotification, NSApp, [NSOperationQueue mainQueue],
|
||||
#endif
|
||||
^(MPAppDelegate_Shared *self, NSNotification *note) {
|
||||
[self.mainManagedObjectContext saveToStore];
|
||||
} );
|
||||
#else
|
||||
PearlAddNotificationObserver( NSApplicationWillResignActiveNotification, NSApp, [NSOperationQueue mainQueue],
|
||||
^(MPAppDelegate_Shared *self, NSNotification *note) {
|
||||
[self.mainManagedObjectContext saveToStore];
|
||||
} );
|
||||
#endif
|
||||
|
||||
// Perform a data sanity check on the newly loaded store to find and fix any issues.
|
||||
if ([[MPConfig get].checkInconsistency boolValue])
|
||||
@ -286,10 +289,10 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
|
||||
NSError *error = nil;
|
||||
for (NSPersistentStore *store in self.storeCoordinator.persistentStores) {
|
||||
if (![self.storeCoordinator removePersistentStore:store error:&error])
|
||||
err( @"Couldn't remove persistence store from coordinator: %@", [error fullDescription] );
|
||||
MPError( error, @"Couldn't remove persistence store from coordinator." );
|
||||
}
|
||||
if (![[NSFileManager defaultManager] removeItemAtURL:self.localStoreURL error:&error])
|
||||
err( @"Couldn't remove persistence store at URL %@: %@", self.localStoreURL, [error fullDescription] );
|
||||
MPError( error, @"Couldn't remove persistence store at URL %@.", self.localStoreURL );
|
||||
|
||||
[self loadStore];
|
||||
}
|
||||
@ -307,7 +310,7 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
|
||||
fetchRequest.entity = entity;
|
||||
NSArray *objects = [context executeFetchRequest:fetchRequest error:&error];
|
||||
if (!objects) {
|
||||
err( @"Failed to fetch %@ objects: %@", entity, [error fullDescription] );
|
||||
MPError( error, @"Failed to fetch %@ objects.", entity );
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -332,7 +335,8 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
|
||||
|
||||
- (void)migrateStore {
|
||||
|
||||
MPStoreMigrationLevel migrationLevel = (signed)[[NSUserDefaults standardUserDefaults] integerForKey:MPMigrationLevelLocalStoreKey];
|
||||
MPStoreMigrationLevel migrationLevel = (MPStoreMigrationLevel)
|
||||
[[NSUserDefaults standardUserDefaults] integerForKey:MPMigrationLevelLocalStoreKey];
|
||||
if (migrationLevel >= MPStoreMigrationLevelCurrent)
|
||||
// Local store up-to-date.
|
||||
return;
|
||||
@ -375,7 +379,7 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
|
||||
if (![NSPersistentStore migrateStore:oldLocalStoreURL withOptions:@{ STORE_OPTIONS }
|
||||
toStore:newLocalStoreURL withOptions:@{ STORE_OPTIONS }
|
||||
model:nil error:&error]) {
|
||||
err( @"Couldn't migrate the old store to the new location: %@", [error fullDescription] );
|
||||
MPError( error, @"Couldn't migrate the old store to the new location." );
|
||||
return NO;
|
||||
}
|
||||
|
||||
@ -422,7 +426,7 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
|
||||
NSInferMappingModelAutomaticallyOption : @YES,
|
||||
STORE_OPTIONS
|
||||
} model:nil error:&error]) {
|
||||
err( @"Couldn't migrate the old store to the new location: %@", [error fullDescription] );
|
||||
MPError( error, @"Couldn't migrate the old store to the new location." );
|
||||
return NO;
|
||||
}
|
||||
|
||||
@ -459,7 +463,7 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
|
||||
|
||||
NSError *error = nil;
|
||||
if (site.objectID.isTemporaryID && ![context obtainPermanentIDsForObjects:@[ site ] error:&error])
|
||||
err( @"Failed to obtain a permanent object ID after creating new site: %@", [error fullDescription] );
|
||||
MPError( error, @"Failed to obtain a permanent object ID after creating new site." );
|
||||
|
||||
[context saveToStore];
|
||||
|
||||
@ -491,7 +495,7 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
|
||||
|
||||
NSError *error = nil;
|
||||
if (![context obtainPermanentIDsForObjects:@[ newSite ] error:&error])
|
||||
err( @"Failed to obtain a permanent object ID after changing object type: %@", [error fullDescription] );
|
||||
MPError( error, @"Failed to obtain a permanent object ID after changing object type." );
|
||||
|
||||
[context deleteObject:site];
|
||||
[context saveToStore];
|
||||
@ -537,7 +541,7 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
|
||||
initWithPattern:@"^#[[:space:]]*([^:]+): (.*)"
|
||||
options:(NSRegularExpressionOptions)0 error:&error];
|
||||
if (error) {
|
||||
err( @"Error loading the header pattern: %@", [error fullDescription] );
|
||||
MPError( error, @"Error loading the header pattern." );
|
||||
return MPImportResultInternalError;
|
||||
}
|
||||
}
|
||||
@ -551,7 +555,7 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
|
||||
options:(NSRegularExpressionOptions)0 error:&error]
|
||||
];
|
||||
if (error) {
|
||||
err( @"Error loading the site patterns: %@", [error fullDescription] );
|
||||
MPError( error, @"Error loading the site patterns." );
|
||||
return MPImportResultInternalError;
|
||||
}
|
||||
}
|
||||
@ -610,7 +614,7 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
|
||||
userFetchRequest.predicate = [NSPredicate predicateWithFormat:@"name == %@", importUserName];
|
||||
NSArray *users = [context executeFetchRequest:userFetchRequest error:&error];
|
||||
if (!users) {
|
||||
err( @"While looking for user: %@, error: %@", importUserName, [error fullDescription] );
|
||||
MPError( error, @"While looking for user: %@.", importUserName );
|
||||
return MPImportResultInternalError;
|
||||
}
|
||||
if ([users count] > 1) {
|
||||
@ -694,7 +698,7 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
|
||||
siteFetchRequest.predicate = [NSPredicate predicateWithFormat:@"name == %@ AND user == %@", siteName, user];
|
||||
NSArray *existingSites = [context executeFetchRequest:siteFetchRequest error:&error];
|
||||
if (!existingSites) {
|
||||
err( @"Lookup of existing sites failed for site: %@, user: %@, error: %@", siteName, user.userID, [error fullDescription] );
|
||||
MPError( error, @"Lookup of existing sites failed for site: %@, user: %@.", siteName, user.userID );
|
||||
return MPImportResultInternalError;
|
||||
}
|
||||
if ([existingSites count]) {
|
||||
|
@ -20,7 +20,7 @@
|
||||
[self.defaults registerDefaults:@{
|
||||
NSStringFromSelector( @selector( askForReviews ) ) : @YES,
|
||||
|
||||
NSStringFromSelector( @selector( sendInfo ) ) : @NO,
|
||||
NSStringFromSelector( @selector( sendInfo ) ) : @YES,
|
||||
NSStringFromSelector( @selector( rememberLogin ) ) : @NO,
|
||||
NSStringFromSelector( @selector( hidePasswords ) ) : @NO,
|
||||
NSStringFromSelector( @selector( checkInconsistency ) ): @NO,
|
||||
|
@ -21,11 +21,11 @@
|
||||
@try {
|
||||
NSError *error = nil;
|
||||
if (!(success = [self save:&error]))
|
||||
err( @"While saving: %@", [error fullDescription] );
|
||||
MPError( error, @"While saving." );
|
||||
}
|
||||
@catch (NSException *exception) {
|
||||
success = NO;
|
||||
err( @"While saving: %@", [exception fullDescription] );
|
||||
err( @"While saving.\n%@", [exception fullDescription] );
|
||||
}
|
||||
}];
|
||||
|
||||
|
@ -6,6 +6,9 @@
|
||||
// Copyright (c) 2012 Lyndir. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Crashlytics/Crashlytics.h>
|
||||
#import <Crashlytics/Answers.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
extern NSString *const MPErrorDomain;
|
||||
|
||||
@ -19,4 +22,21 @@ extern NSString *const MPFoundInconsistenciesNotification;
|
||||
|
||||
extern NSString *const MPSitesImportedNotificationUserKey;
|
||||
extern NSString *const MPInconsistenciesFixResultUserKey;
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#ifdef CRASHLYTICS
|
||||
#define MPError(error_, message, ...) ({ \
|
||||
err( message @"%@%@", ##__VA_ARGS__, error_? @"\n": @"", [error_ fullDescription]?: @"" ); \
|
||||
\
|
||||
if ([[MPConfig get].sendInfo boolValue]) { \
|
||||
[[Crashlytics sharedInstance] recordError:error_ withAdditionalUserInfo:@{ \
|
||||
@"location": strf( @"%@:%d %@", @(basename((char *)__FILE__)), __LINE__, NSStringFromSelector(_cmd) ), \
|
||||
}]; \
|
||||
} \
|
||||
})
|
||||
#else
|
||||
#define MPError(error_, ...) ({ \
|
||||
err( message @"%@%@", ##__VA_ARGS__, error_? @"\n": @"", [error_ fullDescription]?: @"" ); \
|
||||
})
|
||||
#endif
|
||||
|
@ -78,7 +78,6 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
|
||||
[[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;
|
||||
@ -272,7 +271,7 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
|
||||
[[[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)
|
||||
return;
|
||||
|
||||
@ -394,9 +393,9 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
|
||||
inManagedObjectContext:moc];
|
||||
newUser.name = name;
|
||||
[moc saveToStore];
|
||||
NSError *error = nil;
|
||||
if (![moc obtainPermanentIDsForObjects:@[ newUser ] error:&error])
|
||||
err( @"Failed to obtain permanent object ID for new user: %@", [error fullDescription] );
|
||||
// NSError *error = nil;
|
||||
// if (![moc obtainPermanentIDsForObjects:@[ newUser ] error:&error])
|
||||
// MPError( error, @"Failed to obtain permanent object ID for new user." );
|
||||
|
||||
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
|
||||
[self updateUsers];
|
||||
@ -516,20 +515,23 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
|
||||
|
||||
NSError *coordinateError = nil;
|
||||
NSString *exportedSites = [self exportSitesRevealPasswords:revealPasswords];
|
||||
[[[NSFileCoordinator alloc] initWithFilePresenter:nil] coordinateWritingItemAtURL:savePanel.URL options:0 error:&coordinateError
|
||||
byAccessor:^(NSURL *newURL) {
|
||||
[[[NSFileCoordinator alloc] initWithFilePresenter:nil] coordinateWritingItemAtURL:savePanel.URL options:0
|
||||
error:&coordinateError byAccessor:
|
||||
^(NSURL *newURL) {
|
||||
NSError *writeError = nil;
|
||||
if (![exportedSites writeToURL:newURL atomically:NO
|
||||
encoding:NSUTF8StringEncoding
|
||||
error:&writeError])
|
||||
if (![exportedSites writeToURL:newURL atomically:NO encoding:NSUTF8StringEncoding error:&writeError])
|
||||
MPError( writeError, @"Could not write to the export file." );
|
||||
|
||||
PearlMainQueue( ^{
|
||||
[[NSAlert alertWithError:writeError] runModal];
|
||||
} );
|
||||
}];
|
||||
if (coordinateError)
|
||||
if (coordinateError) {
|
||||
MPError( coordinateError, @"Write access to the export file could not be obtained." );
|
||||
PearlMainQueue( ^{
|
||||
[[NSAlert alertWithError:coordinateError] runModal];
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
||||
- (void)updateUsers {
|
||||
@ -567,7 +569,7 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
|
||||
fetchRequest.sortDescriptors = @[ [NSSortDescriptor sortDescriptorWithKey:@"lastUsed" ascending:NO] ];
|
||||
NSArray *users = [mainContext executeFetchRequest:fetchRequest error:&error];
|
||||
if (!users)
|
||||
err( @"Failed to load users: %@", [error fullDescription] );
|
||||
MPError( error, @"Failed to load users." );
|
||||
|
||||
if (![users count]) {
|
||||
NSMenuItem *noUsersItem = [self.usersItem.submenu addItemWithTitle:@"No users" action:NULL keyEquivalent:@""];
|
||||
|
@ -555,7 +555,7 @@
|
||||
NSArray *siteResults = [context executeFetchRequest:fetchRequest error:&error];
|
||||
if (!siteResults) {
|
||||
prof_finish( @"executeFetchRequest: %@ // %@", fetchRequest.predicate, [error fullDescription] );
|
||||
err( @"While fetching sites for completion: %@", [error fullDescription] );
|
||||
MPError( error, @"While fetching sites for completion." );
|
||||
return;
|
||||
}
|
||||
prof_rewind( @"executeFetchRequest: %@", fetchRequest.predicate );
|
||||
|
@ -115,7 +115,7 @@
|
||||
NSError *error;
|
||||
MPSiteEntity *entity = (MPSiteEntity *)[moc existingObjectWithID:_entityOID error:&error];
|
||||
if (!entity)
|
||||
err( @"Couldn't retrieve active site: %@", [error fullDescription] );
|
||||
MPError( error, @"Couldn't retrieve active site." );
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
@ -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>
|
||||
|
Loading…
Reference in New Issue
Block a user