Compare commits
19 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f86210f5da | ||
|
|
e96f678236 | ||
|
|
8b9067ab4b | ||
|
|
5af383235a | ||
|
|
25b13dfb22 | ||
|
|
635692ef09 | ||
|
|
e6bab4e504 | ||
|
|
cd6b7e6051 | ||
|
|
b180202e07 | ||
|
|
f83f2af529 | ||
|
|
cf2c30cfe6 | ||
|
|
834e94ebd5 | ||
|
|
6d9be3fdfe | ||
|
|
07e55140ac | ||
|
|
fbbd08790d | ||
|
|
fcaa5d1d8c | ||
|
|
ea5be8efcb | ||
|
|
c8b4933c3d | ||
|
|
981ee171ae |
2
platform-darwin/External/Pearl
vendored
2
platform-darwin/External/Pearl
vendored
Submodule platform-darwin/External/Pearl updated: 5e5eaa1344...af1cf4cba3
@@ -42,12 +42,11 @@
|
|||||||
93D398ECD7D1A0DEDDADF516 /* MPEmergencyViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39ACBA9F4878B6A1CC33B /* MPEmergencyViewController.m */; };
|
93D398ECD7D1A0DEDDADF516 /* MPEmergencyViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39ACBA9F4878B6A1CC33B /* MPEmergencyViewController.m */; };
|
||||||
93D399246DC90F50913A1287 /* UIResponder+PearlFirstResponder.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39A1DDFA09AE2E14D26DC /* UIResponder+PearlFirstResponder.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 */; };
|
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 */; };
|
93D39943D01E70DAC3B0DF76 /* mpw-util.c in Sources */ = {isa = PBXBuildFile; fileRef = 93D396C311C3725870343EE0 /* mpw-util.c */; };
|
||||||
93D399D7E08A142776A74CB8 /* MPOverlayViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D395105935859D71679931 /* MPOverlayViewController.m */; };
|
93D399D7E08A142776A74CB8 /* MPOverlayViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D395105935859D71679931 /* MPOverlayViewController.m */; };
|
||||||
93D399E4BC1E092A8C8B12AE /* NSOrderedSetOrArray.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D39FBF8FCEB4C106272334 /* NSOrderedSetOrArray.h */; };
|
93D399E4BC1E092A8C8B12AE /* NSOrderedSetOrArray.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D39FBF8FCEB4C106272334 /* NSOrderedSetOrArray.h */; };
|
||||||
93D39A27F2506C6FEEF9C588 /* MPAlgorithmV2.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D399A8E3181B442D347CD7 /* MPAlgorithmV2.m */; };
|
93D39A27F2506C6FEEF9C588 /* MPAlgorithmV2.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D399A8E3181B442D347CD7 /* MPAlgorithmV2.m */; };
|
||||||
93D39A53D76CA70786423458 /* UICollectionView+PearlReloadFromArray.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D39246FC21C6E63E35D615 /* UICollectionView+PearlReloadFromArray.h */; };
|
93D39A53D76CA70786423458 /* UICollectionView+PearlReloadItems.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D39246FC21C6E63E35D615 /* UICollectionView+PearlReloadItems.h */; };
|
||||||
93D39A5FF670957C0AF8298D /* MPPasswordCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39DEA995041A13DC9CAF7 /* MPPasswordCell.m */; };
|
93D39A5FF670957C0AF8298D /* MPPasswordCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39DEA995041A13DC9CAF7 /* MPPasswordCell.m */; };
|
||||||
93D39A8EA1C49CE43B63F47B /* PearlUICollectionView.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39D8A953779B35403AF6E /* PearlUICollectionView.m */; };
|
93D39A8EA1C49CE43B63F47B /* PearlUICollectionView.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39D8A953779B35403AF6E /* PearlUICollectionView.m */; };
|
||||||
93D39AA4A0BE66A872CCC02E /* NSPersistentStore+PearlMigration.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D397F4BAFFF7CF3F1B21A4 /* NSPersistentStore+PearlMigration.h */; };
|
93D39AA4A0BE66A872CCC02E /* NSPersistentStore+PearlMigration.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D397F4BAFFF7CF3F1B21A4 /* NSPersistentStore+PearlMigration.h */; };
|
||||||
@@ -58,7 +57,7 @@
|
|||||||
93D39BA1EA3CAAC8A220B4A6 /* MPAppSettingsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D3916C1D8F1427DFBDEBCA /* MPAppSettingsViewController.m */; };
|
93D39BA1EA3CAAC8A220B4A6 /* MPAppSettingsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D3916C1D8F1427DFBDEBCA /* MPAppSettingsViewController.m */; };
|
||||||
93D39BFB5F5F9337F6565DE3 /* UIView+Visible.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D39B7B765546B1F1900CB7 /* UIView+Visible.h */; };
|
93D39BFB5F5F9337F6565DE3 /* UIView+Visible.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D39B7B765546B1F1900CB7 /* UIView+Visible.h */; };
|
||||||
93D39C34FE35830EF5BE1D2A /* NSArray+Indexing.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D396D04E57792A54D437AC /* NSArray+Indexing.h */; };
|
93D39C34FE35830EF5BE1D2A /* NSArray+Indexing.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D396D04E57792A54D437AC /* NSArray+Indexing.h */; };
|
||||||
93D39D47FC623E91FC39D20C /* UICollectionView+PearlReloadFromArray.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D3908DF8EABBD952065DC0 /* UICollectionView+PearlReloadFromArray.m */; };
|
93D39D47FC623E91FC39D20C /* UICollectionView+PearlReloadItems.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D3908DF8EABBD952065DC0 /* UICollectionView+PearlReloadItems.m */; };
|
||||||
93D39D596A2E376D6F6F5DA1 /* MPCombinedViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D393310223DDB35218467A /* MPCombinedViewController.m */; };
|
93D39D596A2E376D6F6F5DA1 /* MPCombinedViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D393310223DDB35218467A /* MPCombinedViewController.m */; };
|
||||||
93D39D8F78978196D6ABDEDE /* MPNavigationController.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39CC01630D0421205C4C4 /* MPNavigationController.m */; };
|
93D39D8F78978196D6ABDEDE /* MPNavigationController.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39CC01630D0421205C4C4 /* MPNavigationController.m */; };
|
||||||
93D39E281E3658B30550CB55 /* NSDictionary+Indexing.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39AA1EE2E1E7B81372240 /* NSDictionary+Indexing.m */; };
|
93D39E281E3658B30550CB55 /* NSDictionary+Indexing.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39AA1EE2E1E7B81372240 /* NSDictionary+Indexing.m */; };
|
||||||
@@ -87,6 +86,20 @@
|
|||||||
DA0CC5361EAB99BA009A8ED9 /* IASKTextField.m in Sources */ = {isa = PBXBuildFile; fileRef = DA0CC5241EAB99BA009A8ED9 /* IASKTextField.m */; };
|
DA0CC5361EAB99BA009A8ED9 /* IASKTextField.m in Sources */ = {isa = PBXBuildFile; fileRef = DA0CC5241EAB99BA009A8ED9 /* IASKTextField.m */; };
|
||||||
DA0CC5371EAB99BA009A8ED9 /* IASKTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = DA0CC5261EAB99BA009A8ED9 /* IASKTextView.m */; };
|
DA0CC5371EAB99BA009A8ED9 /* IASKTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = DA0CC5261EAB99BA009A8ED9 /* IASKTextView.m */; };
|
||||||
DA0CC5381EAB99BA009A8ED9 /* IASKTextViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = DA0CC5281EAB99BA009A8ED9 /* IASKTextViewCell.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 */; };
|
||||||
|
DA0CC54E1EB6AD0E009A8ED9 /* MasterPassword.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = DA0CC5441EB6AD0E009A8ED9 /* MasterPassword.xcdatamodeld */; };
|
||||||
|
DA0CC58C1EB6B030009A8ED9 /* MPGeneratedSiteEntity+CoreDataClass.m in Sources */ = {isa = PBXBuildFile; fileRef = DA0CC5791EB6B030009A8ED9 /* MPGeneratedSiteEntity+CoreDataClass.m */; };
|
||||||
|
DA0CC58D1EB6B030009A8ED9 /* MPGeneratedSiteEntity+CoreDataProperties.m in Sources */ = {isa = PBXBuildFile; fileRef = DA0CC57B1EB6B030009A8ED9 /* MPGeneratedSiteEntity+CoreDataProperties.m */; };
|
||||||
|
DA0CC58E1EB6B030009A8ED9 /* MPSiteQuestionEntity+CoreDataClass.m in Sources */ = {isa = PBXBuildFile; fileRef = DA0CC57D1EB6B030009A8ED9 /* MPSiteQuestionEntity+CoreDataClass.m */; };
|
||||||
|
DA0CC58F1EB6B030009A8ED9 /* MPSiteQuestionEntity+CoreDataProperties.m in Sources */ = {isa = PBXBuildFile; fileRef = DA0CC57F1EB6B030009A8ED9 /* MPSiteQuestionEntity+CoreDataProperties.m */; };
|
||||||
|
DA0CC5901EB6B030009A8ED9 /* MPStoredSiteEntity+CoreDataClass.m in Sources */ = {isa = PBXBuildFile; fileRef = DA0CC5811EB6B030009A8ED9 /* MPStoredSiteEntity+CoreDataClass.m */; };
|
||||||
|
DA0CC5911EB6B030009A8ED9 /* MPStoredSiteEntity+CoreDataProperties.m in Sources */ = {isa = PBXBuildFile; fileRef = DA0CC5831EB6B030009A8ED9 /* MPStoredSiteEntity+CoreDataProperties.m */; };
|
||||||
|
DA0CC5921EB6B030009A8ED9 /* MPUserEntity+CoreDataClass.m in Sources */ = {isa = PBXBuildFile; fileRef = DA0CC5851EB6B030009A8ED9 /* MPUserEntity+CoreDataClass.m */; };
|
||||||
|
DA0CC5931EB6B030009A8ED9 /* MPUserEntity+CoreDataProperties.m in Sources */ = {isa = PBXBuildFile; fileRef = DA0CC5871EB6B030009A8ED9 /* MPUserEntity+CoreDataProperties.m */; };
|
||||||
|
DA0CC5941EB6B030009A8ED9 /* MPSiteEntity+CoreDataClass.m in Sources */ = {isa = PBXBuildFile; fileRef = DA0CC5891EB6B030009A8ED9 /* MPSiteEntity+CoreDataClass.m */; };
|
||||||
|
DA0CC5951EB6B030009A8ED9 /* MPSiteEntity+CoreDataProperties.m in Sources */ = {isa = PBXBuildFile; fileRef = DA0CC58B1EB6B030009A8ED9 /* MPSiteEntity+CoreDataProperties.m */; };
|
||||||
DA24EBAE19DAD08900FF010B /* tip_basic_black_top.png in Resources */ = {isa = PBXBuildFile; fileRef = DABD38941711E29700CF925C /* tip_basic_black_top.png */; };
|
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 */; };
|
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 */; };
|
DA24EBE819DAD6DE00FF010B /* Icon-320.png in Resources */ = {isa = PBXBuildFile; fileRef = DA24EBE619DAD6DE00FF010B /* Icon-320.png */; };
|
||||||
@@ -114,7 +127,6 @@
|
|||||||
DA29993219C9132F00AF7DF1 /* thumb_generated_login@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = DA29993119C9132F00AF7DF1 /* thumb_generated_login@3x.png */; };
|
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 */; };
|
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 */; };
|
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 */; };
|
DA2C3D631BD96126001137B3 /* libc++.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = DA2C3D621BD96126001137B3 /* libc++.tbd */; };
|
||||||
DA2C3D651BD9612F001137B3 /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = DA2C3D641BD9612F001137B3 /* libz.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 */; };
|
DA2CA4DD18D28859007798F8 /* NSArray+Pearl.m in Sources */ = {isa = PBXBuildFile; fileRef = DA2CA4D918D28859007798F8 /* NSArray+Pearl.m */; };
|
||||||
@@ -128,10 +140,6 @@
|
|||||||
DA30E9D415722EF400A68B4C /* Pearl-UIKit.m in Sources */ = {isa = PBXBuildFile; fileRef = DA30E9D315722EF400A68B4C /* Pearl-UIKit.m */; };
|
DA30E9D415722EF400A68B4C /* Pearl-UIKit.m in Sources */ = {isa = PBXBuildFile; fileRef = DA30E9D315722EF400A68B4C /* Pearl-UIKit.m */; };
|
||||||
DA30E9D715723E6900A68B4C /* PearlLazy.h in Headers */ = {isa = PBXBuildFile; fileRef = DA30E9D515723E6900A68B4C /* PearlLazy.h */; };
|
DA30E9D715723E6900A68B4C /* PearlLazy.h in Headers */ = {isa = PBXBuildFile; fileRef = DA30E9D515723E6900A68B4C /* PearlLazy.h */; };
|
||||||
DA30E9D815723E6900A68B4C /* PearlLazy.m in Sources */ = {isa = PBXBuildFile; fileRef = DA30E9D615723E6900A68B4C /* PearlLazy.m */; };
|
DA30E9D815723E6900A68B4C /* PearlLazy.m in Sources */ = {isa = PBXBuildFile; fileRef = DA30E9D615723E6900A68B4C /* PearlLazy.m */; };
|
||||||
DA32CFF019CF1C8F004F3F0E /* MPUserEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = DA32CFE619CF1C8F004F3F0E /* MPUserEntity.m */; };
|
|
||||||
DA32CFF119CF1C8F004F3F0E /* MPStoredSiteEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = DA32CFE819CF1C8F004F3F0E /* MPStoredSiteEntity.m */; };
|
|
||||||
DA32CFF319CF1C8F004F3F0E /* MPSiteEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = DA32CFEC19CF1C8F004F3F0E /* MPSiteEntity.m */; };
|
|
||||||
DA32CFF419CF1C8F004F3F0E /* MPGeneratedSiteEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = DA32CFEE19CF1C8F004F3F0E /* MPGeneratedSiteEntity.m */; };
|
|
||||||
DA32D00919CF5C55004F3F0E /* icon_question.png in Resources */ = {isa = PBXBuildFile; fileRef = DABD37FE1711E29600CF925C /* icon_question.png */; };
|
DA32D00919CF5C55004F3F0E /* icon_question.png in Resources */ = {isa = PBXBuildFile; fileRef = DABD37FE1711E29600CF925C /* icon_question.png */; };
|
||||||
DA32D00A19CF5C55004F3F0E /* icon_question@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DABD37FF1711E29600CF925C /* icon_question@2x.png */; };
|
DA32D00A19CF5C55004F3F0E /* icon_question@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DABD37FF1711E29600CF925C /* icon_question@2x.png */; };
|
||||||
DA32D01A19D046E1004F3F0E /* PearlFixedTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = DA32D01819D046E1004F3F0E /* PearlFixedTableView.m */; };
|
DA32D01A19D046E1004F3F0E /* PearlFixedTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = DA32D01819D046E1004F3F0E /* PearlFixedTableView.m */; };
|
||||||
@@ -149,7 +157,6 @@
|
|||||||
DA32D05019D2F59B004F3F0E /* meter_fuel.png in Resources */ = {isa = PBXBuildFile; fileRef = DA32D04D19D2F59B004F3F0E /* meter_fuel.png */; };
|
DA32D05019D2F59B004F3F0E /* meter_fuel.png in Resources */ = {isa = PBXBuildFile; fileRef = DA32D04D19D2F59B004F3F0E /* meter_fuel.png */; };
|
||||||
DA32D05119D3D107004F3F0E /* icon_meter.png in Resources */ = {isa = PBXBuildFile; fileRef = DABD37BA1711E29600CF925C /* icon_meter.png */; };
|
DA32D05119D3D107004F3F0E /* icon_meter.png in Resources */ = {isa = PBXBuildFile; fileRef = DABD37BA1711E29600CF925C /* icon_meter.png */; };
|
||||||
DA32D05219D3D107004F3F0E /* icon_meter@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DABD37BB1711E29600CF925C /* icon_meter@2x.png */; };
|
DA32D05219D3D107004F3F0E /* icon_meter@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DABD37BB1711E29600CF925C /* icon_meter@2x.png */; };
|
||||||
DA32D05519D741DC004F3F0E /* MPSiteQuestionEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = DA32D05419D741DC004F3F0E /* MPSiteQuestionEntity.m */; };
|
|
||||||
DA32D07A19D7D784004F3F0E /* background@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = DA32D07719D7D784004F3F0E /* background@3x.png */; };
|
DA32D07A19D7D784004F3F0E /* background@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = DA32D07719D7D784004F3F0E /* background@3x.png */; };
|
||||||
DA32D07B19D7D784004F3F0E /* background@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DA32D07819D7D784004F3F0E /* background@2x.png */; };
|
DA32D07B19D7D784004F3F0E /* background@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DA32D07819D7D784004F3F0E /* background@2x.png */; };
|
||||||
DA32D07C19D7D784004F3F0E /* background.png in Resources */ = {isa = PBXBuildFile; fileRef = DA32D07919D7D784004F3F0E /* background.png */; };
|
DA32D07C19D7D784004F3F0E /* background.png in Resources */ = {isa = PBXBuildFile; fileRef = DA32D07919D7D784004F3F0E /* background.png */; };
|
||||||
@@ -165,7 +172,6 @@
|
|||||||
DA45224A190628A1008F650A /* icon_wrench@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DABD386B1711E29700CF925C /* icon_wrench@2x.png */; };
|
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 */; };
|
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 */; };
|
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 */; };
|
DA4DA1D91564471A00F6F596 /* libjrswizzle.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DAC6326C148680650075AEA5 /* libjrswizzle.a */; };
|
||||||
DA4DA1DA1564471F00F6F596 /* libuicolor-utilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DAC6325D1486805C0075AEA5 /* libuicolor-utilities.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 */; };
|
DA5A09DF171A70E4005284AB /* play.png in Resources */ = {isa = PBXBuildFile; fileRef = DA5A09DD171A70E4005284AB /* play.png */; };
|
||||||
@@ -202,7 +208,6 @@
|
|||||||
DA945C8717E3F3FD0053236B /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DA945C8617E3F3FD0053236B /* Images.xcassets */; };
|
DA945C8717E3F3FD0053236B /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DA945C8617E3F3FD0053236B /* Images.xcassets */; };
|
||||||
DA95B50C1C476B6A0067F5EF /* LocalAuthentication.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA95B50B1C476B6A0067F5EF /* LocalAuthentication.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
|
DA95B50C1C476B6A0067F5EF /* LocalAuthentication.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA95B50B1C476B6A0067F5EF /* LocalAuthentication.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
|
||||||
DA95B50F1C4776F00067F5EF /* NSMutableSet+Pearl.m in Sources */ = {isa = PBXBuildFile; fileRef = DA95B50E1C4776F00067F5EF /* NSMutableSet+Pearl.m */; };
|
DA95B50F1C4776F00067F5EF /* NSMutableSet+Pearl.m in Sources */ = {isa = PBXBuildFile; fileRef = DA95B50E1C4776F00067F5EF /* NSMutableSet+Pearl.m */; };
|
||||||
DA95B5191C477DB50067F5EF /* MasterPassword.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = DA95B5101C477DB50067F5EF /* MasterPassword.xcdatamodeld */; };
|
|
||||||
DA95D5F214DF0B2C008D1B94 /* MessageUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA95D5F014DF0B1E008D1B94 /* MessageUI.framework */; };
|
DA95D5F214DF0B2C008D1B94 /* MessageUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA95D5F014DF0B1E008D1B94 /* MessageUI.framework */; };
|
||||||
DAA141201922FF020032B392 /* PearlTween.m in Sources */ = {isa = PBXBuildFile; fileRef = DAA1411C1922FF020032B392 /* PearlTween.m */; };
|
DAA141201922FF020032B392 /* PearlTween.m in Sources */ = {isa = PBXBuildFile; fileRef = DAA1411C1922FF020032B392 /* PearlTween.m */; };
|
||||||
DAA141211922FF020032B392 /* PearlTween.h in Headers */ = {isa = PBXBuildFile; fileRef = DAA1411D1922FF020032B392 /* PearlTween.h */; };
|
DAA141211922FF020032B392 /* PearlTween.h in Headers */ = {isa = PBXBuildFile; fileRef = DAA1411D1922FF020032B392 /* PearlTween.h */; };
|
||||||
@@ -335,7 +340,6 @@
|
|||||||
DAC77CAE148291A600BCF976 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA5BFA4A147E415C00F98B1E /* Foundation.framework */; };
|
DAC77CAE148291A600BCF976 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA5BFA4A147E415C00F98B1E /* Foundation.framework */; };
|
||||||
DAC8DF47192831E100BA7D71 /* icon_key.png in Resources */ = {isa = PBXBuildFile; fileRef = DABD379A1711E29600CF925C /* icon_key.png */; };
|
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 */; };
|
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 */; };
|
DACA29731705E1A8002C6C22 /* ciphers.plist in Resources */ = {isa = PBXBuildFile; fileRef = DACA29711705E1A8002C6C22 /* ciphers.plist */; };
|
||||||
DACA29741705E1A8002C6C22 /* dictionary.lst in Resources */ = {isa = PBXBuildFile; fileRef = DACA29721705E1A8002C6C22 /* dictionary.lst */; };
|
DACA29741705E1A8002C6C22 /* dictionary.lst in Resources */ = {isa = PBXBuildFile; fileRef = DACA29721705E1A8002C6C22 /* dictionary.lst */; };
|
||||||
DACA298D1705E2BD002C6C22 /* JRSwizzle.h in Headers */ = {isa = PBXBuildFile; fileRef = DACA29771705E2BD002C6C22 /* JRSwizzle.h */; };
|
DACA298D1705E2BD002C6C22 /* JRSwizzle.h in Headers */ = {isa = PBXBuildFile; fileRef = DACA29771705E2BD002C6C22 /* JRSwizzle.h */; };
|
||||||
@@ -466,7 +470,7 @@
|
|||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
93D390519405B76CC6A57C4F /* MPCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPCell.h; sourceTree = "<group>"; };
|
93D390519405B76CC6A57C4F /* MPCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPCell.h; sourceTree = "<group>"; };
|
||||||
93D39067C0AFDC581794E2B8 /* NSArray+Indexing.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSArray+Indexing.m"; sourceTree = "<group>"; };
|
93D39067C0AFDC581794E2B8 /* NSArray+Indexing.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSArray+Indexing.m"; sourceTree = "<group>"; };
|
||||||
93D3908DF8EABBD952065DC0 /* UICollectionView+PearlReloadFromArray.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UICollectionView+PearlReloadFromArray.m"; sourceTree = "<group>"; };
|
93D3908DF8EABBD952065DC0 /* UICollectionView+PearlReloadItems.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UICollectionView+PearlReloadItems.m"; sourceTree = "<group>"; };
|
||||||
93D390A3B351FEF1B9EDAB56 /* mpw-algorithm_v2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "mpw-algorithm_v2.c"; sourceTree = "<group>"; };
|
93D390A3B351FEF1B9EDAB56 /* mpw-algorithm_v2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "mpw-algorithm_v2.c"; sourceTree = "<group>"; };
|
||||||
93D390A99850139D0FF0211E /* mpw-algorithm_v0.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "mpw-algorithm_v0.c"; sourceTree = "<group>"; };
|
93D390A99850139D0FF0211E /* mpw-algorithm_v0.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "mpw-algorithm_v0.c"; sourceTree = "<group>"; };
|
||||||
93D390FADEB325D8D54A957D /* PearlOverlay.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PearlOverlay.m; sourceTree = "<group>"; };
|
93D390FADEB325D8D54A957D /* PearlOverlay.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PearlOverlay.m; sourceTree = "<group>"; };
|
||||||
@@ -477,7 +481,7 @@
|
|||||||
93D3916C1D8F1427DFBDEBCA /* MPAppSettingsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPAppSettingsViewController.m; sourceTree = "<group>"; };
|
93D3916C1D8F1427DFBDEBCA /* MPAppSettingsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPAppSettingsViewController.m; sourceTree = "<group>"; };
|
||||||
93D391943675426839501BB8 /* MPLogsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPLogsViewController.h; sourceTree = "<group>"; };
|
93D391943675426839501BB8 /* MPLogsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPLogsViewController.h; sourceTree = "<group>"; };
|
||||||
93D391AA32F24290C424438E /* NSNotificationCenter+PearlEasyCleanup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSNotificationCenter+PearlEasyCleanup.h"; sourceTree = "<group>"; };
|
93D391AA32F24290C424438E /* NSNotificationCenter+PearlEasyCleanup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSNotificationCenter+PearlEasyCleanup.h"; sourceTree = "<group>"; };
|
||||||
93D39246FC21C6E63E35D615 /* UICollectionView+PearlReloadFromArray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UICollectionView+PearlReloadFromArray.h"; sourceTree = "<group>"; };
|
93D39246FC21C6E63E35D615 /* UICollectionView+PearlReloadItems.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UICollectionView+PearlReloadItems.h"; sourceTree = "<group>"; };
|
||||||
93D3924D6F77E6BF41AC32D3 /* MPRootSegue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPRootSegue.h; sourceTree = "<group>"; };
|
93D3924D6F77E6BF41AC32D3 /* MPRootSegue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPRootSegue.h; sourceTree = "<group>"; };
|
||||||
93D3924EE15017F8A12CB436 /* MPPasswordsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPPasswordsViewController.m; sourceTree = "<group>"; };
|
93D3924EE15017F8A12CB436 /* MPPasswordsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPPasswordsViewController.m; sourceTree = "<group>"; };
|
||||||
93D392876BE5C011DE73B43F /* MPPopdownSegue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPPopdownSegue.h; sourceTree = "<group>"; };
|
93D392876BE5C011DE73B43F /* MPPopdownSegue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPPopdownSegue.h; sourceTree = "<group>"; };
|
||||||
@@ -667,6 +671,37 @@
|
|||||||
DA0CC5261EAB99BA009A8ED9 /* IASKTextView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IASKTextView.m; sourceTree = "<group>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
||||||
|
DA0CC5451EB6AD0E009A8ED9 /* MasterPassword 1.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MasterPassword 1.xcdatamodel"; sourceTree = "<group>"; };
|
||||||
|
DA0CC5461EB6AD0E009A8ED9 /* MasterPassword 2.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MasterPassword 2.xcdatamodel"; sourceTree = "<group>"; };
|
||||||
|
DA0CC5471EB6AD0E009A8ED9 /* MasterPassword 3.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MasterPassword 3.xcdatamodel"; sourceTree = "<group>"; };
|
||||||
|
DA0CC5481EB6AD0E009A8ED9 /* MasterPassword 4.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MasterPassword 4.xcdatamodel"; sourceTree = "<group>"; };
|
||||||
|
DA0CC5491EB6AD0E009A8ED9 /* MasterPassword 5.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MasterPassword 5.xcdatamodel"; sourceTree = "<group>"; };
|
||||||
|
DA0CC54A1EB6AD0E009A8ED9 /* MasterPassword 6.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MasterPassword 6.xcdatamodel"; sourceTree = "<group>"; };
|
||||||
|
DA0CC54B1EB6AD0E009A8ED9 /* MasterPassword 7.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MasterPassword 7.xcdatamodel"; sourceTree = "<group>"; };
|
||||||
|
DA0CC54C1EB6AD0E009A8ED9 /* MasterPassword 8.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MasterPassword 8.xcdatamodel"; sourceTree = "<group>"; };
|
||||||
|
DA0CC54D1EB6AD0E009A8ED9 /* MasterPassword 9.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MasterPassword 9.xcdatamodel"; sourceTree = "<group>"; };
|
||||||
|
DA0CC5781EB6B030009A8ED9 /* MPGeneratedSiteEntity+CoreDataClass.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MPGeneratedSiteEntity+CoreDataClass.h"; sourceTree = "<group>"; };
|
||||||
|
DA0CC5791EB6B030009A8ED9 /* MPGeneratedSiteEntity+CoreDataClass.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MPGeneratedSiteEntity+CoreDataClass.m"; sourceTree = "<group>"; };
|
||||||
|
DA0CC57A1EB6B030009A8ED9 /* MPGeneratedSiteEntity+CoreDataProperties.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MPGeneratedSiteEntity+CoreDataProperties.h"; sourceTree = "<group>"; };
|
||||||
|
DA0CC57B1EB6B030009A8ED9 /* MPGeneratedSiteEntity+CoreDataProperties.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MPGeneratedSiteEntity+CoreDataProperties.m"; sourceTree = "<group>"; };
|
||||||
|
DA0CC57C1EB6B030009A8ED9 /* MPSiteQuestionEntity+CoreDataClass.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MPSiteQuestionEntity+CoreDataClass.h"; sourceTree = "<group>"; };
|
||||||
|
DA0CC57D1EB6B030009A8ED9 /* MPSiteQuestionEntity+CoreDataClass.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MPSiteQuestionEntity+CoreDataClass.m"; sourceTree = "<group>"; };
|
||||||
|
DA0CC57E1EB6B030009A8ED9 /* MPSiteQuestionEntity+CoreDataProperties.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MPSiteQuestionEntity+CoreDataProperties.h"; sourceTree = "<group>"; };
|
||||||
|
DA0CC57F1EB6B030009A8ED9 /* MPSiteQuestionEntity+CoreDataProperties.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MPSiteQuestionEntity+CoreDataProperties.m"; sourceTree = "<group>"; };
|
||||||
|
DA0CC5801EB6B030009A8ED9 /* MPStoredSiteEntity+CoreDataClass.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MPStoredSiteEntity+CoreDataClass.h"; sourceTree = "<group>"; };
|
||||||
|
DA0CC5811EB6B030009A8ED9 /* MPStoredSiteEntity+CoreDataClass.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MPStoredSiteEntity+CoreDataClass.m"; sourceTree = "<group>"; };
|
||||||
|
DA0CC5821EB6B030009A8ED9 /* MPStoredSiteEntity+CoreDataProperties.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MPStoredSiteEntity+CoreDataProperties.h"; sourceTree = "<group>"; };
|
||||||
|
DA0CC5831EB6B030009A8ED9 /* MPStoredSiteEntity+CoreDataProperties.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MPStoredSiteEntity+CoreDataProperties.m"; sourceTree = "<group>"; };
|
||||||
|
DA0CC5841EB6B030009A8ED9 /* MPUserEntity+CoreDataClass.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MPUserEntity+CoreDataClass.h"; sourceTree = "<group>"; };
|
||||||
|
DA0CC5851EB6B030009A8ED9 /* MPUserEntity+CoreDataClass.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MPUserEntity+CoreDataClass.m"; sourceTree = "<group>"; };
|
||||||
|
DA0CC5861EB6B030009A8ED9 /* MPUserEntity+CoreDataProperties.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MPUserEntity+CoreDataProperties.h"; sourceTree = "<group>"; };
|
||||||
|
DA0CC5871EB6B030009A8ED9 /* MPUserEntity+CoreDataProperties.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MPUserEntity+CoreDataProperties.m"; sourceTree = "<group>"; };
|
||||||
|
DA0CC5881EB6B030009A8ED9 /* MPSiteEntity+CoreDataClass.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MPSiteEntity+CoreDataClass.h"; sourceTree = "<group>"; };
|
||||||
|
DA0CC5891EB6B030009A8ED9 /* MPSiteEntity+CoreDataClass.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MPSiteEntity+CoreDataClass.m"; sourceTree = "<group>"; };
|
||||||
|
DA0CC58A1EB6B030009A8ED9 /* MPSiteEntity+CoreDataProperties.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MPSiteEntity+CoreDataProperties.h"; sourceTree = "<group>"; };
|
||||||
|
DA0CC58B1EB6B030009A8ED9 /* MPSiteEntity+CoreDataProperties.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MPSiteEntity+CoreDataProperties.m"; sourceTree = "<group>"; };
|
||||||
DA24EBB219DAD4D000FF010B /* Icon-60.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-60.png"; 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>"; };
|
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>"; };
|
DA24EBB419DAD4D000FF010B /* Icon-60@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-60@3x.png"; sourceTree = "<group>"; };
|
||||||
@@ -715,14 +750,6 @@
|
|||||||
DA30E9D315722EF400A68B4C /* Pearl-UIKit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "Pearl-UIKit.m"; sourceTree = "<group>"; };
|
DA30E9D315722EF400A68B4C /* Pearl-UIKit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "Pearl-UIKit.m"; sourceTree = "<group>"; };
|
||||||
DA30E9D515723E6900A68B4C /* PearlLazy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PearlLazy.h; sourceTree = "<group>"; };
|
DA30E9D515723E6900A68B4C /* PearlLazy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PearlLazy.h; sourceTree = "<group>"; };
|
||||||
DA30E9D615723E6900A68B4C /* PearlLazy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PearlLazy.m; sourceTree = "<group>"; };
|
DA30E9D615723E6900A68B4C /* PearlLazy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PearlLazy.m; sourceTree = "<group>"; };
|
||||||
DA32CFE619CF1C8F004F3F0E /* MPUserEntity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPUserEntity.m; sourceTree = "<group>"; };
|
|
||||||
DA32CFE719CF1C8F004F3F0E /* MPUserEntity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPUserEntity.h; sourceTree = "<group>"; };
|
|
||||||
DA32CFE819CF1C8F004F3F0E /* MPStoredSiteEntity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPStoredSiteEntity.m; sourceTree = "<group>"; };
|
|
||||||
DA32CFE919CF1C8F004F3F0E /* MPStoredSiteEntity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPStoredSiteEntity.h; sourceTree = "<group>"; };
|
|
||||||
DA32CFEC19CF1C8F004F3F0E /* MPSiteEntity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPSiteEntity.m; sourceTree = "<group>"; };
|
|
||||||
DA32CFED19CF1C8F004F3F0E /* MPSiteEntity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPSiteEntity.h; sourceTree = "<group>"; };
|
|
||||||
DA32CFEE19CF1C8F004F3F0E /* MPGeneratedSiteEntity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPGeneratedSiteEntity.m; sourceTree = "<group>"; };
|
|
||||||
DA32CFEF19CF1C8F004F3F0E /* MPGeneratedSiteEntity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPGeneratedSiteEntity.h; sourceTree = "<group>"; };
|
|
||||||
DA32D01819D046E1004F3F0E /* PearlFixedTableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PearlFixedTableView.m; sourceTree = "<group>"; };
|
DA32D01819D046E1004F3F0E /* PearlFixedTableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PearlFixedTableView.m; sourceTree = "<group>"; };
|
||||||
DA32D01919D046E1004F3F0E /* PearlFixedTableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PearlFixedTableView.h; sourceTree = "<group>"; };
|
DA32D01919D046E1004F3F0E /* PearlFixedTableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PearlFixedTableView.h; sourceTree = "<group>"; };
|
||||||
DA32D02019D111C6004F3F0E /* libKCOrderedAccessorFix.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libKCOrderedAccessorFix.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
DA32D02019D111C6004F3F0E /* libKCOrderedAccessorFix.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libKCOrderedAccessorFix.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
@@ -737,8 +764,6 @@
|
|||||||
DA32D04B19D2F59B004F3F0E /* meter_fuel@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "meter_fuel@3x.png"; sourceTree = "<group>"; };
|
DA32D04B19D2F59B004F3F0E /* meter_fuel@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "meter_fuel@3x.png"; sourceTree = "<group>"; };
|
||||||
DA32D04C19D2F59B004F3F0E /* meter_fuel@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "meter_fuel@2x.png"; sourceTree = "<group>"; };
|
DA32D04C19D2F59B004F3F0E /* meter_fuel@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "meter_fuel@2x.png"; sourceTree = "<group>"; };
|
||||||
DA32D04D19D2F59B004F3F0E /* meter_fuel.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = meter_fuel.png; sourceTree = "<group>"; };
|
DA32D04D19D2F59B004F3F0E /* meter_fuel.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = meter_fuel.png; sourceTree = "<group>"; };
|
||||||
DA32D05319D741DC004F3F0E /* MPSiteQuestionEntity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPSiteQuestionEntity.h; sourceTree = "<group>"; };
|
|
||||||
DA32D05419D741DC004F3F0E /* MPSiteQuestionEntity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPSiteQuestionEntity.m; sourceTree = "<group>"; };
|
|
||||||
DA32D07719D7D784004F3F0E /* background@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "background@3x.png"; path = "ios/launch/background@3x.png"; sourceTree = "<group>"; };
|
DA32D07719D7D784004F3F0E /* background@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "background@3x.png"; path = "ios/launch/background@3x.png"; sourceTree = "<group>"; };
|
||||||
DA32D07819D7D784004F3F0E /* background@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "background@2x.png"; path = "ios/launch/background@2x.png"; sourceTree = "<group>"; };
|
DA32D07819D7D784004F3F0E /* background@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "background@2x.png"; path = "ios/launch/background@2x.png"; sourceTree = "<group>"; };
|
||||||
DA32D07919D7D784004F3F0E /* background.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = background.png; path = ios/launch/background.png; sourceTree = "<group>"; };
|
DA32D07919D7D784004F3F0E /* background.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = background.png; path = ios/launch/background.png; sourceTree = "<group>"; };
|
||||||
@@ -775,14 +800,6 @@
|
|||||||
DA95B50B1C476B6A0067F5EF /* LocalAuthentication.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = LocalAuthentication.framework; path = System/Library/Frameworks/LocalAuthentication.framework; sourceTree = SDKROOT; };
|
DA95B50B1C476B6A0067F5EF /* LocalAuthentication.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = LocalAuthentication.framework; path = System/Library/Frameworks/LocalAuthentication.framework; sourceTree = SDKROOT; };
|
||||||
DA95B50D1C4776F00067F5EF /* NSMutableSet+Pearl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSMutableSet+Pearl.h"; sourceTree = "<group>"; };
|
DA95B50D1C4776F00067F5EF /* NSMutableSet+Pearl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSMutableSet+Pearl.h"; sourceTree = "<group>"; };
|
||||||
DA95B50E1C4776F00067F5EF /* NSMutableSet+Pearl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSMutableSet+Pearl.m"; sourceTree = "<group>"; };
|
DA95B50E1C4776F00067F5EF /* NSMutableSet+Pearl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSMutableSet+Pearl.m"; sourceTree = "<group>"; };
|
||||||
DA95B5111C477DB50067F5EF /* MasterPassword 1.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MasterPassword 1.xcdatamodel"; sourceTree = "<group>"; };
|
|
||||||
DA95B5121C477DB50067F5EF /* MasterPassword 2.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MasterPassword 2.xcdatamodel"; sourceTree = "<group>"; };
|
|
||||||
DA95B5131C477DB50067F5EF /* MasterPassword 3.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MasterPassword 3.xcdatamodel"; sourceTree = "<group>"; };
|
|
||||||
DA95B5141C477DB50067F5EF /* MasterPassword 4.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MasterPassword 4.xcdatamodel"; sourceTree = "<group>"; };
|
|
||||||
DA95B5151C477DB50067F5EF /* MasterPassword 5.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MasterPassword 5.xcdatamodel"; sourceTree = "<group>"; };
|
|
||||||
DA95B5161C477DB50067F5EF /* MasterPassword 6.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MasterPassword 6.xcdatamodel"; sourceTree = "<group>"; };
|
|
||||||
DA95B5171C477DB50067F5EF /* MasterPassword 7.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MasterPassword 7.xcdatamodel"; sourceTree = "<group>"; };
|
|
||||||
DA95B5181C477DB50067F5EF /* MasterPassword 8.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MasterPassword 8.xcdatamodel"; sourceTree = "<group>"; };
|
|
||||||
DA95D5F014DF0B1E008D1B94 /* MessageUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MessageUI.framework; path = System/Library/Frameworks/MessageUI.framework; sourceTree = SDKROOT; };
|
DA95D5F014DF0B1E008D1B94 /* MessageUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MessageUI.framework; path = System/Library/Frameworks/MessageUI.framework; sourceTree = SDKROOT; };
|
||||||
DAA141191922FED80032B392 /* Crashlytics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Crashlytics.framework; sourceTree = "<group>"; };
|
DAA141191922FED80032B392 /* Crashlytics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Crashlytics.framework; sourceTree = "<group>"; };
|
||||||
DAA1411C1922FF020032B392 /* PearlTween.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PearlTween.m; sourceTree = "<group>"; };
|
DAA1411C1922FF020032B392 /* PearlTween.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PearlTween.m; sourceTree = "<group>"; };
|
||||||
@@ -1496,7 +1513,6 @@
|
|||||||
DAC632871486D95D0075AEA5 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; };
|
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; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
DACA29771705E2BD002C6C22 /* JRSwizzle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JRSwizzle.h; sourceTree = "<group>"; };
|
||||||
@@ -1623,6 +1639,7 @@
|
|||||||
DA2C3D651BD9612F001137B3 /* libz.tbd in Frameworks */,
|
DA2C3D651BD9612F001137B3 /* libz.tbd in Frameworks */,
|
||||||
DA2C3D631BD96126001137B3 /* libc++.tbd in Frameworks */,
|
DA2C3D631BD96126001137B3 /* libc++.tbd in Frameworks */,
|
||||||
DAA1761B19D86D0D0044227B /* libAttributedMarkdown.a in Frameworks */,
|
DAA1761B19D86D0D0044227B /* libAttributedMarkdown.a in Frameworks */,
|
||||||
|
DA0CC5421EB57BD4009A8ED9 /* Crashlytics.framework in Frameworks */,
|
||||||
DA32D03E19D11293004F3F0E /* libKCOrderedAccessorFix.a in Frameworks */,
|
DA32D03E19D11293004F3F0E /* libKCOrderedAccessorFix.a in Frameworks */,
|
||||||
DA04E33E14B1E70400ECA4F3 /* MobileCoreServices.framework in Frameworks */,
|
DA04E33E14B1E70400ECA4F3 /* MobileCoreServices.framework in Frameworks */,
|
||||||
DAE2725A19C93B8E007C5262 /* StoreKit.framework in Frameworks */,
|
DAE2725A19C93B8E007C5262 /* StoreKit.framework in Frameworks */,
|
||||||
@@ -1634,15 +1651,13 @@
|
|||||||
DA672D3014F9413D004A189C /* libPearl.a in Frameworks */,
|
DA672D3014F9413D004A189C /* libPearl.a in Frameworks */,
|
||||||
DAEBC45314F6364500987BF6 /* QuartzCore.framework in Frameworks */,
|
DAEBC45314F6364500987BF6 /* QuartzCore.framework in Frameworks */,
|
||||||
DA95D5F214DF0B2C008D1B94 /* MessageUI.framework in Frameworks */,
|
DA95D5F214DF0B2C008D1B94 /* MessageUI.framework in Frameworks */,
|
||||||
DA48856019A5A82E000C2D79 /* Crashlytics.framework in Frameworks */,
|
|
||||||
DAC632891486D9690075AEA5 /* Security.framework in Frameworks */,
|
DAC632891486D9690075AEA5 /* Security.framework in Frameworks */,
|
||||||
DA5BFA49147E415C00F98B1E /* UIKit.framework in Frameworks */,
|
DA5BFA49147E415C00F98B1E /* UIKit.framework in Frameworks */,
|
||||||
DA0979171E9A81EE00F0BFE8 /* libsodium.a in Frameworks */,
|
DA0979171E9A81EE00F0BFE8 /* libsodium.a in Frameworks */,
|
||||||
DA5BFA4B147E415C00F98B1E /* Foundation.framework in Frameworks */,
|
DA5BFA4B147E415C00F98B1E /* Foundation.framework in Frameworks */,
|
||||||
DA5BFA4D147E415C00F98B1E /* CoreGraphics.framework in Frameworks */,
|
DA5BFA4D147E415C00F98B1E /* CoreGraphics.framework in Frameworks */,
|
||||||
DA5BFA4F147E415C00F98B1E /* CoreData.framework in Frameworks */,
|
DA5BFA4F147E415C00F98B1E /* CoreData.framework in Frameworks */,
|
||||||
93D399433EA75E50656040CB /* Twitter.framework in Frameworks */,
|
DA0CC5411EB57BD4009A8ED9 /* Fabric.framework in Frameworks */,
|
||||||
DA2C3D611BD95EEE001137B3 /* Fabric.framework in Frameworks */,
|
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
@@ -1861,6 +1876,14 @@
|
|||||||
path = Views;
|
path = Views;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
DA0CC5391EB57B5C009A8ED9 /* Fabric */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
DA0CC53A1EB57B5C009A8ED9 /* Fabric.plist */,
|
||||||
|
);
|
||||||
|
path = Fabric;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
DA24EBB019DAD4D000FF010B /* ios */ = {
|
DA24EBB019DAD4D000FF010B /* ios */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@@ -2022,6 +2045,7 @@
|
|||||||
DAA141181922FED80032B392 /* iOS */ = {
|
DAA141181922FED80032B392 /* iOS */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
DA0CC53F1EB57B91009A8ED9 /* Fabric.framework */,
|
||||||
DAA141191922FED80032B392 /* Crashlytics.framework */,
|
DAA141191922FED80032B392 /* Crashlytics.framework */,
|
||||||
);
|
);
|
||||||
path = iOS;
|
path = iOS;
|
||||||
@@ -2771,7 +2795,7 @@
|
|||||||
children = (
|
children = (
|
||||||
DABD3BD71711E2DC00CF925C /* iOS */,
|
DABD3BD71711E2DC00CF925C /* iOS */,
|
||||||
DA771FE41E6E1595004D7EDE /* MasterPassword-Prefix.pch */,
|
DA771FE41E6E1595004D7EDE /* MasterPassword-Prefix.pch */,
|
||||||
DA95B5101C477DB50067F5EF /* MasterPassword.xcdatamodeld */,
|
DA0CC5441EB6AD0E009A8ED9 /* MasterPassword.xcdatamodeld */,
|
||||||
DABD3BA01711E2DC00CF925C /* MPAlgorithm.h */,
|
DABD3BA01711E2DC00CF925C /* MPAlgorithm.h */,
|
||||||
DABD3BA11711E2DC00CF925C /* MPAlgorithm.m */,
|
DABD3BA11711E2DC00CF925C /* MPAlgorithm.m */,
|
||||||
DABD3BA21711E2DC00CF925C /* MPAlgorithmV0.h */,
|
DABD3BA21711E2DC00CF925C /* MPAlgorithmV0.h */,
|
||||||
@@ -2796,20 +2820,30 @@
|
|||||||
DABD3BB51711E2DC00CF925C /* MPEntities.m */,
|
DABD3BB51711E2DC00CF925C /* MPEntities.m */,
|
||||||
93D399F244BB522A317811BB /* MPFixable.h */,
|
93D399F244BB522A317811BB /* MPFixable.h */,
|
||||||
93D39A813CA9D7E192261ED2 /* MPFixable.m */,
|
93D39A813CA9D7E192261ED2 /* MPFixable.m */,
|
||||||
DA32CFEF19CF1C8F004F3F0E /* MPGeneratedSiteEntity.h */,
|
DA0CC5781EB6B030009A8ED9 /* MPGeneratedSiteEntity+CoreDataClass.h */,
|
||||||
DA32CFEE19CF1C8F004F3F0E /* MPGeneratedSiteEntity.m */,
|
DA0CC5791EB6B030009A8ED9 /* MPGeneratedSiteEntity+CoreDataClass.m */,
|
||||||
|
DA0CC57A1EB6B030009A8ED9 /* MPGeneratedSiteEntity+CoreDataProperties.h */,
|
||||||
|
DA0CC57B1EB6B030009A8ED9 /* MPGeneratedSiteEntity+CoreDataProperties.m */,
|
||||||
DABD3BB61711E2DC00CF925C /* MPKey.h */,
|
DABD3BB61711E2DC00CF925C /* MPKey.h */,
|
||||||
DABD3BB71711E2DC00CF925C /* MPKey.m */,
|
DABD3BB71711E2DC00CF925C /* MPKey.m */,
|
||||||
DA32CFED19CF1C8F004F3F0E /* MPSiteEntity.h */,
|
DA0CC5881EB6B030009A8ED9 /* MPSiteEntity+CoreDataClass.h */,
|
||||||
DA32CFEC19CF1C8F004F3F0E /* MPSiteEntity.m */,
|
DA0CC5891EB6B030009A8ED9 /* MPSiteEntity+CoreDataClass.m */,
|
||||||
DA32D05319D741DC004F3F0E /* MPSiteQuestionEntity.h */,
|
DA0CC58A1EB6B030009A8ED9 /* MPSiteEntity+CoreDataProperties.h */,
|
||||||
DA32D05419D741DC004F3F0E /* MPSiteQuestionEntity.m */,
|
DA0CC58B1EB6B030009A8ED9 /* MPSiteEntity+CoreDataProperties.m */,
|
||||||
DA32CFE919CF1C8F004F3F0E /* MPStoredSiteEntity.h */,
|
DA0CC57C1EB6B030009A8ED9 /* MPSiteQuestionEntity+CoreDataClass.h */,
|
||||||
DA32CFE819CF1C8F004F3F0E /* MPStoredSiteEntity.m */,
|
DA0CC57D1EB6B030009A8ED9 /* MPSiteQuestionEntity+CoreDataClass.m */,
|
||||||
|
DA0CC57E1EB6B030009A8ED9 /* MPSiteQuestionEntity+CoreDataProperties.h */,
|
||||||
|
DA0CC57F1EB6B030009A8ED9 /* MPSiteQuestionEntity+CoreDataProperties.m */,
|
||||||
|
DA0CC5801EB6B030009A8ED9 /* MPStoredSiteEntity+CoreDataClass.h */,
|
||||||
|
DA0CC5811EB6B030009A8ED9 /* MPStoredSiteEntity+CoreDataClass.m */,
|
||||||
|
DA0CC5821EB6B030009A8ED9 /* MPStoredSiteEntity+CoreDataProperties.h */,
|
||||||
|
DA0CC5831EB6B030009A8ED9 /* MPStoredSiteEntity+CoreDataProperties.m */,
|
||||||
DABD3BB81711E2DC00CF925C /* MPTypes.h */,
|
DABD3BB81711E2DC00CF925C /* MPTypes.h */,
|
||||||
93D39D72239990DDAC2D75B0 /* MPTypes.m */,
|
93D39D72239990DDAC2D75B0 /* MPTypes.m */,
|
||||||
DA32CFE719CF1C8F004F3F0E /* MPUserEntity.h */,
|
DA0CC5841EB6B030009A8ED9 /* MPUserEntity+CoreDataClass.h */,
|
||||||
DA32CFE619CF1C8F004F3F0E /* MPUserEntity.m */,
|
DA0CC5851EB6B030009A8ED9 /* MPUserEntity+CoreDataClass.m */,
|
||||||
|
DA0CC5861EB6B030009A8ED9 /* MPUserEntity+CoreDataProperties.h */,
|
||||||
|
DA0CC5871EB6B030009A8ED9 /* MPUserEntity+CoreDataProperties.m */,
|
||||||
93D393CB0B1F4EC8C17CFE43 /* NSString+MPMarkDown.h */,
|
93D393CB0B1F4EC8C17CFE43 /* NSString+MPMarkDown.h */,
|
||||||
93D39C41A27AA42D044D68AE /* NSString+MPMarkDown.m */,
|
93D39C41A27AA42D044D68AE /* NSString+MPMarkDown.m */,
|
||||||
);
|
);
|
||||||
@@ -2908,7 +2942,7 @@
|
|||||||
DACA23B41705DF7D002C6C22 /* Resources */ = {
|
DACA23B41705DF7D002C6C22 /* Resources */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
DACA26991705DF81002C6C22 /* Crashlytics */,
|
DA0CC5391EB57B5C009A8ED9 /* Fabric */,
|
||||||
DACA29701705E1A8002C6C22 /* Data */,
|
DACA29701705E1A8002C6C22 /* Data */,
|
||||||
DAE1EF2417E942DE00BC0086 /* Localizable.strings */,
|
DAE1EF2417E942DE00BC0086 /* Localizable.strings */,
|
||||||
DABD360D1711E29400CF925C /* Media */,
|
DABD360D1711E29400CF925C /* Media */,
|
||||||
@@ -2916,14 +2950,6 @@
|
|||||||
path = Resources;
|
path = Resources;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
DACA26991705DF81002C6C22 /* Crashlytics */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
DACA269A1705DF81002C6C22 /* Crashlytics.plist */,
|
|
||||||
);
|
|
||||||
path = Crashlytics;
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
DACA29701705E1A8002C6C22 /* Data */ = {
|
DACA29701705E1A8002C6C22 /* Data */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@@ -3114,8 +3140,8 @@
|
|||||||
DAFE462515039823003ABA7C /* Resources */,
|
DAFE462515039823003ABA7C /* Resources */,
|
||||||
DA250A16195665A100AC23F1 /* UICollectionReusableView+PearlDequeue.h */,
|
DA250A16195665A100AC23F1 /* UICollectionReusableView+PearlDequeue.h */,
|
||||||
DA250A15195665A100AC23F1 /* UICollectionReusableView+PearlDequeue.m */,
|
DA250A15195665A100AC23F1 /* UICollectionReusableView+PearlDequeue.m */,
|
||||||
93D39246FC21C6E63E35D615 /* UICollectionView+PearlReloadFromArray.h */,
|
93D39246FC21C6E63E35D615 /* UICollectionView+PearlReloadItems.h */,
|
||||||
93D3908DF8EABBD952065DC0 /* UICollectionView+PearlReloadFromArray.m */,
|
93D3908DF8EABBD952065DC0 /* UICollectionView+PearlReloadItems.m */,
|
||||||
DAFE4A63150399FF003ABA83 /* UIControl+PearlBlocks.h */,
|
DAFE4A63150399FF003ABA83 /* UIControl+PearlBlocks.h */,
|
||||||
DAFE4A63150399FF003ABA81 /* UIControl+PearlBlocks.m */,
|
DAFE4A63150399FF003ABA81 /* UIControl+PearlBlocks.m */,
|
||||||
DAFE4A63150399FF003ABA8B /* UIControl+PearlSelect.h */,
|
DAFE4A63150399FF003ABA8B /* UIControl+PearlSelect.h */,
|
||||||
@@ -3249,7 +3275,7 @@
|
|||||||
93D39536EB550E811CCD04BC /* UIResponder+PearlFirstResponder.h in Headers */,
|
93D39536EB550E811CCD04BC /* UIResponder+PearlFirstResponder.h in Headers */,
|
||||||
93D393DB5325820241BA90A7 /* PearlSizedTextView.h in Headers */,
|
93D393DB5325820241BA90A7 /* PearlSizedTextView.h in Headers */,
|
||||||
93D392A8777DC30C11361647 /* UITextView+PearlAttributes.h in Headers */,
|
93D392A8777DC30C11361647 /* UITextView+PearlAttributes.h in Headers */,
|
||||||
93D39A53D76CA70786423458 /* UICollectionView+PearlReloadFromArray.h in Headers */,
|
93D39A53D76CA70786423458 /* UICollectionView+PearlReloadItems.h in Headers */,
|
||||||
93D39AA4A0BE66A872CCC02E /* NSPersistentStore+PearlMigration.h in Headers */,
|
93D39AA4A0BE66A872CCC02E /* NSPersistentStore+PearlMigration.h in Headers */,
|
||||||
93D399E4BC1E092A8C8B12AE /* NSOrderedSetOrArray.h in Headers */,
|
93D399E4BC1E092A8C8B12AE /* NSOrderedSetOrArray.h in Headers */,
|
||||||
93D3959696396A91961C6148 /* UIView+AlphaScale.h in Headers */,
|
93D3959696396A91961C6148 /* UIView+AlphaScale.h in Headers */,
|
||||||
@@ -3287,7 +3313,7 @@
|
|||||||
DA5BFA41147E415C00F98B1E /* Frameworks */,
|
DA5BFA41147E415C00F98B1E /* Frameworks */,
|
||||||
DA5BFA42147E415C00F98B1E /* Resources */,
|
DA5BFA42147E415C00F98B1E /* Resources */,
|
||||||
DA6556E314D55F3000841C99 /* Run Script: GIT version -> Info.plist */,
|
DA6556E314D55F3000841C99 /* Run Script: GIT version -> Info.plist */,
|
||||||
DAD3125D155288AA00A3F9ED /* Run Script: Crashlytics */,
|
DAD3125D155288AA00A3F9ED /* Run Script: Fabric */,
|
||||||
);
|
);
|
||||||
buildRules = (
|
buildRules = (
|
||||||
);
|
);
|
||||||
@@ -3548,7 +3574,7 @@
|
|||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
DAFE4A5A1503982E003ABA7C /* Pearl.strings in Resources */,
|
DAFE4A5A1503982E003ABA7C /* Pearl.strings in Resources */,
|
||||||
DACA296F1705DF81002C6C22 /* Crashlytics.plist in Resources */,
|
DA0CC53B1EB57B5C009A8ED9 /* Fabric.plist in Resources */,
|
||||||
DACA29731705E1A8002C6C22 /* ciphers.plist in Resources */,
|
DACA29731705E1A8002C6C22 /* ciphers.plist in Resources */,
|
||||||
DA32D04F19D2F59B004F3F0E /* meter_fuel@2x.png in Resources */,
|
DA32D04F19D2F59B004F3F0E /* meter_fuel@2x.png in Resources */,
|
||||||
DACA29741705E1A8002C6C22 /* dictionary.lst in Resources */,
|
DACA29741705E1A8002C6C22 /* dictionary.lst in Resources */,
|
||||||
@@ -3778,19 +3804,19 @@
|
|||||||
shellScript = "exec Scripts/genassets";
|
shellScript = "exec Scripts/genassets";
|
||||||
showEnvVarsInLog = 0;
|
showEnvVarsInLog = 0;
|
||||||
};
|
};
|
||||||
DAD3125D155288AA00A3F9ED /* Run Script: Crashlytics */ = {
|
DAD3125D155288AA00A3F9ED /* Run Script: Fabric */ = {
|
||||||
isa = PBXShellScriptBuildPhase;
|
isa = PBXShellScriptBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
);
|
);
|
||||||
inputPaths = (
|
inputPaths = (
|
||||||
);
|
);
|
||||||
name = "Run Script: Crashlytics";
|
name = "Run Script: Fabric";
|
||||||
outputPaths = (
|
outputPaths = (
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
shellPath = "/bin/bash -e";
|
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;
|
showEnvVarsInLog = 0;
|
||||||
};
|
};
|
||||||
/* End PBXShellScriptBuildPhase section */
|
/* End PBXShellScriptBuildPhase section */
|
||||||
@@ -3808,7 +3834,9 @@
|
|||||||
isa = PBXSourcesBuildPhase;
|
isa = PBXSourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
DA0CC5921EB6B030009A8ED9 /* MPUserEntity+CoreDataClass.m in Sources */,
|
||||||
DABD3BFD1711E2DC00CF925C /* MPAlgorithm.m in Sources */,
|
DABD3BFD1711E2DC00CF925C /* MPAlgorithm.m in Sources */,
|
||||||
|
DA0CC5951EB6B030009A8ED9 /* MPSiteEntity+CoreDataProperties.m in Sources */,
|
||||||
DABD3BFE1711E2DC00CF925C /* MPAlgorithmV0.m in Sources */,
|
DABD3BFE1711E2DC00CF925C /* MPAlgorithmV0.m in Sources */,
|
||||||
DABD3BFF1711E2DC00CF925C /* MPAlgorithmV1.m in Sources */,
|
DABD3BFF1711E2DC00CF925C /* MPAlgorithmV1.m in Sources */,
|
||||||
DABD3C001711E2DC00CF925C /* MPAppDelegate_Key.m in Sources */,
|
DABD3C001711E2DC00CF925C /* MPAppDelegate_Key.m in Sources */,
|
||||||
@@ -3816,38 +3844,40 @@
|
|||||||
DABD3C021711E2DC00CF925C /* MPAppDelegate_Store.m in Sources */,
|
DABD3C021711E2DC00CF925C /* MPAppDelegate_Store.m in Sources */,
|
||||||
DABD3C031711E2DC00CF925C /* MPConfig.m in Sources */,
|
DABD3C031711E2DC00CF925C /* MPConfig.m in Sources */,
|
||||||
DABD3C071711E2DC00CF925C /* MPEntities.m in Sources */,
|
DABD3C071711E2DC00CF925C /* MPEntities.m in Sources */,
|
||||||
DA32CFF319CF1C8F004F3F0E /* MPSiteEntity.m in Sources */,
|
|
||||||
DABD3C081711E2DC00CF925C /* MPKey.m in Sources */,
|
DABD3C081711E2DC00CF925C /* MPKey.m in Sources */,
|
||||||
DABD3C151711E2DC00CF925C /* MPiOSAppDelegate.m in Sources */,
|
DABD3C151711E2DC00CF925C /* MPiOSAppDelegate.m in Sources */,
|
||||||
|
DA0CC5941EB6B030009A8ED9 /* MPSiteEntity+CoreDataClass.m in Sources */,
|
||||||
DABD3C1C1711E2DC00CF925C /* MPGuideViewController.m in Sources */,
|
DABD3C1C1711E2DC00CF925C /* MPGuideViewController.m in Sources */,
|
||||||
DABD3C1E1711E2DC00CF925C /* MPPreferencesViewController.m in Sources */,
|
DABD3C1E1711E2DC00CF925C /* MPPreferencesViewController.m in Sources */,
|
||||||
DABD3C1F1711E2DC00CF925C /* MPTypeViewController.m in Sources */,
|
DABD3C1F1711E2DC00CF925C /* MPTypeViewController.m in Sources */,
|
||||||
DABD3C211711E2DC00CF925C /* MPiOSConfig.m in Sources */,
|
DABD3C211711E2DC00CF925C /* MPiOSConfig.m in Sources */,
|
||||||
|
DA0CC5901EB6B030009A8ED9 /* MPStoredSiteEntity+CoreDataClass.m in Sources */,
|
||||||
|
DA0CC58D1EB6B030009A8ED9 /* MPGeneratedSiteEntity+CoreDataProperties.m in Sources */,
|
||||||
DABD3C271711E2DC00CF925C /* main.m in Sources */,
|
DABD3C271711E2DC00CF925C /* main.m in Sources */,
|
||||||
|
DA0CC5931EB6B030009A8ED9 /* MPUserEntity+CoreDataProperties.m in Sources */,
|
||||||
93D39F8A9254177891F38705 /* MPSetupViewController.m in Sources */,
|
93D39F8A9254177891F38705 /* MPSetupViewController.m in Sources */,
|
||||||
DA095E75172F4CD8001C948B /* MPLogsViewController.m in Sources */,
|
DA095E75172F4CD8001C948B /* MPLogsViewController.m in Sources */,
|
||||||
93D39D596A2E376D6F6F5DA1 /* MPCombinedViewController.m in Sources */,
|
93D39D596A2E376D6F6F5DA1 /* MPCombinedViewController.m in Sources */,
|
||||||
DA32CFF419CF1C8F004F3F0E /* MPGeneratedSiteEntity.m in Sources */,
|
|
||||||
93D3957237D303DE2D38C267 /* MPAvatarCell.m in Sources */,
|
93D3957237D303DE2D38C267 /* MPAvatarCell.m in Sources */,
|
||||||
93D39B8F90F58A5D158DDBA3 /* MPPasswordsViewController.m in Sources */,
|
93D39B8F90F58A5D158DDBA3 /* MPPasswordsViewController.m in Sources */,
|
||||||
DA32D05519D741DC004F3F0E /* MPSiteQuestionEntity.m in Sources */,
|
|
||||||
93D3954FCE045A3CC7E804B7 /* MPUsersViewController.m in Sources */,
|
93D3954FCE045A3CC7E804B7 /* MPUsersViewController.m in Sources */,
|
||||||
93D39392DEDA376F93C6C718 /* MPCell.m in Sources */,
|
93D39392DEDA376F93C6C718 /* MPCell.m in Sources */,
|
||||||
|
DA0CC58E1EB6B030009A8ED9 /* MPSiteQuestionEntity+CoreDataClass.m in Sources */,
|
||||||
93D39A5FF670957C0AF8298D /* MPPasswordCell.m in Sources */,
|
93D39A5FF670957C0AF8298D /* MPPasswordCell.m in Sources */,
|
||||||
93D398ECD7D1A0DEDDADF516 /* MPEmergencyViewController.m in Sources */,
|
93D398ECD7D1A0DEDDADF516 /* MPEmergencyViewController.m in Sources */,
|
||||||
DA95B50F1C4776F00067F5EF /* NSMutableSet+Pearl.m in Sources */,
|
DA95B50F1C4776F00067F5EF /* NSMutableSet+Pearl.m in Sources */,
|
||||||
93D394B5036C882B33C71872 /* MPPasswordsSegue.m in Sources */,
|
93D394B5036C882B33C71872 /* MPPasswordsSegue.m in Sources */,
|
||||||
|
DA0CC5911EB6B030009A8ED9 /* MPStoredSiteEntity+CoreDataProperties.m in Sources */,
|
||||||
93D39673DDC085BE72C34D7C /* MPPopdownSegue.m in Sources */,
|
93D39673DDC085BE72C34D7C /* MPPopdownSegue.m in Sources */,
|
||||||
93D39BA1EA3CAAC8A220B4A6 /* MPAppSettingsViewController.m in Sources */,
|
93D39BA1EA3CAAC8A220B4A6 /* MPAppSettingsViewController.m in Sources */,
|
||||||
|
DA0CC58F1EB6B030009A8ED9 /* MPSiteQuestionEntity+CoreDataProperties.m in Sources */,
|
||||||
93D396D8B67DA6522CDBA142 /* MPCoachmarkViewController.m in Sources */,
|
93D396D8B67DA6522CDBA142 /* MPCoachmarkViewController.m in Sources */,
|
||||||
DAADBFE01A68763B00F7A756 /* mpw-algorithm.c in Sources */,
|
DAADBFE01A68763B00F7A756 /* mpw-algorithm.c in Sources */,
|
||||||
DA95B5191C477DB50067F5EF /* MasterPassword.xcdatamodeld in Sources */,
|
DA0CC54E1EB6AD0E009A8ED9 /* MasterPassword.xcdatamodeld in Sources */,
|
||||||
93D39EAA4D064193074D3021 /* MPFixable.m in Sources */,
|
93D39EAA4D064193074D3021 /* MPFixable.m in Sources */,
|
||||||
DA32CFF119CF1C8F004F3F0E /* MPStoredSiteEntity.m in Sources */,
|
|
||||||
93D394982CBD25D46692DD7C /* MPWebViewController.m in Sources */,
|
93D394982CBD25D46692DD7C /* MPWebViewController.m in Sources */,
|
||||||
93D39D8F78978196D6ABDEDE /* MPNavigationController.m in Sources */,
|
93D39D8F78978196D6ABDEDE /* MPNavigationController.m in Sources */,
|
||||||
93D3939661CE37180AF7CD6A /* MPStoreViewController.m in Sources */,
|
93D3939661CE37180AF7CD6A /* MPStoreViewController.m in Sources */,
|
||||||
DA32CFF019CF1C8F004F3F0E /* MPUserEntity.m in Sources */,
|
|
||||||
93D390C1B93F9D3AE37DD0A5 /* MPAnswersViewController.m in Sources */,
|
93D390C1B93F9D3AE37DD0A5 /* MPAnswersViewController.m in Sources */,
|
||||||
93D399D7E08A142776A74CB8 /* MPOverlayViewController.m in Sources */,
|
93D399D7E08A142776A74CB8 /* MPOverlayViewController.m in Sources */,
|
||||||
93D39A27F2506C6FEEF9C588 /* MPAlgorithmV2.m in Sources */,
|
93D39A27F2506C6FEEF9C588 /* MPAlgorithmV2.m in Sources */,
|
||||||
@@ -3857,6 +3887,7 @@
|
|||||||
93D39943D01E70DAC3B0DF76 /* mpw-util.c in Sources */,
|
93D39943D01E70DAC3B0DF76 /* mpw-util.c in Sources */,
|
||||||
93D39577FD8BB0945DB2F0A3 /* MPAlgorithmV3.m in Sources */,
|
93D39577FD8BB0945DB2F0A3 /* MPAlgorithmV3.m in Sources */,
|
||||||
93D39E5F7F6D7F5C0FAD090F /* MPTypes.m in Sources */,
|
93D39E5F7F6D7F5C0FAD090F /* MPTypes.m in Sources */,
|
||||||
|
DA0CC58C1EB6B030009A8ED9 /* MPGeneratedSiteEntity+CoreDataClass.m in Sources */,
|
||||||
DA92614E1BE1A57500369DE5 /* MPAppDelegate_InApp.m in Sources */,
|
DA92614E1BE1A57500369DE5 /* MPAppDelegate_InApp.m in Sources */,
|
||||||
93D39508A6814612A5B3C226 /* MPMessageViewController.m in Sources */,
|
93D39508A6814612A5B3C226 /* MPMessageViewController.m in Sources */,
|
||||||
);
|
);
|
||||||
@@ -3959,7 +3990,7 @@
|
|||||||
DAA141201922FF020032B392 /* PearlTween.m in Sources */,
|
DAA141201922FF020032B392 /* PearlTween.m in Sources */,
|
||||||
93D391ECBD9BD2C64115B5DD /* PearlSizedTextView.m in Sources */,
|
93D391ECBD9BD2C64115B5DD /* PearlSizedTextView.m in Sources */,
|
||||||
93D39E34FD28D24FE3442C48 /* UITextView+PearlAttributes.m in Sources */,
|
93D39E34FD28D24FE3442C48 /* UITextView+PearlAttributes.m in Sources */,
|
||||||
93D39D47FC623E91FC39D20C /* UICollectionView+PearlReloadFromArray.m in Sources */,
|
93D39D47FC623E91FC39D20C /* UICollectionView+PearlReloadItems.m in Sources */,
|
||||||
93D3928D629EA563F9EC4909 /* NSPersistentStore+PearlMigration.m in Sources */,
|
93D3928D629EA563F9EC4909 /* NSPersistentStore+PearlMigration.m in Sources */,
|
||||||
93D392A33CCE85431E910C7B /* NSOrderedSetOrArray.m in Sources */,
|
93D392A33CCE85431E910C7B /* NSOrderedSetOrArray.m in Sources */,
|
||||||
93D393AA69A1193401160418 /* UIView+AlphaScale.m in Sources */,
|
93D393AA69A1193401160418 /* UIView+AlphaScale.m in Sources */,
|
||||||
@@ -4137,6 +4168,7 @@
|
|||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
|
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
|
||||||
CLANG_ENABLE_OBJC_ARC = YES;
|
CLANG_ENABLE_OBJC_ARC = YES;
|
||||||
|
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = NO;
|
||||||
CODE_SIGN_ENTITLEMENTS = Source/iOS/MasterPassword.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Source/iOS/MasterPassword.entitlements;
|
||||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "-";
|
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "-";
|
||||||
COPY_PHASE_STRIP = YES;
|
COPY_PHASE_STRIP = YES;
|
||||||
@@ -4146,8 +4178,9 @@
|
|||||||
"\"$(SRCROOT)/External/iOS\"",
|
"\"$(SRCROOT)/External/iOS\"",
|
||||||
);
|
);
|
||||||
GCC_PREFIX_HEADER = "Source/MasterPassword-Prefix.pch";
|
GCC_PREFIX_HEADER = "Source/MasterPassword-Prefix.pch";
|
||||||
|
GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO;
|
||||||
INFOPLIST_FILE = "Source/iOS/MasterPassword-Info.plist";
|
INFOPLIST_FILE = "Source/iOS/MasterPassword-Info.plist";
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||||
LIBRARY_SEARCH_PATHS = (
|
LIBRARY_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"$(PROJECT_DIR)/External/libsodium/libsodium-ios/lib",
|
"$(PROJECT_DIR)/External/libsodium/libsodium-ios/lib",
|
||||||
@@ -4263,6 +4296,7 @@
|
|||||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||||
"DEBUG=1",
|
"DEBUG=1",
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
|
"CRASHLYTICS=1",
|
||||||
);
|
);
|
||||||
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
|
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
|
||||||
GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES;
|
GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES;
|
||||||
@@ -4404,6 +4438,7 @@
|
|||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
|
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
|
||||||
CLANG_ENABLE_OBJC_ARC = YES;
|
CLANG_ENABLE_OBJC_ARC = YES;
|
||||||
|
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = NO;
|
||||||
CODE_SIGN_ENTITLEMENTS = Source/iOS/MasterPassword.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Source/iOS/MasterPassword.entitlements;
|
||||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||||
FRAMEWORK_SEARCH_PATHS = (
|
FRAMEWORK_SEARCH_PATHS = (
|
||||||
@@ -4411,8 +4446,9 @@
|
|||||||
"\"$(SRCROOT)/External/iOS\"",
|
"\"$(SRCROOT)/External/iOS\"",
|
||||||
);
|
);
|
||||||
GCC_PREFIX_HEADER = "Source/MasterPassword-Prefix.pch";
|
GCC_PREFIX_HEADER = "Source/MasterPassword-Prefix.pch";
|
||||||
|
GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO;
|
||||||
INFOPLIST_FILE = "Source/iOS/MasterPassword-Info.plist";
|
INFOPLIST_FILE = "Source/iOS/MasterPassword-Info.plist";
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||||
LIBRARY_SEARCH_PATHS = (
|
LIBRARY_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"$(PROJECT_DIR)/External/libsodium/libsodium-ios/lib",
|
"$(PROJECT_DIR)/External/libsodium/libsodium-ios/lib",
|
||||||
@@ -4430,6 +4466,7 @@
|
|||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
|
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
|
||||||
CLANG_ENABLE_OBJC_ARC = YES;
|
CLANG_ENABLE_OBJC_ARC = YES;
|
||||||
|
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = NO;
|
||||||
CODE_SIGN_ENTITLEMENTS = Source/iOS/MasterPassword.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Source/iOS/MasterPassword.entitlements;
|
||||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||||
COPY_PHASE_STRIP = YES;
|
COPY_PHASE_STRIP = YES;
|
||||||
@@ -4439,8 +4476,9 @@
|
|||||||
"\"$(SRCROOT)/External/iOS\"",
|
"\"$(SRCROOT)/External/iOS\"",
|
||||||
);
|
);
|
||||||
GCC_PREFIX_HEADER = "Source/MasterPassword-Prefix.pch";
|
GCC_PREFIX_HEADER = "Source/MasterPassword-Prefix.pch";
|
||||||
|
GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO;
|
||||||
INFOPLIST_FILE = "Source/iOS/MasterPassword-Info.plist";
|
INFOPLIST_FILE = "Source/iOS/MasterPassword-Info.plist";
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||||
LIBRARY_SEARCH_PATHS = (
|
LIBRARY_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"$(PROJECT_DIR)/External/libsodium/libsodium-ios/lib",
|
"$(PROJECT_DIR)/External/libsodium/libsodium-ios/lib",
|
||||||
@@ -4627,19 +4665,20 @@
|
|||||||
/* End XCConfigurationList section */
|
/* End XCConfigurationList section */
|
||||||
|
|
||||||
/* Begin XCVersionGroup section */
|
/* Begin XCVersionGroup section */
|
||||||
DA95B5101C477DB50067F5EF /* MasterPassword.xcdatamodeld */ = {
|
DA0CC5441EB6AD0E009A8ED9 /* MasterPassword.xcdatamodeld */ = {
|
||||||
isa = XCVersionGroup;
|
isa = XCVersionGroup;
|
||||||
children = (
|
children = (
|
||||||
DA95B5111C477DB50067F5EF /* MasterPassword 1.xcdatamodel */,
|
DA0CC5451EB6AD0E009A8ED9 /* MasterPassword 1.xcdatamodel */,
|
||||||
DA95B5121C477DB50067F5EF /* MasterPassword 2.xcdatamodel */,
|
DA0CC5461EB6AD0E009A8ED9 /* MasterPassword 2.xcdatamodel */,
|
||||||
DA95B5131C477DB50067F5EF /* MasterPassword 3.xcdatamodel */,
|
DA0CC5471EB6AD0E009A8ED9 /* MasterPassword 3.xcdatamodel */,
|
||||||
DA95B5141C477DB50067F5EF /* MasterPassword 4.xcdatamodel */,
|
DA0CC5481EB6AD0E009A8ED9 /* MasterPassword 4.xcdatamodel */,
|
||||||
DA95B5151C477DB50067F5EF /* MasterPassword 5.xcdatamodel */,
|
DA0CC5491EB6AD0E009A8ED9 /* MasterPassword 5.xcdatamodel */,
|
||||||
DA95B5161C477DB50067F5EF /* MasterPassword 6.xcdatamodel */,
|
DA0CC54A1EB6AD0E009A8ED9 /* MasterPassword 6.xcdatamodel */,
|
||||||
DA95B5171C477DB50067F5EF /* MasterPassword 7.xcdatamodel */,
|
DA0CC54B1EB6AD0E009A8ED9 /* MasterPassword 7.xcdatamodel */,
|
||||||
DA95B5181C477DB50067F5EF /* MasterPassword 8.xcdatamodel */,
|
DA0CC54C1EB6AD0E009A8ED9 /* MasterPassword 8.xcdatamodel */,
|
||||||
|
DA0CC54D1EB6AD0E009A8ED9 /* MasterPassword 9.xcdatamodel */,
|
||||||
);
|
);
|
||||||
currentVersion = DA95B5181C477DB50067F5EF /* MasterPassword 8.xcdatamodel */;
|
currentVersion = DA0CC54D1EB6AD0E009A8ED9 /* MasterPassword 9.xcdatamodel */;
|
||||||
path = MasterPassword.xcdatamodeld;
|
path = MasterPassword.xcdatamodeld;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
versionGroupType = wrapper.xcdatamodel;
|
versionGroupType = wrapper.xcdatamodel;
|
||||||
|
|||||||
@@ -27,6 +27,8 @@
|
|||||||
DA09745B1E99582900F0BFE8 /* mpw-tests.c in Sources */ = {isa = PBXBuildFile; fileRef = DA0974571E99582200F0BFE8 /* mpw-tests.c */; };
|
DA09745B1E99582900F0BFE8 /* mpw-tests.c in Sources */ = {isa = PBXBuildFile; fileRef = DA0974571E99582200F0BFE8 /* mpw-tests.c */; };
|
||||||
DA09745E1E99586600F0BFE8 /* libxml2.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = DA09745D1E99586600F0BFE8 /* libxml2.tbd */; };
|
DA09745E1E99586600F0BFE8 /* libxml2.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = DA09745D1E99586600F0BFE8 /* libxml2.tbd */; };
|
||||||
DA0979681E9A834C00F0BFE8 /* libsodium.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DA0979571E9A824700F0BFE8 /* libsodium.a */; };
|
DA0979681E9A834C00F0BFE8 /* libsodium.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DA0979571E9A824700F0BFE8 /* libsodium.a */; };
|
||||||
|
DA0CC53E1EB57B69009A8ED9 /* Fabric.plist in Resources */ = {isa = PBXBuildFile; fileRef = DA0CC53D1EB57B69009A8ED9 /* Fabric.plist */; };
|
||||||
|
DA0CC5591EB6AE45009A8ED9 /* MasterPassword.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = DA0CC54F1EB6AE45009A8ED9 /* MasterPassword.xcdatamodeld */; };
|
||||||
DA1000801998A4C6002B873F /* openssl in Headers */ = {isa = PBXBuildFile; fileRef = DAE8E65719867AF500416A0F /* openssl */; settings = {ATTRIBUTES = (Public, ); }; };
|
DA1000801998A4C6002B873F /* openssl in Headers */ = {isa = PBXBuildFile; fileRef = DAE8E65719867AF500416A0F /* openssl */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
DA16B341170661DB000A0EAB /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA16B340170661DB000A0EAB /* Carbon.framework */; };
|
DA16B341170661DB000A0EAB /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA16B340170661DB000A0EAB /* Carbon.framework */; };
|
||||||
DA16B342170661E0000A0EAB /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DAC632871486D95D0075AEA5 /* Security.framework */; };
|
DA16B342170661E0000A0EAB /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DAC632871486D95D0075AEA5 /* Security.framework */; };
|
||||||
@@ -96,7 +98,6 @@
|
|||||||
DA9261521BE1A86700369DE5 /* Fabric.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA9261501BE1A86700369DE5 /* Fabric.framework */; };
|
DA9261521BE1A86700369DE5 /* Fabric.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA9261501BE1A86700369DE5 /* Fabric.framework */; };
|
||||||
DA9261541BE1A88900369DE5 /* libc++.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = DA9261531BE1A88900369DE5 /* libc++.tbd */; };
|
DA9261541BE1A88900369DE5 /* libc++.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = DA9261531BE1A88900369DE5 /* libc++.tbd */; };
|
||||||
DA9261561BE1A89600369DE5 /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = DA9261551BE1A89600369DE5 /* libz.tbd */; };
|
DA9261561BE1A89600369DE5 /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = DA9261551BE1A89600369DE5 /* libz.tbd */; };
|
||||||
DA95B5231C477DE10067F5EF /* MasterPassword.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = DA95B51A1C477DE10067F5EF /* MasterPassword.xcdatamodeld */; };
|
|
||||||
DAAA81B0195A8D1300FA30D9 /* gradient.png in Resources */ = {isa = PBXBuildFile; fileRef = DAAA81AF195A8D1300FA30D9 /* gradient.png */; };
|
DAAA81B0195A8D1300FA30D9 /* gradient.png in Resources */ = {isa = PBXBuildFile; fileRef = DAAA81AF195A8D1300FA30D9 /* gradient.png */; };
|
||||||
DAADCC4719FAFFAD00987B1D /* NSNotificationCenter+PearlEasyCleanup.h in Headers */ = {isa = PBXBuildFile; fileRef = DAADCC3E19FAFFAD00987B1D /* NSNotificationCenter+PearlEasyCleanup.h */; };
|
DAADCC4719FAFFAD00987B1D /* NSNotificationCenter+PearlEasyCleanup.h in Headers */ = {isa = PBXBuildFile; fileRef = DAADCC3E19FAFFAD00987B1D /* NSNotificationCenter+PearlEasyCleanup.h */; };
|
||||||
DAADCC4819FAFFAD00987B1D /* NSPersistentStore+PearlMigration.h in Headers */ = {isa = PBXBuildFile; fileRef = DAADCC3F19FAFFAD00987B1D /* NSPersistentStore+PearlMigration.h */; };
|
DAADCC4819FAFFAD00987B1D /* NSPersistentStore+PearlMigration.h in Headers */ = {isa = PBXBuildFile; fileRef = DAADCC3F19FAFFAD00987B1D /* NSPersistentStore+PearlMigration.h */; };
|
||||||
@@ -148,7 +149,6 @@
|
|||||||
DACA27381705DF81002C6C22 /* menu-icon.png in Resources */ = {isa = PBXBuildFile; fileRef = DACA24581705DF7D002C6C22 /* menu-icon.png */; };
|
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 */; };
|
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 */; };
|
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 */; };
|
DACA29731705E1A8002C6C22 /* ciphers.plist in Resources */ = {isa = PBXBuildFile; fileRef = DACA29711705E1A8002C6C22 /* ciphers.plist */; };
|
||||||
DACA29741705E1A8002C6C22 /* dictionary.lst in Resources */ = {isa = PBXBuildFile; fileRef = DACA29721705E1A8002C6C22 /* dictionary.lst */; };
|
DACA29741705E1A8002C6C22 /* dictionary.lst in Resources */ = {isa = PBXBuildFile; fileRef = DACA29721705E1A8002C6C22 /* dictionary.lst */; };
|
||||||
DACA298D1705E2BD002C6C22 /* JRSwizzle.h in Headers */ = {isa = PBXBuildFile; fileRef = DACA29771705E2BD002C6C22 /* JRSwizzle.h */; };
|
DACA298D1705E2BD002C6C22 /* JRSwizzle.h in Headers */ = {isa = PBXBuildFile; fileRef = DACA29771705E2BD002C6C22 /* JRSwizzle.h */; };
|
||||||
@@ -350,6 +350,16 @@
|
|||||||
DA0979531E9A824700F0BFE8 /* version.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = version.h; sourceTree = "<group>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
||||||
|
DA0CC5501EB6AE45009A8ED9 /* MasterPassword 1.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MasterPassword 1.xcdatamodel"; sourceTree = "<group>"; };
|
||||||
|
DA0CC5511EB6AE45009A8ED9 /* MasterPassword 2.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MasterPassword 2.xcdatamodel"; sourceTree = "<group>"; };
|
||||||
|
DA0CC5521EB6AE45009A8ED9 /* MasterPassword 3.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MasterPassword 3.xcdatamodel"; sourceTree = "<group>"; };
|
||||||
|
DA0CC5531EB6AE45009A8ED9 /* MasterPassword 4.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MasterPassword 4.xcdatamodel"; sourceTree = "<group>"; };
|
||||||
|
DA0CC5541EB6AE45009A8ED9 /* MasterPassword 5.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MasterPassword 5.xcdatamodel"; sourceTree = "<group>"; };
|
||||||
|
DA0CC5551EB6AE45009A8ED9 /* MasterPassword 6.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MasterPassword 6.xcdatamodel"; sourceTree = "<group>"; };
|
||||||
|
DA0CC5561EB6AE45009A8ED9 /* MasterPassword 7.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MasterPassword 7.xcdatamodel"; sourceTree = "<group>"; };
|
||||||
|
DA0CC5571EB6AE45009A8ED9 /* MasterPassword 8.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MasterPassword 8.xcdatamodel"; sourceTree = "<group>"; };
|
||||||
|
DA0CC5581EB6AE45009A8ED9 /* MasterPassword 9.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MasterPassword 9.xcdatamodel"; sourceTree = "<group>"; };
|
||||||
DA16B340170661DB000A0EAB /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = System/Library/Frameworks/Carbon.framework; sourceTree = SDKROOT; };
|
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; };
|
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>"; };
|
DA2508F019511D3600AC23F1 /* MPPasswordWindowController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MPPasswordWindowController.xib; sourceTree = "<group>"; };
|
||||||
@@ -849,14 +859,6 @@
|
|||||||
DA9261501BE1A86700369DE5 /* Fabric.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Fabric.framework; sourceTree = "<group>"; };
|
DA9261501BE1A86700369DE5 /* Fabric.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Fabric.framework; sourceTree = "<group>"; };
|
||||||
DA9261531BE1A88900369DE5 /* libc++.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = "libc++.tbd"; path = "usr/lib/libc++.tbd"; sourceTree = SDKROOT; };
|
DA9261531BE1A88900369DE5 /* libc++.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = "libc++.tbd"; path = "usr/lib/libc++.tbd"; sourceTree = SDKROOT; };
|
||||||
DA9261551BE1A89600369DE5 /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; };
|
DA9261551BE1A89600369DE5 /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; };
|
||||||
DA95B51B1C477DE10067F5EF /* MasterPassword 1.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MasterPassword 1.xcdatamodel"; sourceTree = "<group>"; };
|
|
||||||
DA95B51C1C477DE10067F5EF /* MasterPassword 2.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MasterPassword 2.xcdatamodel"; sourceTree = "<group>"; };
|
|
||||||
DA95B51D1C477DE10067F5EF /* MasterPassword 3.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MasterPassword 3.xcdatamodel"; sourceTree = "<group>"; };
|
|
||||||
DA95B51E1C477DE10067F5EF /* MasterPassword 4.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MasterPassword 4.xcdatamodel"; sourceTree = "<group>"; };
|
|
||||||
DA95B51F1C477DE10067F5EF /* MasterPassword 5.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MasterPassword 5.xcdatamodel"; sourceTree = "<group>"; };
|
|
||||||
DA95B5201C477DE10067F5EF /* MasterPassword 6.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MasterPassword 6.xcdatamodel"; sourceTree = "<group>"; };
|
|
||||||
DA95B5211C477DE10067F5EF /* MasterPassword 7.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MasterPassword 7.xcdatamodel"; sourceTree = "<group>"; };
|
|
||||||
DA95B5221C477DE10067F5EF /* MasterPassword 8.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MasterPassword 8.xcdatamodel"; sourceTree = "<group>"; };
|
|
||||||
DAAA81AF195A8D1300FA30D9 /* gradient.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = gradient.png; sourceTree = "<group>"; };
|
DAAA81AF195A8D1300FA30D9 /* gradient.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = gradient.png; sourceTree = "<group>"; };
|
||||||
DAADCC3E19FAFFAD00987B1D /* NSNotificationCenter+PearlEasyCleanup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSNotificationCenter+PearlEasyCleanup.h"; sourceTree = "<group>"; };
|
DAADCC3E19FAFFAD00987B1D /* NSNotificationCenter+PearlEasyCleanup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSNotificationCenter+PearlEasyCleanup.h"; sourceTree = "<group>"; };
|
||||||
DAADCC3F19FAFFAD00987B1D /* NSPersistentStore+PearlMigration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSPersistentStore+PearlMigration.h"; sourceTree = "<group>"; };
|
DAADCC3F19FAFFAD00987B1D /* NSPersistentStore+PearlMigration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSPersistentStore+PearlMigration.h"; sourceTree = "<group>"; };
|
||||||
@@ -911,7 +913,6 @@
|
|||||||
DACA24581705DF7D002C6C22 /* menu-icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "menu-icon.png"; sourceTree = "<group>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
DACA29771705E2BD002C6C22 /* JRSwizzle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JRSwizzle.h; sourceTree = "<group>"; };
|
||||||
@@ -1132,6 +1133,14 @@
|
|||||||
path = lib;
|
path = lib;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
DA0CC53C1EB57B69009A8ED9 /* Fabric */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
DA0CC53D1EB57B69009A8ED9 /* Fabric.plist */,
|
||||||
|
);
|
||||||
|
path = Fabric;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
DA2508F819513C1400AC23F1 /* Other Frameworks */ = {
|
DA2508F819513C1400AC23F1 /* Other Frameworks */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@@ -1212,7 +1221,7 @@
|
|||||||
children = (
|
children = (
|
||||||
DA5E5CB21724A667003798D8 /* Mac */,
|
DA5E5CB21724A667003798D8 /* Mac */,
|
||||||
DA771FE51E6E15A1004D7EDE /* MasterPassword-Prefix.pch */,
|
DA771FE51E6E15A1004D7EDE /* MasterPassword-Prefix.pch */,
|
||||||
DA95B51A1C477DE10067F5EF /* MasterPassword.xcdatamodeld */,
|
DA0CC54F1EB6AE45009A8ED9 /* MasterPassword.xcdatamodeld */,
|
||||||
DA5E5C971724A667003798D8 /* MPAlgorithm.h */,
|
DA5E5C971724A667003798D8 /* MPAlgorithm.h */,
|
||||||
DA5E5C981724A667003798D8 /* MPAlgorithm.m */,
|
DA5E5C981724A667003798D8 /* MPAlgorithm.m */,
|
||||||
DA5E5C991724A667003798D8 /* MPAlgorithmV0.h */,
|
DA5E5C991724A667003798D8 /* MPAlgorithmV0.h */,
|
||||||
@@ -1772,8 +1781,8 @@
|
|||||||
DACA23B41705DF7D002C6C22 /* Resources */ = {
|
DACA23B41705DF7D002C6C22 /* Resources */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
DA0CC53C1EB57B69009A8ED9 /* Fabric */,
|
||||||
DA09745F1E995EB500F0BFE8 /* mpw_tests.xml */,
|
DA09745F1E995EB500F0BFE8 /* mpw_tests.xml */,
|
||||||
DACA26991705DF81002C6C22 /* Crashlytics */,
|
|
||||||
DACA29701705E1A8002C6C22 /* Data */,
|
DACA29701705E1A8002C6C22 /* Data */,
|
||||||
DACA23B51705DF7D002C6C22 /* Media */,
|
DACA23B51705DF7D002C6C22 /* Media */,
|
||||||
);
|
);
|
||||||
@@ -1856,14 +1865,6 @@
|
|||||||
path = Fonts;
|
path = Fonts;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
DACA26991705DF81002C6C22 /* Crashlytics */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
DACA269A1705DF81002C6C22 /* Crashlytics.plist */,
|
|
||||||
);
|
|
||||||
path = Crashlytics;
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
DACA29701705E1A8002C6C22 /* Data */ = {
|
DACA29701705E1A8002C6C22 /* Data */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@@ -2086,7 +2087,7 @@
|
|||||||
DA5BFA42147E415C00F98B1E /* Resources */,
|
DA5BFA42147E415C00F98B1E /* Resources */,
|
||||||
DAD9B5EE1762CA3A001835F9 /* Copy LoginHelper */,
|
DAD9B5EE1762CA3A001835F9 /* Copy LoginHelper */,
|
||||||
DA6556E314D55F3000841C99 /* Run Script: GIT version -> Info.plist */,
|
DA6556E314D55F3000841C99 /* Run Script: GIT version -> Info.plist */,
|
||||||
DAD3125D155288AA00A3F9ED /* Run Script: Crashlytics */,
|
DAD3125D155288AA00A3F9ED /* Run Script: Fabric */,
|
||||||
);
|
);
|
||||||
buildRules = (
|
buildRules = (
|
||||||
);
|
);
|
||||||
@@ -2295,13 +2296,13 @@
|
|||||||
DACA27331705DF81002C6C22 /* avatar-12@2x.png in Resources */,
|
DACA27331705DF81002C6C22 /* avatar-12@2x.png in Resources */,
|
||||||
DACA27341705DF81002C6C22 /* avatar-2@2x.png in Resources */,
|
DACA27341705DF81002C6C22 /* avatar-2@2x.png in Resources */,
|
||||||
DA60717D195D040500CA98B5 /* icon_gear@2x.png in Resources */,
|
DA60717D195D040500CA98B5 /* icon_gear@2x.png in Resources */,
|
||||||
|
DA0CC53E1EB57B69009A8ED9 /* Fabric.plist in Resources */,
|
||||||
DACA27351705DF81002C6C22 /* avatar-11.png in Resources */,
|
DACA27351705DF81002C6C22 /* avatar-11.png in Resources */,
|
||||||
DACA27361705DF81002C6C22 /* avatar-0@2x.png in Resources */,
|
DACA27361705DF81002C6C22 /* avatar-0@2x.png in Resources */,
|
||||||
DACA27371705DF81002C6C22 /* avatar-10@2x.png in Resources */,
|
DACA27371705DF81002C6C22 /* avatar-10@2x.png in Resources */,
|
||||||
DACA27381705DF81002C6C22 /* menu-icon.png in Resources */,
|
DACA27381705DF81002C6C22 /* menu-icon.png in Resources */,
|
||||||
DACA29671705DF81002C6C22 /* SourceCodePro-ExtraLight.otf in Resources */,
|
DACA29671705DF81002C6C22 /* SourceCodePro-ExtraLight.otf in Resources */,
|
||||||
DACA29681705DF81002C6C22 /* SourceCodePro-Black.otf in Resources */,
|
DACA29681705DF81002C6C22 /* SourceCodePro-Black.otf in Resources */,
|
||||||
DACA296F1705DF81002C6C22 /* Crashlytics.plist in Resources */,
|
|
||||||
DACA29731705E1A8002C6C22 /* ciphers.plist in Resources */,
|
DACA29731705E1A8002C6C22 /* ciphers.plist in Resources */,
|
||||||
DACA29741705E1A8002C6C22 /* dictionary.lst in Resources */,
|
DACA29741705E1A8002C6C22 /* dictionary.lst in Resources */,
|
||||||
DA5E5D081724A667003798D8 /* MasterPassword.entitlements in Resources */,
|
DA5E5D081724A667003798D8 /* MasterPassword.entitlements in Resources */,
|
||||||
@@ -2359,19 +2360,19 @@
|
|||||||
shellPath = "/bin/sh -e";
|
shellPath = "/bin/sh -e";
|
||||||
shellScript = "exec Scripts/updatePlist";
|
shellScript = "exec Scripts/updatePlist";
|
||||||
};
|
};
|
||||||
DAD3125D155288AA00A3F9ED /* Run Script: Crashlytics */ = {
|
DAD3125D155288AA00A3F9ED /* Run Script: Fabric */ = {
|
||||||
isa = PBXShellScriptBuildPhase;
|
isa = PBXShellScriptBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
);
|
);
|
||||||
inputPaths = (
|
inputPaths = (
|
||||||
);
|
);
|
||||||
name = "Run Script: Crashlytics";
|
name = "Run Script: Fabric";
|
||||||
outputPaths = (
|
outputPaths = (
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
shellPath = "/bin/sh -e";
|
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;
|
showEnvVarsInLog = 0;
|
||||||
};
|
};
|
||||||
/* End PBXShellScriptBuildPhase section */
|
/* End PBXShellScriptBuildPhase section */
|
||||||
@@ -2408,8 +2409,8 @@
|
|||||||
93D39784E725A34D1EE3FB3B /* MPInitialWindowController.m in Sources */,
|
93D39784E725A34D1EE3FB3B /* MPInitialWindowController.m in Sources */,
|
||||||
DA32CFDF19CF1C70004F3F0E /* MPSiteEntity.m in Sources */,
|
DA32CFDF19CF1C70004F3F0E /* MPSiteEntity.m in Sources */,
|
||||||
93D394C4254EEB45FB335AFB /* MPSitesTableView.m in Sources */,
|
93D394C4254EEB45FB335AFB /* MPSitesTableView.m in Sources */,
|
||||||
DA95B5231C477DE10067F5EF /* MasterPassword.xcdatamodeld in Sources */,
|
|
||||||
DA6774291A4746AF004F356A /* mpw-algorithm.c in Sources */,
|
DA6774291A4746AF004F356A /* mpw-algorithm.c in Sources */,
|
||||||
|
DA0CC5591EB6AE45009A8ED9 /* MasterPassword.xcdatamodeld in Sources */,
|
||||||
93D395E4830290EBB6E71F34 /* MPNoStateButton.m in Sources */,
|
93D395E4830290EBB6E71F34 /* MPNoStateButton.m in Sources */,
|
||||||
DA4DAE941A7D8117003E5423 /* MPAlgorithmV3.m in Sources */,
|
DA4DAE941A7D8117003E5423 /* MPAlgorithmV3.m in Sources */,
|
||||||
DA4DAE951A7D8117003E5423 /* MPTypes.m in Sources */,
|
DA4DAE951A7D8117003E5423 /* MPTypes.m in Sources */,
|
||||||
@@ -3129,19 +3130,20 @@
|
|||||||
/* End XCConfigurationList section */
|
/* End XCConfigurationList section */
|
||||||
|
|
||||||
/* Begin XCVersionGroup section */
|
/* Begin XCVersionGroup section */
|
||||||
DA95B51A1C477DE10067F5EF /* MasterPassword.xcdatamodeld */ = {
|
DA0CC54F1EB6AE45009A8ED9 /* MasterPassword.xcdatamodeld */ = {
|
||||||
isa = XCVersionGroup;
|
isa = XCVersionGroup;
|
||||||
children = (
|
children = (
|
||||||
DA95B51B1C477DE10067F5EF /* MasterPassword 1.xcdatamodel */,
|
DA0CC5501EB6AE45009A8ED9 /* MasterPassword 1.xcdatamodel */,
|
||||||
DA95B51C1C477DE10067F5EF /* MasterPassword 2.xcdatamodel */,
|
DA0CC5511EB6AE45009A8ED9 /* MasterPassword 2.xcdatamodel */,
|
||||||
DA95B51D1C477DE10067F5EF /* MasterPassword 3.xcdatamodel */,
|
DA0CC5521EB6AE45009A8ED9 /* MasterPassword 3.xcdatamodel */,
|
||||||
DA95B51E1C477DE10067F5EF /* MasterPassword 4.xcdatamodel */,
|
DA0CC5531EB6AE45009A8ED9 /* MasterPassword 4.xcdatamodel */,
|
||||||
DA95B51F1C477DE10067F5EF /* MasterPassword 5.xcdatamodel */,
|
DA0CC5541EB6AE45009A8ED9 /* MasterPassword 5.xcdatamodel */,
|
||||||
DA95B5201C477DE10067F5EF /* MasterPassword 6.xcdatamodel */,
|
DA0CC5551EB6AE45009A8ED9 /* MasterPassword 6.xcdatamodel */,
|
||||||
DA95B5211C477DE10067F5EF /* MasterPassword 7.xcdatamodel */,
|
DA0CC5561EB6AE45009A8ED9 /* MasterPassword 7.xcdatamodel */,
|
||||||
DA95B5221C477DE10067F5EF /* MasterPassword 8.xcdatamodel */,
|
DA0CC5571EB6AE45009A8ED9 /* MasterPassword 8.xcdatamodel */,
|
||||||
|
DA0CC5581EB6AE45009A8ED9 /* MasterPassword 9.xcdatamodel */,
|
||||||
);
|
);
|
||||||
currentVersion = DA95B5221C477DE10067F5EF /* MasterPassword 8.xcdatamodel */;
|
currentVersion = DA0CC5581EB6AE45009A8ED9 /* MasterPassword 9.xcdatamodel */;
|
||||||
path = MasterPassword.xcdatamodeld;
|
path = MasterPassword.xcdatamodeld;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
versionGroupType = wrapper.xcdatamodel;
|
versionGroupType = wrapper.xcdatamodel;
|
||||||
|
|||||||
@@ -41,9 +41,9 @@ case $PLATFORM_NAME in
|
|||||||
*) ftl 'ERROR: Unknown platform: %s.' "$PLATFORM_NAME"; exit 1 ;;
|
*) ftl 'ERROR: Unknown platform: %s.' "$PLATFORM_NAME"; exit 1 ;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
description=$(git describe --always --dirty --long --match "*-$platform-*")
|
description=$(git describe --always --dirty --long --match "*-$platform*")
|
||||||
version=${description%-g*} build=${version##*-} version=${version%-$build}
|
version=${description%-g*} build=${version##*-} version=${version%-$build}
|
||||||
version=${version//-*-/.} release=${version%%-*} commit=${description##*-g}
|
version=${version//-$platform/} version=${version//-/.} commit=${description##*-g}
|
||||||
|
|
||||||
addPlistWithKey GITDescription string "$description"
|
addPlistWithKey GITDescription string "$description"
|
||||||
setPlistWithKey CFBundleVersion "$(hr "${version%%.*}" 14).${version#*.}"
|
setPlistWithKey CFBundleVersion "$(hr "${version%%.*}" 14).${version#*.}"
|
||||||
@@ -55,14 +55,14 @@ setSettingWithTitle "Copyright" "$(getPlistWithKey NSHumanReadableCopyright)"
|
|||||||
|
|
||||||
if [[ $DEPLOYMENT_LOCATION = YES ]]; then
|
if [[ $DEPLOYMENT_LOCATION = YES ]]; then
|
||||||
# This build is a release. Do some release checks.
|
# 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
|
passed=1
|
||||||
[[ $description != *-dirty ]] || \
|
[[ $description != *-dirty ]] || \
|
||||||
{ passed=0; err 'ERROR: Cannot release a dirty version, first commit any changes.'; }
|
{ passed=0; err 'ERROR: Cannot release a dirty version, first commit any changes.'; }
|
||||||
[[ $build == 0 ]] || \
|
[[ $build == 0 ]] || \
|
||||||
{ passed=0; err 'ERROR: Commit is not tagged for release, first tag accordingly.'; }
|
{ passed=0; err 'ERROR: Commit is not tagged for release, first tag accordingly.'; }
|
||||||
[[ -r "$crashlyticsPlist" && $(PlistBuddy -c "Print :'API Key'" "$crashlyticsPlist" 2>/dev/null) ]] || \
|
[[ -r "$fabricPlist" && $(PlistBuddy -c "Print :'API Key'" "$fabricPlist" 2>/dev/null) ]] || \
|
||||||
{ passed=0; err 'ERROR: Cannot release: Crashlytics API key is missing.'; }
|
{ passed=0; err 'ERROR: Cannot release: Fabric API key is missing.'; }
|
||||||
(( passed )) || \
|
(( passed )) || \
|
||||||
{ ftl "Failed to pass release checks. Fix the above errors and re-try. Aborting."; exit 1; }
|
{ ftl "Failed to pass release checks. Fix the above errors and re-try. Aborting."; exit 1; }
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -17,9 +17,9 @@
|
|||||||
//==============================================================================
|
//==============================================================================
|
||||||
|
|
||||||
#import "MPKey.h"
|
#import "MPKey.h"
|
||||||
#import "MPStoredSiteEntity.h"
|
#import "MPStoredSiteEntity+CoreDataClass.h"
|
||||||
#import "MPGeneratedSiteEntity.h"
|
#import "MPGeneratedSiteEntity+CoreDataClass.h"
|
||||||
#import "MPSiteQuestionEntity.h"
|
#import "MPSiteQuestionEntity+CoreDataClass.h"
|
||||||
#import "mpw-algorithm.h"
|
#import "mpw-algorithm.h"
|
||||||
|
|
||||||
#define MPAlgorithmDefaultVersion MPAlgorithmVersionCurrent
|
#define MPAlgorithmDefaultVersion MPAlgorithmVersionCurrent
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ NSOperationQueue *_mpwQueue = nil;
|
|||||||
migrationRequest.predicate = [NSPredicate predicateWithFormat:@"version_ < %d AND user == %@", self.version, user];
|
migrationRequest.predicate = [NSPredicate predicateWithFormat:@"version_ < %d AND user == %@", self.version, user];
|
||||||
NSArray *migrationSites = [moc executeFetchRequest:migrationRequest error:&error];
|
NSArray *migrationSites = [moc executeFetchRequest:migrationRequest error:&error];
|
||||||
if (!migrationSites) {
|
if (!migrationSites) {
|
||||||
err( @"While looking for sites to migrate: %@", [error fullDescription] );
|
MPError( error, @"While looking for sites to migrate." );
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,17 +25,20 @@
|
|||||||
#define MPProductTouchID @"com.lyndir.masterpassword.products.touchid"
|
#define MPProductTouchID @"com.lyndir.masterpassword.products.touchid"
|
||||||
#define MPProductFuel @"com.lyndir.masterpassword.products.fuel"
|
#define MPProductFuel @"com.lyndir.masterpassword.products.fuel"
|
||||||
|
|
||||||
#define MP_FUEL_HOURLY_RATE 30.f /* Tier 1 purchases/h ~> USD/h */
|
#define MP_FUEL_HOURLY_RATE 40.f /* payment in tier 1 purchases / h (≅ USD / h) */
|
||||||
|
|
||||||
@protocol MPInAppDelegate
|
@protocol MPInAppDelegate
|
||||||
|
|
||||||
- (void)updateWithProducts:(NSArray /* SKProduct */ *)products;
|
- (void)updateWithProducts:(NSDictionary<NSString *, SKProduct *> *)products
|
||||||
- (void)updateWithTransaction:(SKPaymentTransaction *)transaction;
|
transactions:(NSDictionary<NSString *, SKPaymentTransaction *> *)transactions;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@interface MPAppDelegate_Shared(InApp)
|
@interface MPAppDelegate_Shared(InApp)
|
||||||
|
|
||||||
|
- (NSDictionary<NSString *, SKProduct *> *)products;
|
||||||
|
- (NSDictionary<NSString *, SKPaymentTransaction *> *)transactions;
|
||||||
|
|
||||||
- (void)registerProductsObserver:(id<MPInAppDelegate>)delegate;
|
- (void)registerProductsObserver:(id<MPInAppDelegate>)delegate;
|
||||||
- (void)removeProductsObserver:(id<MPInAppDelegate>)delegate;
|
- (void)removeProductsObserver:(id<MPInAppDelegate>)delegate;
|
||||||
|
|
||||||
|
|||||||
@@ -23,9 +23,20 @@
|
|||||||
|
|
||||||
@implementation MPAppDelegate_Shared(InApp)
|
@implementation MPAppDelegate_Shared(InApp)
|
||||||
|
|
||||||
PearlAssociatedObjectProperty( NSArray*, Products, products );
|
PearlAssociatedObjectProperty( NSDictionary*, Products, products );
|
||||||
|
|
||||||
PearlAssociatedObjectProperty( NSMutableArray*, ProductObservers, productObservers );
|
PearlAssociatedObjectProperty( NSMutableArray*, ProductObservers, productObservers );
|
||||||
|
|
||||||
|
- (NSDictionary<NSString *, SKPaymentTransaction *> *)transactions {
|
||||||
|
|
||||||
|
NSMutableDictionary<NSString *, SKPaymentTransaction *> *transactions =
|
||||||
|
[NSMutableDictionary dictionaryWithCapacity:self.paymentQueue.transactions.count];
|
||||||
|
for (SKPaymentTransaction *transaction in self.paymentQueue.transactions)
|
||||||
|
transactions[transaction.payment.productIdentifier] = transaction;
|
||||||
|
|
||||||
|
return transactions;
|
||||||
|
}
|
||||||
|
|
||||||
- (void)registerProductsObserver:(id<MPInAppDelegate>)delegate {
|
- (void)registerProductsObserver:(id<MPInAppDelegate>)delegate {
|
||||||
|
|
||||||
if (!self.productObservers)
|
if (!self.productObservers)
|
||||||
@@ -33,7 +44,7 @@ PearlAssociatedObjectProperty( NSMutableArray*, ProductObservers, productObserve
|
|||||||
[self.productObservers addObject:delegate];
|
[self.productObservers addObject:delegate];
|
||||||
|
|
||||||
if (self.products)
|
if (self.products)
|
||||||
[delegate updateWithProducts:self.products];
|
[delegate updateWithProducts:self.products transactions:[self transactions]];
|
||||||
else
|
else
|
||||||
[self reloadProducts];
|
[self reloadProducts];
|
||||||
}
|
}
|
||||||
@@ -101,11 +112,13 @@ PearlAssociatedObjectProperty( NSMutableArray*, ProductObservers, productObserve
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (SKProduct *product in self.products)
|
for (SKProduct *product in [self.products allValues])
|
||||||
if ([product.productIdentifier isEqualToString:productIdentifier]) {
|
if ([product.productIdentifier isEqualToString:productIdentifier]) {
|
||||||
SKMutablePayment *payment = [SKMutablePayment paymentWithProduct:product];
|
SKMutablePayment *payment = [SKMutablePayment paymentWithProduct:product];
|
||||||
|
if (payment) {
|
||||||
payment.quantity = quantity;
|
payment.quantity = quantity;
|
||||||
[[self paymentQueue] addPayment:payment];
|
[[self paymentQueue] addPayment:payment];
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -114,15 +127,22 @@ PearlAssociatedObjectProperty( NSMutableArray*, ProductObservers, productObserve
|
|||||||
|
|
||||||
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response {
|
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response {
|
||||||
|
|
||||||
inf( @"products: %@, invalid: %@", response.products, response.invalidProductIdentifiers );
|
if ([response.invalidProductIdentifiers count])
|
||||||
self.products = response.products;
|
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)
|
for (id<MPInAppDelegate> productObserver in self.productObservers)
|
||||||
[productObserver updateWithProducts:self.products];
|
[productObserver updateWithProducts:self.products transactions:[self transactions]];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)request:(SKRequest *)request didFailWithError:(NSError *)error {
|
- (void)request:(SKRequest *)request didFailWithError:(NSError *)error {
|
||||||
|
|
||||||
|
MPError( error, @"StoreKit request (%@) failed.", request );
|
||||||
|
|
||||||
#if TARGET_OS_IPHONE
|
#if TARGET_OS_IPHONE
|
||||||
[PearlAlert showAlertWithTitle:@"Purchase Failed" message:
|
[PearlAlert showAlertWithTitle:@"Purchase Failed" message:
|
||||||
strf( @"%@\n\n%@", error.localizedDescription,
|
strf( @"%@\n\n%@", error.localizedDescription,
|
||||||
@@ -131,7 +151,6 @@ PearlAssociatedObjectProperty( NSMutableArray*, ProductObservers, productObserve
|
|||||||
cancelTitle:@"OK" otherTitles:nil];
|
cancelTitle:@"OK" otherTitles:nil];
|
||||||
#else
|
#else
|
||||||
#endif
|
#endif
|
||||||
err( @"StoreKit request (%@) failed: %@", request, [error fullDescription] );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)requestDidFinish:(SKRequest *)request {
|
- (void)requestDidFinish:(SKRequest *)request {
|
||||||
@@ -145,23 +164,41 @@ PearlAssociatedObjectProperty( NSMutableArray*, ProductObservers, productObserve
|
|||||||
|
|
||||||
for (SKPaymentTransaction *transaction in transactions) {
|
for (SKPaymentTransaction *transaction in transactions) {
|
||||||
dbg( @"transaction updated: %@ -> %d", transaction.payment.productIdentifier, (int)(transaction.transactionState) );
|
dbg( @"transaction updated: %@ -> %d", transaction.payment.productIdentifier, (int)(transaction.transactionState) );
|
||||||
|
|
||||||
switch (transaction.transactionState) {
|
switch (transaction.transactionState) {
|
||||||
case SKPaymentTransactionStatePurchased: {
|
case SKPaymentTransactionStatePurchased: {
|
||||||
inf( @"purchased: %@", transaction.payment.productIdentifier );
|
inf( @"Purchased: %@", transaction.payment.productIdentifier );
|
||||||
|
NSMutableDictionary *attributes = [NSMutableDictionary new];
|
||||||
|
|
||||||
if ([transaction.payment.productIdentifier isEqualToString:MPProductFuel]) {
|
if ([transaction.payment.productIdentifier isEqualToString:MPProductFuel]) {
|
||||||
float currentFuel = [[MPiOSConfig get].developmentFuelRemaining floatValue];
|
float currentFuel = [[MPiOSConfig get].developmentFuelRemaining floatValue];
|
||||||
float purchasedFuel = transaction.payment.quantity / MP_FUEL_HOURLY_RATE;
|
float purchasedFuel = transaction.payment.quantity / MP_FUEL_HOURLY_RATE;
|
||||||
[MPiOSConfig get].developmentFuelRemaining = @(currentFuel + purchasedFuel);
|
[MPiOSConfig get].developmentFuelRemaining = @(currentFuel + purchasedFuel);
|
||||||
if (![MPiOSConfig get].developmentFuelChecked || currentFuel < DBL_EPSILON)
|
if (![MPiOSConfig get].developmentFuelChecked || currentFuel < DBL_EPSILON)
|
||||||
[MPiOSConfig get].developmentFuelChecked = [NSDate date];
|
[MPiOSConfig get].developmentFuelChecked = [NSDate date];
|
||||||
|
[attributes addEntriesFromDictionary:@{
|
||||||
|
@"currentFuel" : @(currentFuel),
|
||||||
|
@"purchasedFuel": @(purchasedFuel),
|
||||||
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
[[NSUserDefaults standardUserDefaults] setObject:transaction.transactionIdentifier
|
[[NSUserDefaults standardUserDefaults] setObject:transaction.transactionIdentifier
|
||||||
forKey:transaction.payment.productIdentifier];
|
forKey:transaction.payment.productIdentifier];
|
||||||
[queue finishTransaction:transaction];
|
[queue finishTransaction:transaction];
|
||||||
|
|
||||||
|
if ([[MPConfig get].sendInfo boolValue]) {
|
||||||
|
#ifdef CRASHLYTICS
|
||||||
|
SKProduct *product = self.products[transaction.payment.productIdentifier];
|
||||||
|
for (int q = 0; q < transaction.payment.quantity; ++q)
|
||||||
|
[Answers logPurchaseWithPrice:product.price currency:[product.priceLocale objectForKey:NSLocaleCurrencyCode]
|
||||||
|
success:@YES itemName:product.localizedTitle itemType:@"InApp"
|
||||||
|
itemId:product.productIdentifier customAttributes:attributes];
|
||||||
|
#endif
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SKPaymentTransactionStateRestored: {
|
case SKPaymentTransactionStateRestored: {
|
||||||
inf( @"restored: %@", transaction.payment.productIdentifier );
|
inf( @"Restored: %@", transaction.payment.productIdentifier );
|
||||||
[[NSUserDefaults standardUserDefaults] setObject:transaction.transactionIdentifier
|
[[NSUserDefaults standardUserDefaults] setObject:transaction.transactionIdentifier
|
||||||
forKey:transaction.payment.productIdentifier];
|
forKey:transaction.payment.productIdentifier];
|
||||||
[queue finishTransaction:transaction];
|
[queue finishTransaction:transaction];
|
||||||
@@ -171,21 +208,38 @@ PearlAssociatedObjectProperty( NSMutableArray*, ProductObservers, productObserve
|
|||||||
case SKPaymentTransactionStateDeferred:
|
case SKPaymentTransactionStateDeferred:
|
||||||
break;
|
break;
|
||||||
case SKPaymentTransactionStateFailed:
|
case SKPaymentTransactionStateFailed:
|
||||||
err( @"Transaction failed: %@, reason: %@", transaction.payment.productIdentifier, [transaction.error fullDescription] );
|
MPError( transaction.error, @"Transaction failed: %@.", transaction.payment.productIdentifier );
|
||||||
[queue finishTransaction:transaction];
|
[queue finishTransaction:transaction];
|
||||||
|
|
||||||
|
if ([[MPConfig get].sendInfo boolValue]) {
|
||||||
|
#ifdef CRASHLYTICS
|
||||||
|
SKProduct *product = self.products[transaction.payment.productIdentifier];
|
||||||
|
[Answers logPurchaseWithPrice:product.price currency:[product.priceLocale objectForKey:NSLocaleCurrencyCode]
|
||||||
|
success:@NO itemName:product.localizedTitle itemType:@"InApp" itemId:product.productIdentifier
|
||||||
|
customAttributes:@{
|
||||||
|
@"state" : @"Failed",
|
||||||
|
@"quantity": @(transaction.payment.quantity),
|
||||||
|
@"reason" : [transaction.error localizedFailureReason]?: [transaction.error localizedDescription],
|
||||||
|
}];
|
||||||
|
#endif
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (id<MPInAppDelegate> productObserver in self.productObservers)
|
|
||||||
[productObserver updateWithTransaction:transaction];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (![[NSUserDefaults standardUserDefaults] synchronize])
|
if (![[NSUserDefaults standardUserDefaults] synchronize])
|
||||||
wrn( @"Couldn't synchronize after transaction updates." );
|
wrn( @"Couldn't synchronize after transaction updates." );
|
||||||
|
|
||||||
|
NSMutableDictionary<NSString *, SKPaymentTransaction *> *allTransactions = [[self transactions] mutableCopy];
|
||||||
|
for (SKPaymentTransaction *transaction in transactions)
|
||||||
|
allTransactions[transaction.payment.productIdentifier] = transaction;
|
||||||
|
for (id<MPInAppDelegate> productObserver in self.productObservers)
|
||||||
|
[productObserver updateWithProducts:self.products transactions:allTransactions];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)paymentQueue:(SKPaymentQueue *)queue restoreCompletedTransactionsFailedWithError:(NSError *)error {
|
- (void)paymentQueue:(SKPaymentQueue *)queue restoreCompletedTransactionsFailedWithError:(NSError *)error {
|
||||||
|
|
||||||
err( @"StoreKit restore failed: %@", [error fullDescription] );
|
MPError( error, @"StoreKit restore failed." );
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -16,18 +16,19 @@
|
|||||||
// LICENSE file. Alternatively, see <http://www.gnu.org/licenses/>.
|
// LICENSE file. Alternatively, see <http://www.gnu.org/licenses/>.
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
|
|
||||||
|
#import <Crashlytics/Answers.h>
|
||||||
#import "MPAppDelegate_Key.h"
|
#import "MPAppDelegate_Key.h"
|
||||||
#import "MPAppDelegate_Store.h"
|
#import "MPAppDelegate_Store.h"
|
||||||
|
|
||||||
@interface MPAppDelegate_Shared()
|
@interface MPAppDelegate_Shared()
|
||||||
|
|
||||||
@property(strong, nonatomic) MPKey *key;
|
@property(strong, atomic) MPKey *key;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation MPAppDelegate_Shared(Key)
|
@implementation MPAppDelegate_Shared(Key)
|
||||||
|
|
||||||
static NSDictionary *createKeyQuery(MPUserEntity *user, BOOL newItem, MPKeyOrigin *keyOrigin) {
|
- (NSDictionary *)createKeyQueryforUser:(MPUserEntity *)user origin:(out MPKeyOrigin *)keyOrigin {
|
||||||
|
|
||||||
#if TARGET_OS_IPHONE
|
#if TARGET_OS_IPHONE
|
||||||
if (user.touchID && kSecUseAuthenticationUI) {
|
if (user.touchID && kSecUseAuthenticationUI) {
|
||||||
@@ -37,8 +38,8 @@ static NSDictionary *createKeyQuery(MPUserEntity *user, BOOL newItem, MPKeyOrigi
|
|||||||
CFErrorRef acError = NULL;
|
CFErrorRef acError = NULL;
|
||||||
id accessControl = (__bridge_transfer id)SecAccessControlCreateWithFlags( kCFAllocatorDefault,
|
id accessControl = (__bridge_transfer id)SecAccessControlCreateWithFlags( kCFAllocatorDefault,
|
||||||
kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly, kSecAccessControlTouchIDCurrentSet, &acError );
|
kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly, kSecAccessControlTouchIDCurrentSet, &acError );
|
||||||
if (!accessControl || acError)
|
if (!accessControl)
|
||||||
err( @"Could not use TouchID on this device: %@", acError );
|
MPError( (__bridge_transfer NSError *)acError, @"Could not use TouchID on this device." );
|
||||||
|
|
||||||
else
|
else
|
||||||
return [PearlKeyChain createQueryForClass:kSecClassGenericPassword
|
return [PearlKeyChain createQueryForClass:kSecClassGenericPassword
|
||||||
@@ -46,7 +47,7 @@ static NSDictionary *createKeyQuery(MPUserEntity *user, BOOL newItem, MPKeyOrigi
|
|||||||
(__bridge id)kSecAttrService : @"Saved Master Password",
|
(__bridge id)kSecAttrService : @"Saved Master Password",
|
||||||
(__bridge id)kSecAttrAccount : user.name?: @"",
|
(__bridge id)kSecAttrAccount : user.name?: @"",
|
||||||
(__bridge id)kSecAttrAccessControl : accessControl,
|
(__bridge id)kSecAttrAccessControl : accessControl,
|
||||||
(__bridge id)kSecUseAuthenticationUI : (__bridge id)kSecUseAuthenticationUIAllow,
|
(__bridge id)kSecUseAuthenticationUI: (__bridge id)kSecUseAuthenticationUIAllow,
|
||||||
(__bridge id)kSecUseOperationPrompt :
|
(__bridge id)kSecUseOperationPrompt :
|
||||||
strf( @"Access %@'s master password.", user.name ),
|
strf( @"Access %@'s master password.", user.name ),
|
||||||
}
|
}
|
||||||
@@ -59,10 +60,10 @@ static NSDictionary *createKeyQuery(MPUserEntity *user, BOOL newItem, MPKeyOrigi
|
|||||||
|
|
||||||
return [PearlKeyChain createQueryForClass:kSecClassGenericPassword
|
return [PearlKeyChain createQueryForClass:kSecClassGenericPassword
|
||||||
attributes:@{
|
attributes:@{
|
||||||
(__bridge id)kSecAttrService: @"Saved Master Password",
|
(__bridge id)kSecAttrService : @"Saved Master Password",
|
||||||
(__bridge id)kSecAttrAccount: user.name?: @"",
|
(__bridge id)kSecAttrAccount : user.name?: @"",
|
||||||
#if TARGET_OS_IPHONE
|
#if TARGET_OS_IPHONE
|
||||||
(__bridge id)kSecAttrAccessible : (__bridge id)(kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly?: kSecAttrAccessibleWhenUnlockedThisDeviceOnly),
|
(__bridge id)kSecAttrAccessible: (__bridge id)(kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly?: kSecAttrAccessibleWhenUnlockedThisDeviceOnly),
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
matches:nil];
|
matches:nil];
|
||||||
@@ -71,7 +72,7 @@ static NSDictionary *createKeyQuery(MPUserEntity *user, BOOL newItem, MPKeyOrigi
|
|||||||
- (MPKey *)loadSavedKeyFor:(MPUserEntity *)user {
|
- (MPKey *)loadSavedKeyFor:(MPUserEntity *)user {
|
||||||
|
|
||||||
MPKeyOrigin keyOrigin;
|
MPKeyOrigin keyOrigin;
|
||||||
NSDictionary *keyQuery = createKeyQuery( user, NO, &keyOrigin );
|
NSDictionary *keyQuery = [self createKeyQueryforUser:user origin:&keyOrigin];
|
||||||
id<MPAlgorithm> keyAlgorithm = user.algorithm;
|
id<MPAlgorithm> keyAlgorithm = user.algorithm;
|
||||||
MPKey *key = [[MPKey alloc] initForFullName:user.name withKeyResolver:^NSData *(id<MPAlgorithm> algorithm) {
|
MPKey *key = [[MPKey alloc] initForFullName:user.name withKeyResolver:^NSData *(id<MPAlgorithm> algorithm) {
|
||||||
return ![algorithm isEqual:keyAlgorithm]? nil:
|
return ![algorithm isEqual:keyAlgorithm]? nil:
|
||||||
@@ -99,7 +100,7 @@ static NSDictionary *createKeyQuery(MPUserEntity *user, BOOL newItem, MPKeyOrigi
|
|||||||
[self forgetSavedKeyFor:user];
|
[self forgetSavedKeyFor:user];
|
||||||
|
|
||||||
inf( @"Saving key in keychain for user: %@", user.userID );
|
inf( @"Saving key in keychain for user: %@", user.userID );
|
||||||
[PearlKeyChain addOrUpdateItemForQuery:createKeyQuery( user, YES, nil )
|
[PearlKeyChain addOrUpdateItemForQuery:[self createKeyQueryforUser:user origin:nil]
|
||||||
withAttributes:@{ (__bridge id)kSecValueData: keyData }];
|
withAttributes:@{ (__bridge id)kSecValueData: keyData }];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -107,7 +108,7 @@ static NSDictionary *createKeyQuery(MPUserEntity *user, BOOL newItem, MPKeyOrigi
|
|||||||
|
|
||||||
- (void)forgetSavedKeyFor:(MPUserEntity *)user {
|
- (void)forgetSavedKeyFor:(MPUserEntity *)user {
|
||||||
|
|
||||||
OSStatus result = [PearlKeyChain deleteItemForQuery:createKeyQuery( user, NO, nil )];
|
OSStatus result = [PearlKeyChain deleteItemForQuery:[self createKeyQueryforUser:user origin:nil]];
|
||||||
if (result == noErr) {
|
if (result == noErr) {
|
||||||
inf( @"Removed key from keychain for user: %@", user.userID );
|
inf( @"Removed key from keychain for user: %@", user.userID );
|
||||||
|
|
||||||
@@ -177,6 +178,14 @@ static NSDictionary *createKeyQuery(MPUserEntity *user, BOOL newItem, MPKeyOrigi
|
|||||||
else
|
else
|
||||||
dbg( @"Automatic login failed for user: %@", user.userID );
|
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;
|
return NO;
|
||||||
}
|
}
|
||||||
inf( @"Logged in user: %@", user.userID );
|
inf( @"Logged in user: %@", user.userID );
|
||||||
@@ -198,8 +207,11 @@ static NSDictionary *createKeyQuery(MPUserEntity *user, BOOL newItem, MPKeyOrigi
|
|||||||
@try {
|
@try {
|
||||||
if ([[MPConfig get].sendInfo boolValue]) {
|
if ([[MPConfig get].sendInfo boolValue]) {
|
||||||
#ifdef CRASHLYTICS
|
#ifdef CRASHLYTICS
|
||||||
[[Crashlytics sharedInstance] setObjectValue:user.userID forKey:@"username"];
|
|
||||||
[[Crashlytics sharedInstance] setUserName:user.userID];
|
[[Crashlytics sharedInstance] setUserName:user.userID];
|
||||||
|
|
||||||
|
[Answers logLoginWithMethod:password? @"Password": @"Automatic" success:@YES customAttributes:@{
|
||||||
|
@"algorithm": @(user.algorithm.version),
|
||||||
|
}];
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,9 +26,9 @@
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@property(strong, nonatomic, readonly) MPKey *key;
|
@property(strong, atomic, readonly) MPKey *key;
|
||||||
@property(strong, nonatomic, readonly) NSManagedObjectID *activeUserOID;
|
@property(strong, atomic, readonly) NSManagedObjectID *activeUserOID;
|
||||||
@property(strong, nonatomic, readonly) NSPersistentStoreCoordinator *storeCoordinator;
|
@property(strong, atomic, readonly) NSPersistentStoreCoordinator *storeCoordinator;
|
||||||
|
|
||||||
+ (instancetype)get;
|
+ (instancetype)get;
|
||||||
|
|
||||||
|
|||||||
@@ -23,9 +23,9 @@
|
|||||||
|
|
||||||
@interface MPAppDelegate_Shared()
|
@interface MPAppDelegate_Shared()
|
||||||
|
|
||||||
@property(strong, nonatomic) MPKey *key;
|
@property(strong, atomic) MPKey *key;
|
||||||
@property(strong, nonatomic) NSManagedObjectID *activeUserOID;
|
@property(strong, atomic) NSManagedObjectID *activeUserOID;
|
||||||
@property(strong, nonatomic) NSPersistentStoreCoordinator *storeCoordinator;
|
@property(strong, atomic) NSPersistentStoreCoordinator *storeCoordinator;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@@ -74,14 +74,11 @@
|
|||||||
|
|
||||||
- (void)setActiveUser:(MPUserEntity *)activeUser {
|
- (void)setActiveUser:(MPUserEntity *)activeUser {
|
||||||
|
|
||||||
NSError *error;
|
self.activeUserOID = activeUser.permanentObjectID;
|
||||||
if (activeUser.objectID.isTemporaryID && ![activeUser.managedObjectContext obtainPermanentIDsForObjects:@[ activeUser ] error:&error])
|
|
||||||
err( @"Failed to obtain a permanent object ID after setting active user: %@", [error fullDescription] );
|
|
||||||
|
|
||||||
self.activeUserOID = activeUser.objectID;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)handleCoordinatorError:(NSError *)error {
|
- (void)handleCoordinatorError:(NSError *)error {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ typedef NS_ENUM( NSUInteger, MPImportResult ) {
|
|||||||
+ (BOOL)managedObjectContextForMainThreadPerformBlockAndWait:(void ( ^ )(NSManagedObjectContext *mainContext))mocBlock;
|
+ (BOOL)managedObjectContextForMainThreadPerformBlockAndWait:(void ( ^ )(NSManagedObjectContext *mainContext))mocBlock;
|
||||||
+ (BOOL)managedObjectContextPerformBlock:(void ( ^ )(NSManagedObjectContext *context))mocBlock;
|
+ (BOOL)managedObjectContextPerformBlock:(void ( ^ )(NSManagedObjectContext *context))mocBlock;
|
||||||
+ (BOOL)managedObjectContextPerformBlockAndWait:(void ( ^ )(NSManagedObjectContext *context))mocBlock;
|
+ (BOOL)managedObjectContextPerformBlockAndWait:(void ( ^ )(NSManagedObjectContext *context))mocBlock;
|
||||||
|
+ (id)managedObjectContextChanged:(void ( ^ )(NSDictionary<NSManagedObjectID *, NSString *> *affectedObjects))changedBlock;
|
||||||
|
|
||||||
- (MPFixableResult)findAndFixInconsistenciesSaveInContext:(NSManagedObjectContext *)context;
|
- (MPFixableResult)findAndFixInconsistenciesSaveInContext:(NSManagedObjectContext *)context;
|
||||||
- (void)deleteAndResetStore;
|
- (void)deleteAndResetStore;
|
||||||
|
|||||||
@@ -131,6 +131,25 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
|
|||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
+ (id)managedObjectContextChanged:(void ( ^ )(NSDictionary<NSManagedObjectID *, NSString *> *affectedObjects))changedBlock {
|
||||||
|
|
||||||
|
NSManagedObjectContext *privateManagedObjectContextIfReady = [[self get] privateManagedObjectContextIfReady];
|
||||||
|
if (!privateManagedObjectContextIfReady)
|
||||||
|
return nil;
|
||||||
|
|
||||||
|
return PearlAddNotificationObserver( NSManagedObjectContextObjectsDidChangeNotification, privateManagedObjectContextIfReady, nil,
|
||||||
|
^(id host, NSNotification *note) {
|
||||||
|
NSMutableDictionary *affectedObjects = [NSMutableDictionary new];
|
||||||
|
for (NSManagedObject *object in note.userInfo[NSInsertedObjectsKey])
|
||||||
|
affectedObjects[object.objectID] = NSInsertedObjectsKey;
|
||||||
|
for (NSManagedObject *object in note.userInfo[NSUpdatedObjectsKey])
|
||||||
|
affectedObjects[object.objectID] = NSUpdatedObjectsKey;
|
||||||
|
for (NSManagedObject *object in note.userInfo[NSDeletedObjectsKey])
|
||||||
|
affectedObjects[object.objectID] = NSDeletedObjectsKey;
|
||||||
|
changedBlock( affectedObjects );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
- (NSManagedObjectContext *)mainManagedObjectContextIfReady {
|
- (NSManagedObjectContext *)mainManagedObjectContextIfReady {
|
||||||
|
|
||||||
[self loadStore];
|
[self loadStore];
|
||||||
@@ -196,13 +215,15 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
|
|||||||
|
|
||||||
self.mainManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
|
self.mainManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
|
||||||
self.mainManagedObjectContext.parentContext = self.privateManagedObjectContext;
|
self.mainManagedObjectContext.parentContext = self.privateManagedObjectContext;
|
||||||
|
if ([self.mainManagedObjectContext respondsToSelector:@selector( automaticallyMergesChangesFromParent )]) // iOS 10+
|
||||||
|
self.mainManagedObjectContext.automaticallyMergesChangesFromParent = YES;
|
||||||
|
else
|
||||||
// When privateManagedObjectContext is saved, import the changes into mainManagedObjectContext.
|
// When privateManagedObjectContext is saved, import the changes into mainManagedObjectContext.
|
||||||
PearlAddNotificationObserverTo( self.mainManagedObjectContext, NSManagedObjectContextDidSaveNotification,
|
PearlAddNotificationObserverTo( self.mainManagedObjectContext, NSManagedObjectContextDidSaveNotification,
|
||||||
self.privateManagedObjectContext, nil, ^(NSManagedObjectContext *mainManagedObjectContext, NSNotification *note) {
|
self.privateManagedObjectContext, nil, ^(NSManagedObjectContext *mainContext, NSNotification *note) {
|
||||||
[mainManagedObjectContext performBlock:^{
|
[mainContext performBlock:^{
|
||||||
@try {
|
@try {
|
||||||
[mainManagedObjectContext mergeChangesFromContextDidSaveNotification:note];
|
[mainContext mergeChangesFromContextDidSaveNotification:note];
|
||||||
}
|
}
|
||||||
@catch (NSException *exception) {
|
@catch (NSException *exception) {
|
||||||
err( @"While merging changes:\n%@", [exception fullDescription] );
|
err( @"While merging changes:\n%@", [exception fullDescription] );
|
||||||
@@ -216,7 +237,7 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
|
|||||||
NSURL *localStoreURL = [self localStoreURL];
|
NSURL *localStoreURL = [self localStoreURL];
|
||||||
if (![[NSFileManager defaultManager] createDirectoryAtURL:[localStoreURL URLByDeletingLastPathComponent]
|
if (![[NSFileManager defaultManager] createDirectoryAtURL:[localStoreURL URLByDeletingLastPathComponent]
|
||||||
withIntermediateDirectories:YES attributes:nil error:&error]) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
if (![self.storeCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:[self localStoreURL]
|
if (![self.storeCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:[self localStoreURL]
|
||||||
@@ -225,7 +246,7 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
|
|||||||
NSInferMappingModelAutomaticallyOption : @YES,
|
NSInferMappingModelAutomaticallyOption : @YES,
|
||||||
STORE_OPTIONS
|
STORE_OPTIONS
|
||||||
} error:&error]) {
|
} error:&error]) {
|
||||||
err( @"Failed to open store: %@", [error fullDescription] );
|
MPError( error, @"Failed to open store." );
|
||||||
self.storeCorrupted = @YES;
|
self.storeCorrupted = @YES;
|
||||||
[self handleCoordinatorError:error];
|
[self handleCoordinatorError:error];
|
||||||
return;
|
return;
|
||||||
@@ -234,12 +255,15 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
|
|||||||
|
|
||||||
#if TARGET_OS_IPHONE
|
#if TARGET_OS_IPHONE
|
||||||
PearlAddNotificationObserver( UIApplicationWillResignActiveNotification, UIApp, [NSOperationQueue mainQueue],
|
PearlAddNotificationObserver( UIApplicationWillResignActiveNotification, UIApp, [NSOperationQueue mainQueue],
|
||||||
#else
|
|
||||||
PearlAddNotificationObserver( NSApplicationWillResignActiveNotification, NSApp, [NSOperationQueue mainQueue],
|
|
||||||
#endif
|
|
||||||
^(MPAppDelegate_Shared *self, NSNotification *note) {
|
^(MPAppDelegate_Shared *self, NSNotification *note) {
|
||||||
[self.mainManagedObjectContext saveToStore];
|
[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.
|
// Perform a data sanity check on the newly loaded store to find and fix any issues.
|
||||||
if ([[MPConfig get].checkInconsistency boolValue])
|
if ([[MPConfig get].checkInconsistency boolValue])
|
||||||
@@ -265,10 +289,10 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
|
|||||||
NSError *error = nil;
|
NSError *error = nil;
|
||||||
for (NSPersistentStore *store in self.storeCoordinator.persistentStores) {
|
for (NSPersistentStore *store in self.storeCoordinator.persistentStores) {
|
||||||
if (![self.storeCoordinator removePersistentStore:store error:&error])
|
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])
|
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];
|
[self loadStore];
|
||||||
}
|
}
|
||||||
@@ -286,7 +310,7 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
|
|||||||
fetchRequest.entity = entity;
|
fetchRequest.entity = entity;
|
||||||
NSArray *objects = [context executeFetchRequest:fetchRequest error:&error];
|
NSArray *objects = [context executeFetchRequest:fetchRequest error:&error];
|
||||||
if (!objects) {
|
if (!objects) {
|
||||||
err( @"Failed to fetch %@ objects: %@", entity, [error fullDescription] );
|
MPError( error, @"Failed to fetch %@ objects.", entity );
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -311,7 +335,8 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
|
|||||||
|
|
||||||
- (void)migrateStore {
|
- (void)migrateStore {
|
||||||
|
|
||||||
MPStoreMigrationLevel migrationLevel = (signed)[[NSUserDefaults standardUserDefaults] integerForKey:MPMigrationLevelLocalStoreKey];
|
MPStoreMigrationLevel migrationLevel = (MPStoreMigrationLevel)
|
||||||
|
[[NSUserDefaults standardUserDefaults] integerForKey:MPMigrationLevelLocalStoreKey];
|
||||||
if (migrationLevel >= MPStoreMigrationLevelCurrent)
|
if (migrationLevel >= MPStoreMigrationLevelCurrent)
|
||||||
// Local store up-to-date.
|
// Local store up-to-date.
|
||||||
return;
|
return;
|
||||||
@@ -353,8 +378,8 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
|
|||||||
NSError *error = nil;
|
NSError *error = nil;
|
||||||
if (![NSPersistentStore migrateStore:oldLocalStoreURL withOptions:@{ STORE_OPTIONS }
|
if (![NSPersistentStore migrateStore:oldLocalStoreURL withOptions:@{ STORE_OPTIONS }
|
||||||
toStore:newLocalStoreURL withOptions:@{ STORE_OPTIONS }
|
toStore:newLocalStoreURL withOptions:@{ STORE_OPTIONS }
|
||||||
model:nil error:&error]) {
|
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;
|
return NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -400,14 +425,52 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
|
|||||||
NSMigratePersistentStoresAutomaticallyOption: @YES,
|
NSMigratePersistentStoresAutomaticallyOption: @YES,
|
||||||
NSInferMappingModelAutomaticallyOption : @YES,
|
NSInferMappingModelAutomaticallyOption : @YES,
|
||||||
STORE_OPTIONS
|
STORE_OPTIONS
|
||||||
} model:nil error:&error]) {
|
} 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;
|
return NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//- (BOOL)migrateV3LocalStore {
|
||||||
|
//
|
||||||
|
// inf( @"Migrating V3 local store" );
|
||||||
|
// NSURL *localStoreURL = [self localStoreURL];
|
||||||
|
// if (![[NSFileManager defaultManager] fileExistsAtPath:localStoreURL.path isDirectory:NULL]) {
|
||||||
|
// inf( @"No V3 local store to migrate." );
|
||||||
|
// return YES;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// NSError *error = nil;
|
||||||
|
// NSDictionary<NSString *, id> *metadata = [NSPersistentStore metadataForPersistentStoreWithURL:localStoreURL error:&error];
|
||||||
|
// if (!metadata) {
|
||||||
|
// MPError( error, @"Couldn't inspect metadata for store: %@", localStoreURL );
|
||||||
|
// return NO;
|
||||||
|
// }
|
||||||
|
// NSPersistentStoreCoordinator *coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:
|
||||||
|
// [NSManagedObjectModel mergedModelFromBundles:nil forStoreMetadata:metadata]];
|
||||||
|
// if (![coordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil
|
||||||
|
// URL:localStoreURL options:@{ STORE_OPTIONS }
|
||||||
|
// error:&error]) {
|
||||||
|
// MPError( error, @"Couldn't open V3 local store to migrate." );
|
||||||
|
// return NO;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// NSManagedObjectContext *context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
|
||||||
|
// [context performBlockAndWait:^{
|
||||||
|
// context.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy;
|
||||||
|
// context.persistentStoreCoordinator = coordinator;
|
||||||
|
// for (MPStoredSiteEntity *storedSite in [[MPStoredSiteEntity fetchRequest] execute:&error]) {
|
||||||
|
// id contentObject = [storedSite valueForKey:@"contentObject"];
|
||||||
|
// if ([contentObject isKindOfClass:[NSData class]])
|
||||||
|
// storedSite.contentObject = contentObject;
|
||||||
|
// }
|
||||||
|
// }];
|
||||||
|
//
|
||||||
|
// return YES;
|
||||||
|
//}
|
||||||
|
|
||||||
#pragma mark - Utilities
|
#pragma mark - Utilities
|
||||||
|
|
||||||
- (void)addSiteNamed:(NSString *)siteName completion:(void ( ^ )(MPSiteEntity *site, NSManagedObjectContext *context))completion {
|
- (void)addSiteNamed:(NSString *)siteName completion:(void ( ^ )(MPSiteEntity *site, NSManagedObjectContext *context))completion {
|
||||||
@@ -436,10 +499,6 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
|
|||||||
site.lastUsed = [NSDate date];
|
site.lastUsed = [NSDate date];
|
||||||
site.algorithm = algorithm;
|
site.algorithm = algorithm;
|
||||||
|
|
||||||
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] );
|
|
||||||
|
|
||||||
[context saveToStore];
|
[context saveToStore];
|
||||||
|
|
||||||
completion( site, context );
|
completion( site, context );
|
||||||
@@ -468,18 +527,14 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
|
|||||||
newSite.algorithm = site.algorithm;
|
newSite.algorithm = site.algorithm;
|
||||||
newSite.loginName = site.loginName;
|
newSite.loginName = site.loginName;
|
||||||
|
|
||||||
NSError *error = nil;
|
|
||||||
if (![context obtainPermanentIDsForObjects:@[ newSite ] error:&error])
|
|
||||||
err( @"Failed to obtain a permanent object ID after changing object type: %@", [error fullDescription] );
|
|
||||||
|
|
||||||
[context deleteObject:site];
|
[context deleteObject:site];
|
||||||
[context saveToStore];
|
[context saveToStore];
|
||||||
|
|
||||||
[[NSNotificationCenter defaultCenter] postNotificationName:MPSiteUpdatedNotification object:site.objectID];
|
[[NSNotificationCenter defaultCenter] postNotificationName:MPSiteUpdatedNotification object:site.permanentObjectID];
|
||||||
site = newSite;
|
site = newSite;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[NSNotificationCenter defaultCenter] postNotificationName:MPSiteUpdatedNotification object:site.objectID];
|
[[NSNotificationCenter defaultCenter] postNotificationName:MPSiteUpdatedNotification object:site.permanentObjectID];
|
||||||
return site;
|
return site;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -516,7 +571,7 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
|
|||||||
initWithPattern:@"^#[[:space:]]*([^:]+): (.*)"
|
initWithPattern:@"^#[[:space:]]*([^:]+): (.*)"
|
||||||
options:(NSRegularExpressionOptions)0 error:&error];
|
options:(NSRegularExpressionOptions)0 error:&error];
|
||||||
if (error) {
|
if (error) {
|
||||||
err( @"Error loading the header pattern: %@", [error fullDescription] );
|
MPError( error, @"Error loading the header pattern." );
|
||||||
return MPImportResultInternalError;
|
return MPImportResultInternalError;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -530,7 +585,7 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
|
|||||||
options:(NSRegularExpressionOptions)0 error:&error]
|
options:(NSRegularExpressionOptions)0 error:&error]
|
||||||
];
|
];
|
||||||
if (error) {
|
if (error) {
|
||||||
err( @"Error loading the site patterns: %@", [error fullDescription] );
|
MPError( error, @"Error loading the site patterns." );
|
||||||
return MPImportResultInternalError;
|
return MPImportResultInternalError;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -589,7 +644,7 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
|
|||||||
userFetchRequest.predicate = [NSPredicate predicateWithFormat:@"name == %@", importUserName];
|
userFetchRequest.predicate = [NSPredicate predicateWithFormat:@"name == %@", importUserName];
|
||||||
NSArray *users = [context executeFetchRequest:userFetchRequest error:&error];
|
NSArray *users = [context executeFetchRequest:userFetchRequest error:&error];
|
||||||
if (!users) {
|
if (!users) {
|
||||||
err( @"While looking for user: %@, error: %@", importUserName, [error fullDescription] );
|
MPError( error, @"While looking for user: %@.", importUserName );
|
||||||
return MPImportResultInternalError;
|
return MPImportResultInternalError;
|
||||||
}
|
}
|
||||||
if ([users count] > 1) {
|
if ([users count] > 1) {
|
||||||
@@ -673,7 +728,7 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
|
|||||||
siteFetchRequest.predicate = [NSPredicate predicateWithFormat:@"name == %@ AND user == %@", siteName, user];
|
siteFetchRequest.predicate = [NSPredicate predicateWithFormat:@"name == %@ AND user == %@", siteName, user];
|
||||||
NSArray *existingSites = [context executeFetchRequest:siteFetchRequest error:&error];
|
NSArray *existingSites = [context executeFetchRequest:siteFetchRequest error:&error];
|
||||||
if (!existingSites) {
|
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;
|
return MPImportResultInternalError;
|
||||||
}
|
}
|
||||||
if ([existingSites count]) {
|
if ([existingSites count]) {
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
[self.defaults registerDefaults:@{
|
[self.defaults registerDefaults:@{
|
||||||
NSStringFromSelector( @selector( askForReviews ) ) : @YES,
|
NSStringFromSelector( @selector( askForReviews ) ) : @YES,
|
||||||
|
|
||||||
NSStringFromSelector( @selector( sendInfo ) ) : @NO,
|
NSStringFromSelector( @selector( sendInfo ) ) : @YES,
|
||||||
NSStringFromSelector( @selector( rememberLogin ) ) : @NO,
|
NSStringFromSelector( @selector( rememberLogin ) ) : @NO,
|
||||||
NSStringFromSelector( @selector( hidePasswords ) ) : @NO,
|
NSStringFromSelector( @selector( hidePasswords ) ) : @NO,
|
||||||
NSStringFromSelector( @selector( checkInconsistency ) ): @NO,
|
NSStringFromSelector( @selector( checkInconsistency ) ): @NO,
|
||||||
|
|||||||
@@ -7,10 +7,10 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
#import "MPSiteEntity.h"
|
#import "MPSiteEntity+CoreDataClass.h"
|
||||||
#import "MPStoredSiteEntity.h"
|
#import "MPStoredSiteEntity+CoreDataClass.h"
|
||||||
#import "MPGeneratedSiteEntity.h"
|
#import "MPGeneratedSiteEntity+CoreDataClass.h"
|
||||||
#import "MPUserEntity.h"
|
#import "MPUserEntity+CoreDataClass.h"
|
||||||
#import "MPAlgorithm.h"
|
#import "MPAlgorithm.h"
|
||||||
#import "MPFixable.h"
|
#import "MPFixable.h"
|
||||||
|
|
||||||
@@ -22,6 +22,12 @@
|
|||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@interface NSManagedObject(MP)
|
||||||
|
|
||||||
|
- (NSManagedObjectID *)permanentObjectID;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
@interface MPSiteQuestionEntity(MP)
|
@interface MPSiteQuestionEntity(MP)
|
||||||
|
|
||||||
- (NSString *)resolveQuestionAnswerUsingKey:(MPKey *)key;
|
- (NSString *)resolveQuestionAnswerUsingKey:(MPKey *)key;
|
||||||
|
|||||||
@@ -16,25 +16,41 @@
|
|||||||
- (BOOL)saveToStore {
|
- (BOOL)saveToStore {
|
||||||
|
|
||||||
__block BOOL success = YES;
|
__block BOOL success = YES;
|
||||||
if ([self hasChanges]) {
|
if ([self hasChanges])
|
||||||
[self performBlockAndWait:^{
|
[self performBlockAndWait:^{
|
||||||
@try {
|
@try {
|
||||||
NSError *error = nil;
|
NSError *error = nil;
|
||||||
if (!(success = [self save:&error]))
|
if (!(success = [self save:&error]))
|
||||||
err( @"While saving: %@", [error fullDescription] );
|
MPError( error, @"While saving." );
|
||||||
}
|
}
|
||||||
@catch (NSException *exception) {
|
@catch (NSException *exception) {
|
||||||
success = NO;
|
success = NO;
|
||||||
err( @"While saving: %@", [exception fullDescription] );
|
err( @"While saving.\n%@", [exception fullDescription] );
|
||||||
}
|
}
|
||||||
}];
|
}];
|
||||||
}
|
|
||||||
|
|
||||||
return success && (!self.parentContext || [self.parentContext saveToStore]);
|
return success && (!self.parentContext || [self.parentContext saveToStore]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@implementation NSManagedObject(MP)
|
||||||
|
|
||||||
|
- (NSManagedObjectID *)permanentObjectID {
|
||||||
|
|
||||||
|
NSManagedObjectID *objectID = self.objectID;
|
||||||
|
if ([objectID isTemporaryID]) {
|
||||||
|
NSError *error = nil;
|
||||||
|
if (![self.managedObjectContext obtainPermanentIDsForObjects:@[ self ] error:&error])
|
||||||
|
MPError( error, @"Failed to obtain permanent object ID." );
|
||||||
|
objectID = self.objectID;
|
||||||
|
}
|
||||||
|
|
||||||
|
return objectID.isTemporaryID? nil: objectID;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
@implementation MPSiteQuestionEntity(MP)
|
@implementation MPSiteQuestionEntity(MP)
|
||||||
|
|
||||||
- (NSString *)resolveQuestionAnswerUsingKey:(MPKey *)key {
|
- (NSString *)resolveQuestionAnswerUsingKey:(MPKey *)key {
|
||||||
|
|||||||
20
platform-darwin/Source/MPGeneratedSiteEntity+CoreDataClass.h
Normal file
20
platform-darwin/Source/MPGeneratedSiteEntity+CoreDataClass.h
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
//
|
||||||
|
// MPGeneratedSiteEntity+CoreDataClass.h
|
||||||
|
// MasterPassword-iOS
|
||||||
|
//
|
||||||
|
// Created by Maarten Billemont on 2017-04-30.
|
||||||
|
// Copyright © 2017 Lyndir. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
#import "MPSiteEntity+CoreDataClass.h"
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@interface MPGeneratedSiteEntity : MPSiteEntity
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
||||||
|
|
||||||
|
#import "MPGeneratedSiteEntity+CoreDataProperties.h"
|
||||||
13
platform-darwin/Source/MPGeneratedSiteEntity+CoreDataClass.m
Normal file
13
platform-darwin/Source/MPGeneratedSiteEntity+CoreDataClass.m
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
//
|
||||||
|
// MPGeneratedSiteEntity+CoreDataClass.m
|
||||||
|
// MasterPassword-iOS
|
||||||
|
//
|
||||||
|
// Created by Maarten Billemont on 2017-04-30.
|
||||||
|
// Copyright © 2017 Lyndir. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "MPGeneratedSiteEntity+CoreDataClass.h"
|
||||||
|
|
||||||
|
@implementation MPGeneratedSiteEntity
|
||||||
|
|
||||||
|
@end
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
//
|
||||||
|
// MPGeneratedSiteEntity+CoreDataProperties.h
|
||||||
|
// MasterPassword-iOS
|
||||||
|
//
|
||||||
|
// Created by Maarten Billemont on 2017-04-30.
|
||||||
|
// Copyright © 2017 Lyndir. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "MPGeneratedSiteEntity+CoreDataClass.h"
|
||||||
|
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@interface MPGeneratedSiteEntity (CoreDataProperties)
|
||||||
|
|
||||||
|
+ (NSFetchRequest<MPGeneratedSiteEntity *> *)fetchRequest;
|
||||||
|
|
||||||
|
@property (nullable, nonatomic, copy) NSNumber *counter_;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
//
|
||||||
|
// MPGeneratedSiteEntity+CoreDataProperties.m
|
||||||
|
// MasterPassword-iOS
|
||||||
|
//
|
||||||
|
// Created by Maarten Billemont on 2017-04-30.
|
||||||
|
// Copyright © 2017 Lyndir. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "MPGeneratedSiteEntity+CoreDataProperties.h"
|
||||||
|
|
||||||
|
@implementation MPGeneratedSiteEntity (CoreDataProperties)
|
||||||
|
|
||||||
|
+ (NSFetchRequest<MPGeneratedSiteEntity *> *)fetchRequest {
|
||||||
|
return [[NSFetchRequest alloc] initWithEntityName:@"MPGeneratedSiteEntity"];
|
||||||
|
}
|
||||||
|
|
||||||
|
@dynamic counter_;
|
||||||
|
|
||||||
|
@end
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
//
|
|
||||||
// MPGeneratedSiteEntity.h
|
|
||||||
// MasterPassword-Mac
|
|
||||||
//
|
|
||||||
// Created by Maarten Billemont on 2014-09-21.
|
|
||||||
// Copyright (c) 2014 Lyndir. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
|
||||||
#import <CoreData/CoreData.h>
|
|
||||||
#import "MPSiteEntity.h"
|
|
||||||
|
|
||||||
@interface MPGeneratedSiteEntity : MPSiteEntity
|
|
||||||
|
|
||||||
@property(nonatomic, retain) NSNumber *counter_;
|
|
||||||
|
|
||||||
@end
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
//
|
|
||||||
// MPGeneratedSiteEntity.m
|
|
||||||
// MasterPassword-Mac
|
|
||||||
//
|
|
||||||
// Created by Maarten Billemont on 2014-09-21.
|
|
||||||
// Copyright (c) 2014 Lyndir. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import "MPGeneratedSiteEntity.h"
|
|
||||||
|
|
||||||
@implementation MPGeneratedSiteEntity
|
|
||||||
|
|
||||||
@dynamic counter_;
|
|
||||||
|
|
||||||
@end
|
|
||||||
22
platform-darwin/Source/MPSiteEntity+CoreDataClass.h
Normal file
22
platform-darwin/Source/MPSiteEntity+CoreDataClass.h
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
//
|
||||||
|
// MPSiteEntity+CoreDataClass.h
|
||||||
|
// MasterPassword-iOS
|
||||||
|
//
|
||||||
|
// Created by Maarten Billemont on 2017-04-30.
|
||||||
|
// Copyright © 2017 Lyndir. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
#import <CoreData/CoreData.h>
|
||||||
|
|
||||||
|
@class MPSiteQuestionEntity, MPUserEntity, NSObject;
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@interface MPSiteEntity : NSManagedObject
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
||||||
|
|
||||||
|
#import "MPSiteEntity+CoreDataProperties.h"
|
||||||
16
platform-darwin/Source/MPSiteEntity+CoreDataClass.m
Normal file
16
platform-darwin/Source/MPSiteEntity+CoreDataClass.m
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
//
|
||||||
|
// MPSiteEntity+CoreDataClass.m
|
||||||
|
// MasterPassword-iOS
|
||||||
|
//
|
||||||
|
// Created by Maarten Billemont on 2017-04-30.
|
||||||
|
// Copyright © 2017 Lyndir. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "MPSiteEntity+CoreDataClass.h"
|
||||||
|
#import "MPSiteQuestionEntity+CoreDataClass.h"
|
||||||
|
|
||||||
|
#import "MPUserEntity+CoreDataClass.h"
|
||||||
|
|
||||||
|
@implementation MPSiteEntity
|
||||||
|
|
||||||
|
@end
|
||||||
48
platform-darwin/Source/MPSiteEntity+CoreDataProperties.h
Normal file
48
platform-darwin/Source/MPSiteEntity+CoreDataProperties.h
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
//
|
||||||
|
// MPSiteEntity+CoreDataProperties.h
|
||||||
|
// MasterPassword-iOS
|
||||||
|
//
|
||||||
|
// Created by Maarten Billemont on 2017-04-30.
|
||||||
|
// Copyright © 2017 Lyndir. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "MPSiteEntity+CoreDataClass.h"
|
||||||
|
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@interface MPSiteEntity (CoreDataProperties)
|
||||||
|
|
||||||
|
+ (NSFetchRequest<MPSiteEntity *> *)fetchRequest;
|
||||||
|
|
||||||
|
@property (nullable, nonatomic, retain) NSObject *content;
|
||||||
|
@property (nullable, nonatomic, copy) NSDate *lastUsed;
|
||||||
|
@property (nullable, nonatomic, copy) NSNumber *loginGenerated_;
|
||||||
|
@property (nullable, nonatomic, copy) NSString *loginName;
|
||||||
|
@property (nullable, nonatomic, copy) NSString *name;
|
||||||
|
@property (nullable, nonatomic, copy) NSNumber *requiresExplicitMigration_;
|
||||||
|
@property (nullable, nonatomic, copy) NSNumber *type_;
|
||||||
|
@property (nullable, nonatomic, copy) NSNumber *uses_;
|
||||||
|
@property (nullable, nonatomic, copy) NSNumber *version_;
|
||||||
|
@property (nullable, nonatomic, copy) NSString *url;
|
||||||
|
@property (nullable, nonatomic, retain) NSOrderedSet<MPSiteQuestionEntity *> *questions;
|
||||||
|
@property (nullable, nonatomic, retain) MPUserEntity *user;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface MPSiteEntity (CoreDataGeneratedAccessors)
|
||||||
|
|
||||||
|
- (void)insertObject:(MPSiteQuestionEntity *)value inQuestionsAtIndex:(NSUInteger)idx;
|
||||||
|
- (void)removeObjectFromQuestionsAtIndex:(NSUInteger)idx;
|
||||||
|
- (void)insertQuestions:(NSArray<MPSiteQuestionEntity *> *)value atIndexes:(NSIndexSet *)indexes;
|
||||||
|
- (void)removeQuestionsAtIndexes:(NSIndexSet *)indexes;
|
||||||
|
- (void)replaceObjectInQuestionsAtIndex:(NSUInteger)idx withObject:(MPSiteQuestionEntity *)value;
|
||||||
|
- (void)replaceQuestionsAtIndexes:(NSIndexSet *)indexes withQuestions:(NSArray<MPSiteQuestionEntity *> *)values;
|
||||||
|
- (void)addQuestionsObject:(MPSiteQuestionEntity *)value;
|
||||||
|
- (void)removeQuestionsObject:(MPSiteQuestionEntity *)value;
|
||||||
|
- (void)addQuestions:(NSOrderedSet<MPSiteQuestionEntity *> *)values;
|
||||||
|
- (void)removeQuestions:(NSOrderedSet<MPSiteQuestionEntity *> *)values;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
||||||
30
platform-darwin/Source/MPSiteEntity+CoreDataProperties.m
Normal file
30
platform-darwin/Source/MPSiteEntity+CoreDataProperties.m
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
//
|
||||||
|
// MPSiteEntity+CoreDataProperties.m
|
||||||
|
// MasterPassword-iOS
|
||||||
|
//
|
||||||
|
// Created by Maarten Billemont on 2017-04-30.
|
||||||
|
// Copyright © 2017 Lyndir. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "MPSiteEntity+CoreDataProperties.h"
|
||||||
|
|
||||||
|
@implementation MPSiteEntity (CoreDataProperties)
|
||||||
|
|
||||||
|
+ (NSFetchRequest<MPSiteEntity *> *)fetchRequest {
|
||||||
|
return [[NSFetchRequest alloc] initWithEntityName:@"MPSiteEntity"];
|
||||||
|
}
|
||||||
|
|
||||||
|
@dynamic content;
|
||||||
|
@dynamic lastUsed;
|
||||||
|
@dynamic loginGenerated_;
|
||||||
|
@dynamic loginName;
|
||||||
|
@dynamic name;
|
||||||
|
@dynamic requiresExplicitMigration_;
|
||||||
|
@dynamic type_;
|
||||||
|
@dynamic uses_;
|
||||||
|
@dynamic version_;
|
||||||
|
@dynamic url;
|
||||||
|
@dynamic questions;
|
||||||
|
@dynamic user;
|
||||||
|
|
||||||
|
@end
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
//
|
|
||||||
// MPSiteEntity.h
|
|
||||||
// MasterPassword-Mac
|
|
||||||
//
|
|
||||||
// Created by Maarten Billemont on 2014-09-21.
|
|
||||||
// Copyright (c) 2014 Lyndir. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
|
||||||
#import <CoreData/CoreData.h>
|
|
||||||
|
|
||||||
@class MPSiteQuestionEntity, MPUserEntity;
|
|
||||||
|
|
||||||
@interface MPSiteEntity : NSManagedObject
|
|
||||||
|
|
||||||
//@property (nonatomic, retain) id content; // Hide here, reveal in MPStoredSiteEntity
|
|
||||||
@property(nonatomic, retain) NSDate *lastUsed;
|
|
||||||
@property(nonatomic, retain) NSNumber *loginGenerated_;
|
|
||||||
@property(nonatomic, retain) NSString *loginName;
|
|
||||||
@property(nonatomic, retain) NSString *name;
|
|
||||||
@property(nonatomic, retain) NSNumber *requiresExplicitMigration_;
|
|
||||||
@property(nonatomic, retain) NSNumber *type_;
|
|
||||||
@property(nonatomic, retain) NSNumber *uses_;
|
|
||||||
@property(nonatomic, retain) NSNumber *version_;
|
|
||||||
@property(nonatomic, retain) NSOrderedSet *questions;
|
|
||||||
@property(nonatomic, retain) MPUserEntity *user;
|
|
||||||
@end
|
|
||||||
|
|
||||||
@interface MPSiteEntity(CoreDataGeneratedAccessors)
|
|
||||||
|
|
||||||
- (void)insertObject:(MPSiteQuestionEntity *)value inQuestionsAtIndex:(NSUInteger)idx;
|
|
||||||
- (void)removeObjectFromQuestionsAtIndex:(NSUInteger)idx;
|
|
||||||
- (void)insertQuestions:(NSArray *)value atIndexes:(NSIndexSet *)indexes;
|
|
||||||
- (void)removeQuestionsAtIndexes:(NSIndexSet *)indexes;
|
|
||||||
- (void)replaceObjectInQuestionsAtIndex:(NSUInteger)idx withObject:(MPSiteQuestionEntity *)value;
|
|
||||||
- (void)replaceQuestionsAtIndexes:(NSIndexSet *)indexes withQuestions:(NSArray *)values;
|
|
||||||
- (void)addQuestionsObject:(MPSiteQuestionEntity *)value;
|
|
||||||
- (void)removeQuestionsObject:(MPSiteQuestionEntity *)value;
|
|
||||||
- (void)addQuestions:(NSOrderedSet *)values;
|
|
||||||
- (void)removeQuestions:(NSOrderedSet *)values;
|
|
||||||
@end
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
//
|
|
||||||
// MPSiteEntity.m
|
|
||||||
// MasterPassword-Mac
|
|
||||||
//
|
|
||||||
// Created by Maarten Billemont on 2014-09-21.
|
|
||||||
// Copyright (c) 2014 Lyndir. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import "MPSiteEntity.h"
|
|
||||||
#import "MPSiteQuestionEntity.h"
|
|
||||||
#import "MPUserEntity.h"
|
|
||||||
|
|
||||||
@implementation MPSiteEntity
|
|
||||||
|
|
||||||
//@dynamic content;
|
|
||||||
@dynamic lastUsed;
|
|
||||||
@dynamic loginGenerated_;
|
|
||||||
@dynamic loginName;
|
|
||||||
@dynamic name;
|
|
||||||
@dynamic requiresExplicitMigration_;
|
|
||||||
@dynamic type_;
|
|
||||||
@dynamic uses_;
|
|
||||||
@dynamic version_;
|
|
||||||
@dynamic questions;
|
|
||||||
@dynamic user;
|
|
||||||
|
|
||||||
@end
|
|
||||||
22
platform-darwin/Source/MPSiteQuestionEntity+CoreDataClass.h
Normal file
22
platform-darwin/Source/MPSiteQuestionEntity+CoreDataClass.h
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
//
|
||||||
|
// MPSiteQuestionEntity+CoreDataClass.h
|
||||||
|
// MasterPassword-iOS
|
||||||
|
//
|
||||||
|
// Created by Maarten Billemont on 2017-04-30.
|
||||||
|
// Copyright © 2017 Lyndir. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
#import <CoreData/CoreData.h>
|
||||||
|
|
||||||
|
@class MPSiteEntity;
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@interface MPSiteQuestionEntity : NSManagedObject
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
||||||
|
|
||||||
|
#import "MPSiteQuestionEntity+CoreDataProperties.h"
|
||||||
14
platform-darwin/Source/MPSiteQuestionEntity+CoreDataClass.m
Normal file
14
platform-darwin/Source/MPSiteQuestionEntity+CoreDataClass.m
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
//
|
||||||
|
// MPSiteQuestionEntity+CoreDataClass.m
|
||||||
|
// MasterPassword-iOS
|
||||||
|
//
|
||||||
|
// Created by Maarten Billemont on 2017-04-30.
|
||||||
|
// Copyright © 2017 Lyndir. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "MPSiteQuestionEntity+CoreDataClass.h"
|
||||||
|
#import "MPSiteEntity+CoreDataClass.h"
|
||||||
|
|
||||||
|
@implementation MPSiteQuestionEntity
|
||||||
|
|
||||||
|
@end
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
//
|
||||||
|
// MPSiteQuestionEntity+CoreDataProperties.h
|
||||||
|
// MasterPassword-iOS
|
||||||
|
//
|
||||||
|
// Created by Maarten Billemont on 2017-04-30.
|
||||||
|
// Copyright © 2017 Lyndir. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "MPSiteQuestionEntity+CoreDataClass.h"
|
||||||
|
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@interface MPSiteQuestionEntity (CoreDataProperties)
|
||||||
|
|
||||||
|
+ (NSFetchRequest<MPSiteQuestionEntity *> *)fetchRequest;
|
||||||
|
|
||||||
|
@property (nullable, nonatomic, copy) NSString *keyword;
|
||||||
|
@property (nullable, nonatomic, retain) MPSiteEntity *site;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
//
|
||||||
|
// MPSiteQuestionEntity+CoreDataProperties.m
|
||||||
|
// MasterPassword-iOS
|
||||||
|
//
|
||||||
|
// Created by Maarten Billemont on 2017-04-30.
|
||||||
|
// Copyright © 2017 Lyndir. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "MPSiteQuestionEntity+CoreDataProperties.h"
|
||||||
|
|
||||||
|
@implementation MPSiteQuestionEntity (CoreDataProperties)
|
||||||
|
|
||||||
|
+ (NSFetchRequest<MPSiteQuestionEntity *> *)fetchRequest {
|
||||||
|
return [[NSFetchRequest alloc] initWithEntityName:@"MPSiteQuestionEntity"];
|
||||||
|
}
|
||||||
|
|
||||||
|
@dynamic keyword;
|
||||||
|
@dynamic site;
|
||||||
|
|
||||||
|
@end
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
//
|
|
||||||
// MPSiteQuestionEntity.h
|
|
||||||
// MasterPassword-iOS
|
|
||||||
//
|
|
||||||
// Created by Maarten Billemont on 2014-09-27.
|
|
||||||
// Copyright (c) 2014 Lyndir. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
|
||||||
#import <CoreData/CoreData.h>
|
|
||||||
|
|
||||||
@class MPSiteEntity;
|
|
||||||
|
|
||||||
@interface MPSiteQuestionEntity : NSManagedObject
|
|
||||||
|
|
||||||
@property(nonatomic, retain) NSString *keyword;
|
|
||||||
@property(nonatomic, retain) MPSiteEntity *site;
|
|
||||||
|
|
||||||
@end
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
//
|
|
||||||
// MPSiteQuestionEntity.m
|
|
||||||
// MasterPassword-iOS
|
|
||||||
//
|
|
||||||
// Created by Maarten Billemont on 2014-09-27.
|
|
||||||
// Copyright (c) 2014 Lyndir. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import "MPSiteQuestionEntity.h"
|
|
||||||
#import "MPSiteEntity.h"
|
|
||||||
|
|
||||||
@implementation MPSiteQuestionEntity
|
|
||||||
|
|
||||||
@dynamic keyword;
|
|
||||||
@dynamic site;
|
|
||||||
|
|
||||||
@end
|
|
||||||
22
platform-darwin/Source/MPStoredSiteEntity+CoreDataClass.h
Normal file
22
platform-darwin/Source/MPStoredSiteEntity+CoreDataClass.h
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
//
|
||||||
|
// MPStoredSiteEntity+CoreDataClass.h
|
||||||
|
// MasterPassword-iOS
|
||||||
|
//
|
||||||
|
// Created by Maarten Billemont on 2017-04-30.
|
||||||
|
// Copyright © 2017 Lyndir. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
#import "MPSiteEntity+CoreDataClass.h"
|
||||||
|
|
||||||
|
@class NSObject;
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@interface MPStoredSiteEntity : MPSiteEntity
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
||||||
|
|
||||||
|
#import "MPStoredSiteEntity+CoreDataProperties.h"
|
||||||
13
platform-darwin/Source/MPStoredSiteEntity+CoreDataClass.m
Normal file
13
platform-darwin/Source/MPStoredSiteEntity+CoreDataClass.m
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
//
|
||||||
|
// MPStoredSiteEntity+CoreDataClass.m
|
||||||
|
// MasterPassword-iOS
|
||||||
|
//
|
||||||
|
// Created by Maarten Billemont on 2017-04-30.
|
||||||
|
// Copyright © 2017 Lyndir. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "MPStoredSiteEntity+CoreDataClass.h"
|
||||||
|
|
||||||
|
@implementation MPStoredSiteEntity
|
||||||
|
|
||||||
|
@end
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
//
|
||||||
|
// MPStoredSiteEntity+CoreDataProperties.h
|
||||||
|
// MasterPassword-iOS
|
||||||
|
//
|
||||||
|
// Created by Maarten Billemont on 2017-05-01.
|
||||||
|
// Copyright © 2017 Lyndir. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "MPStoredSiteEntity+CoreDataClass.h"
|
||||||
|
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@interface MPStoredSiteEntity (CoreDataProperties)
|
||||||
|
|
||||||
|
+ (NSFetchRequest<MPStoredSiteEntity *> *)fetchRequest;
|
||||||
|
|
||||||
|
@property (nullable, nonatomic, retain) NSData *contentObject;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
//
|
||||||
|
// MPStoredSiteEntity+CoreDataProperties.m
|
||||||
|
// MasterPassword-iOS
|
||||||
|
//
|
||||||
|
// Created by Maarten Billemont on 2017-05-01.
|
||||||
|
// Copyright © 2017 Lyndir. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "MPStoredSiteEntity+CoreDataProperties.h"
|
||||||
|
|
||||||
|
@implementation MPStoredSiteEntity (CoreDataProperties)
|
||||||
|
|
||||||
|
+ (NSFetchRequest<MPStoredSiteEntity *> *)fetchRequest {
|
||||||
|
return [[NSFetchRequest alloc] initWithEntityName:@"MPStoredSiteEntity"];
|
||||||
|
}
|
||||||
|
|
||||||
|
@dynamic contentObject;
|
||||||
|
|
||||||
|
@end
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
//
|
|
||||||
// MPStoredSiteEntity.h
|
|
||||||
// MasterPassword-Mac
|
|
||||||
//
|
|
||||||
// Created by Maarten Billemont on 2014-09-21.
|
|
||||||
// Copyright (c) 2014 Lyndir. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
|
||||||
#import <CoreData/CoreData.h>
|
|
||||||
#import "MPSiteEntity.h"
|
|
||||||
|
|
||||||
@interface MPStoredSiteEntity : MPSiteEntity
|
|
||||||
|
|
||||||
@property(nonatomic, retain) NSData *contentObject;
|
|
||||||
|
|
||||||
@end
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
//
|
|
||||||
// MPStoredSiteEntity.m
|
|
||||||
// MasterPassword-Mac
|
|
||||||
//
|
|
||||||
// Created by Maarten Billemont on 2014-09-21.
|
|
||||||
// Copyright (c) 2014 Lyndir. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import "MPStoredSiteEntity.h"
|
|
||||||
|
|
||||||
@implementation MPStoredSiteEntity
|
|
||||||
|
|
||||||
@dynamic contentObject;
|
|
||||||
|
|
||||||
@end
|
|
||||||
@@ -6,8 +6,12 @@
|
|||||||
// Copyright (c) 2012 Lyndir. All rights reserved.
|
// Copyright (c) 2012 Lyndir. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#import <Crashlytics/Crashlytics.h>
|
||||||
|
#import <Crashlytics/Answers.h>
|
||||||
|
|
||||||
__BEGIN_DECLS
|
__BEGIN_DECLS
|
||||||
extern NSString *const MPErrorDomain;
|
extern NSString *const MPErrorDomain;
|
||||||
|
extern NSInteger const MPErrorHangCode;
|
||||||
|
|
||||||
extern NSString *const MPSignedInNotification;
|
extern NSString *const MPSignedInNotification;
|
||||||
extern NSString *const MPSignedOutNotification;
|
extern NSString *const MPSignedOutNotification;
|
||||||
@@ -19,4 +23,21 @@ extern NSString *const MPFoundInconsistenciesNotification;
|
|||||||
|
|
||||||
extern NSString *const MPSitesImportedNotificationUserKey;
|
extern NSString *const MPSitesImportedNotificationUserKey;
|
||||||
extern NSString *const MPInconsistenciesFixResultUserKey;
|
extern NSString *const MPInconsistenciesFixResultUserKey;
|
||||||
|
|
||||||
__END_DECLS
|
__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
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#import "MPTypes.h"
|
#import "MPTypes.h"
|
||||||
|
|
||||||
NSString *const MPErrorDomain = @"MPErrorDomain";
|
NSString *const MPErrorDomain = @"MPErrorDomain";
|
||||||
|
NSInteger const MPErrorHangCode = 1;
|
||||||
|
|
||||||
NSString *const MPSignedInNotification = @"MPSignedInNotification";
|
NSString *const MPSignedInNotification = @"MPSignedInNotification";
|
||||||
NSString *const MPSignedOutNotification = @"MPSignedOutNotification";
|
NSString *const MPSignedOutNotification = @"MPSignedOutNotification";
|
||||||
|
|||||||
22
platform-darwin/Source/MPUserEntity+CoreDataClass.h
Normal file
22
platform-darwin/Source/MPUserEntity+CoreDataClass.h
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
//
|
||||||
|
// MPUserEntity+CoreDataClass.h
|
||||||
|
// MasterPassword-iOS
|
||||||
|
//
|
||||||
|
// Created by Maarten Billemont on 2017-04-30.
|
||||||
|
// Copyright © 2017 Lyndir. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
#import <CoreData/CoreData.h>
|
||||||
|
|
||||||
|
@class MPSiteEntity;
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@interface MPUserEntity : NSManagedObject
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
||||||
|
|
||||||
|
#import "MPUserEntity+CoreDataProperties.h"
|
||||||
14
platform-darwin/Source/MPUserEntity+CoreDataClass.m
Normal file
14
platform-darwin/Source/MPUserEntity+CoreDataClass.m
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
//
|
||||||
|
// MPUserEntity+CoreDataClass.m
|
||||||
|
// MasterPassword-iOS
|
||||||
|
//
|
||||||
|
// Created by Maarten Billemont on 2017-04-30.
|
||||||
|
// Copyright © 2017 Lyndir. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "MPUserEntity+CoreDataClass.h"
|
||||||
|
#import "MPSiteEntity+CoreDataClass.h"
|
||||||
|
|
||||||
|
@implementation MPUserEntity
|
||||||
|
|
||||||
|
@end
|
||||||
39
platform-darwin/Source/MPUserEntity+CoreDataProperties.h
Normal file
39
platform-darwin/Source/MPUserEntity+CoreDataProperties.h
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
//
|
||||||
|
// MPUserEntity+CoreDataProperties.h
|
||||||
|
// MasterPassword-iOS
|
||||||
|
//
|
||||||
|
// Created by Maarten Billemont on 2017-04-30.
|
||||||
|
// Copyright © 2017 Lyndir. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "MPUserEntity+CoreDataClass.h"
|
||||||
|
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@interface MPUserEntity (CoreDataProperties)
|
||||||
|
|
||||||
|
+ (NSFetchRequest<MPUserEntity *> *)fetchRequest;
|
||||||
|
|
||||||
|
@property (nullable, nonatomic, copy) NSNumber *avatar_;
|
||||||
|
@property (nullable, nonatomic, copy) NSNumber *defaultType_;
|
||||||
|
@property (nullable, nonatomic, retain) NSData *keyID;
|
||||||
|
@property (nullable, nonatomic, copy) NSDate *lastUsed;
|
||||||
|
@property (nullable, nonatomic, copy) NSString *name;
|
||||||
|
@property (nullable, nonatomic, copy) NSNumber *saveKey_;
|
||||||
|
@property (nullable, nonatomic, copy) NSNumber *touchID_;
|
||||||
|
@property (nullable, nonatomic, copy) NSNumber *version_;
|
||||||
|
@property (nullable, nonatomic, retain) NSSet<MPSiteEntity *> *sites;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface MPUserEntity (CoreDataGeneratedAccessors)
|
||||||
|
|
||||||
|
- (void)addSitesObject:(MPSiteEntity *)value;
|
||||||
|
- (void)removeSitesObject:(MPSiteEntity *)value;
|
||||||
|
- (void)addSites:(NSSet<MPSiteEntity *> *)values;
|
||||||
|
- (void)removeSites:(NSSet<MPSiteEntity *> *)values;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
||||||
27
platform-darwin/Source/MPUserEntity+CoreDataProperties.m
Normal file
27
platform-darwin/Source/MPUserEntity+CoreDataProperties.m
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
//
|
||||||
|
// MPUserEntity+CoreDataProperties.m
|
||||||
|
// MasterPassword-iOS
|
||||||
|
//
|
||||||
|
// Created by Maarten Billemont on 2017-04-30.
|
||||||
|
// Copyright © 2017 Lyndir. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "MPUserEntity+CoreDataProperties.h"
|
||||||
|
|
||||||
|
@implementation MPUserEntity (CoreDataProperties)
|
||||||
|
|
||||||
|
+ (NSFetchRequest<MPUserEntity *> *)fetchRequest {
|
||||||
|
return [[NSFetchRequest alloc] initWithEntityName:@"MPUserEntity"];
|
||||||
|
}
|
||||||
|
|
||||||
|
@dynamic avatar_;
|
||||||
|
@dynamic defaultType_;
|
||||||
|
@dynamic keyID;
|
||||||
|
@dynamic lastUsed;
|
||||||
|
@dynamic name;
|
||||||
|
@dynamic saveKey_;
|
||||||
|
@dynamic touchID_;
|
||||||
|
@dynamic version_;
|
||||||
|
@dynamic sites;
|
||||||
|
|
||||||
|
@end
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
//
|
|
||||||
// MPUserEntity.h
|
|
||||||
// MasterPassword-Mac
|
|
||||||
//
|
|
||||||
// Created by Maarten Billemont on 2014-09-21.
|
|
||||||
// Copyright (c) 2014 Lyndir. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
|
||||||
#import <CoreData/CoreData.h>
|
|
||||||
|
|
||||||
@class MPSiteEntity;
|
|
||||||
|
|
||||||
@interface MPUserEntity : NSManagedObject
|
|
||||||
|
|
||||||
@property(nonatomic, retain) NSNumber *avatar_;
|
|
||||||
@property(nonatomic, retain) NSNumber *defaultType_;
|
|
||||||
@property(nonatomic, retain) NSData *keyID;
|
|
||||||
@property(nonatomic, retain) NSDate *lastUsed;
|
|
||||||
@property(nonatomic, retain) NSString *name;
|
|
||||||
@property(nonatomic, retain) NSNumber *saveKey_;
|
|
||||||
@property(nonatomic, retain) NSNumber *touchID_;
|
|
||||||
@property(nonatomic, retain) NSNumber *version_;
|
|
||||||
@property(nonatomic, retain) NSSet *sites;
|
|
||||||
@end
|
|
||||||
|
|
||||||
@interface MPUserEntity(CoreDataGeneratedAccessors)
|
|
||||||
|
|
||||||
- (void)addSitesObject:(MPSiteEntity *)value;
|
|
||||||
- (void)removeSitesObject:(MPSiteEntity *)value;
|
|
||||||
- (void)addSites:(NSSet *)values;
|
|
||||||
- (void)removeSites:(NSSet *)values;
|
|
||||||
|
|
||||||
@end
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
//
|
|
||||||
// MPUserEntity.m
|
|
||||||
// MasterPassword-Mac
|
|
||||||
//
|
|
||||||
// Created by Maarten Billemont on 2014-09-21.
|
|
||||||
// Copyright (c) 2014 Lyndir. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import "MPUserEntity.h"
|
|
||||||
#import "MPSiteEntity.h"
|
|
||||||
|
|
||||||
@implementation MPUserEntity
|
|
||||||
|
|
||||||
@dynamic avatar_;
|
|
||||||
@dynamic defaultType_;
|
|
||||||
@dynamic keyID;
|
|
||||||
@dynamic lastUsed;
|
|
||||||
@dynamic name;
|
|
||||||
@dynamic saveKey_;
|
|
||||||
@dynamic touchID_;
|
|
||||||
@dynamic version_;
|
|
||||||
@dynamic sites;
|
|
||||||
|
|
||||||
@end
|
|
||||||
@@ -78,7 +78,6 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
|
|||||||
[[Crashlytics sharedInstance] setUserIdentifier:[PearlKeyChain deviceIdentifier]];
|
[[Crashlytics sharedInstance] setUserIdentifier:[PearlKeyChain deviceIdentifier]];
|
||||||
[[Crashlytics sharedInstance] setObjectValue:[PearlKeyChain deviceIdentifier] forKey:@"deviceIdentifier"];
|
[[Crashlytics sharedInstance] setObjectValue:[PearlKeyChain deviceIdentifier] forKey:@"deviceIdentifier"];
|
||||||
[[Crashlytics sharedInstance] setUserName:@"Anonymous"];
|
[[Crashlytics sharedInstance] setUserName:@"Anonymous"];
|
||||||
[[Crashlytics sharedInstance] setObjectValue:@"Anonymous" forKey:@"username"];
|
|
||||||
[Crashlytics startWithAPIKey:crashlyticsAPIKey];
|
[Crashlytics startWithAPIKey:crashlyticsAPIKey];
|
||||||
[[PearlLogger get] registerListener:^BOOL(PearlLogMessage *message) {
|
[[PearlLogger get] registerListener:^BOOL(PearlLogMessage *message) {
|
||||||
PearlLogLevel level = PearlLogLevelInfo;
|
PearlLogLevel level = PearlLogLevelInfo;
|
||||||
@@ -172,17 +171,17 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
|
|||||||
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender {
|
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender {
|
||||||
// Save changes in the application's managed object context before the application terminates.
|
// Save changes in the application's managed object context before the application terminates.
|
||||||
|
|
||||||
NSManagedObjectContext *context = [MPMacAppDelegate managedObjectContextForMainThreadIfReady];
|
NSManagedObjectContext *mainContext = [MPMacAppDelegate managedObjectContextForMainThreadIfReady];
|
||||||
if (!context)
|
if (!mainContext)
|
||||||
return NSTerminateNow;
|
return NSTerminateNow;
|
||||||
|
|
||||||
if (![context commitEditing])
|
if (![mainContext commitEditing])
|
||||||
return NSTerminateCancel;
|
return NSTerminateCancel;
|
||||||
|
|
||||||
if (![context hasChanges])
|
if (![mainContext hasChanges])
|
||||||
return NSTerminateNow;
|
return NSTerminateNow;
|
||||||
|
|
||||||
[context saveToStore];
|
[mainContext saveToStore];
|
||||||
return NSTerminateNow;
|
return NSTerminateNow;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -272,7 +271,7 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
|
|||||||
[[[NSURLSession sharedSession] dataTaskWithURL:url completionHandler:
|
[[[NSURLSession sharedSession] dataTaskWithURL:url completionHandler:
|
||||||
^(NSData *importedSitesData, NSURLResponse *response, NSError *error) {
|
^(NSData *importedSitesData, NSURLResponse *response, NSError *error) {
|
||||||
if (error)
|
if (error)
|
||||||
err( @"While reading imported sites from %@: %@", url, [error fullDescription] );
|
MPError( error, @"While reading imported sites from %@.", url );
|
||||||
if (!importedSitesData)
|
if (!importedSitesData)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -389,20 +388,16 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
NSString *name = [(NSSecureTextField *)alert.accessoryView stringValue];
|
NSString *name = [(NSSecureTextField *)alert.accessoryView stringValue];
|
||||||
[MPMacAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *moc) {
|
[MPMacAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
|
||||||
MPUserEntity *newUser = [NSEntityDescription insertNewObjectForEntityForName:NSStringFromClass( [MPUserEntity class] )
|
MPUserEntity *newUser = [NSEntityDescription insertNewObjectForEntityForName:NSStringFromClass( [MPUserEntity class] )
|
||||||
inManagedObjectContext:moc];
|
inManagedObjectContext:context];
|
||||||
newUser.name = name;
|
newUser.name = name;
|
||||||
[moc saveToStore];
|
[context saveToStore];
|
||||||
NSError *error = nil;
|
|
||||||
if (![moc obtainPermanentIDsForObjects:@[ newUser ] error:&error])
|
|
||||||
err( @"Failed to obtain permanent object ID for new user: %@", [error fullDescription] );
|
|
||||||
|
|
||||||
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
|
|
||||||
[self updateUsers];
|
|
||||||
[self setActiveUser:newUser];
|
[self setActiveUser:newUser];
|
||||||
|
|
||||||
|
PearlMainQueue( ^{
|
||||||
[self showPasswordWindow:nil];
|
[self showPasswordWindow:nil];
|
||||||
}];
|
} );
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -416,10 +411,10 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
|
|||||||
if ([alert runModal] != NSAlertFirstButtonReturn)
|
if ([alert runModal] != NSAlertFirstButtonReturn)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
[MPMacAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *moc) {
|
[MPMacAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
|
||||||
[moc deleteObject:[self activeUserInContext:moc]];
|
[context deleteObject:[self activeUserInContext:context]];
|
||||||
[self setActiveUser:nil];
|
[self setActiveUser:nil];
|
||||||
[moc saveToStore];
|
[context saveToStore];
|
||||||
|
|
||||||
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
|
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
|
||||||
[self updateUsers];
|
[self updateUsers];
|
||||||
@@ -516,20 +511,23 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
|
|||||||
|
|
||||||
NSError *coordinateError = nil;
|
NSError *coordinateError = nil;
|
||||||
NSString *exportedSites = [self exportSitesRevealPasswords:revealPasswords];
|
NSString *exportedSites = [self exportSitesRevealPasswords:revealPasswords];
|
||||||
[[[NSFileCoordinator alloc] initWithFilePresenter:nil] coordinateWritingItemAtURL:savePanel.URL options:0 error:&coordinateError
|
[[[NSFileCoordinator alloc] initWithFilePresenter:nil] coordinateWritingItemAtURL:savePanel.URL options:0
|
||||||
byAccessor:^(NSURL *newURL) {
|
error:&coordinateError byAccessor:
|
||||||
|
^(NSURL *newURL) {
|
||||||
NSError *writeError = nil;
|
NSError *writeError = nil;
|
||||||
if (![exportedSites writeToURL:newURL atomically:NO
|
if (![exportedSites writeToURL:newURL atomically:NO encoding:NSUTF8StringEncoding error:&writeError])
|
||||||
encoding:NSUTF8StringEncoding
|
MPError( writeError, @"Could not write to the export file." );
|
||||||
error:&writeError])
|
|
||||||
PearlMainQueue( ^{
|
PearlMainQueue( ^{
|
||||||
[[NSAlert alertWithError:writeError] runModal];
|
[[NSAlert alertWithError:writeError] runModal];
|
||||||
} );
|
} );
|
||||||
}];
|
}];
|
||||||
if (coordinateError)
|
if (coordinateError) {
|
||||||
|
MPError( coordinateError, @"Write access to the export file could not be obtained." );
|
||||||
PearlMainQueue( ^{
|
PearlMainQueue( ^{
|
||||||
[[NSAlert alertWithError:coordinateError] runModal];
|
[[NSAlert alertWithError:coordinateError] runModal];
|
||||||
} );
|
} );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)updateUsers {
|
- (void)updateUsers {
|
||||||
@@ -567,7 +565,7 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
|
|||||||
fetchRequest.sortDescriptors = @[ [NSSortDescriptor sortDescriptorWithKey:@"lastUsed" ascending:NO] ];
|
fetchRequest.sortDescriptors = @[ [NSSortDescriptor sortDescriptorWithKey:@"lastUsed" ascending:NO] ];
|
||||||
NSArray *users = [mainContext executeFetchRequest:fetchRequest error:&error];
|
NSArray *users = [mainContext executeFetchRequest:fetchRequest error:&error];
|
||||||
if (!users)
|
if (!users)
|
||||||
err( @"Failed to load users: %@", [error fullDescription] );
|
MPError( error, @"Failed to load users." );
|
||||||
|
|
||||||
if (![users count]) {
|
if (![users count]) {
|
||||||
NSMenuItem *noUsersItem = [self.usersItem.submenu addItemWithTitle:@"No users" action:NULL keyEquivalent:@""];
|
NSMenuItem *noUsersItem = [self.usersItem.submenu addItemWithTitle:@"No users" action:NULL keyEquivalent:@""];
|
||||||
@@ -579,7 +577,7 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
|
|||||||
for (MPUserEntity *user in users) {
|
for (MPUserEntity *user in users) {
|
||||||
NSMenuItem *userItem = [[NSMenuItem alloc] initWithTitle:user.name action:@selector( selectUser: ) keyEquivalent:@""];
|
NSMenuItem *userItem = [[NSMenuItem alloc] initWithTitle:user.name action:@selector( selectUser: ) keyEquivalent:@""];
|
||||||
[userItem setTarget:self];
|
[userItem setTarget:self];
|
||||||
[userItem setRepresentedObject:[user objectID]];
|
[userItem setRepresentedObject:user.permanentObjectID];
|
||||||
[[self.usersItem submenu] addItem:userItem];
|
[[self.usersItem submenu] addItem:userItem];
|
||||||
|
|
||||||
if (!mainActiveUser && [user.name isEqualToString:[MPMacConfig get].usedUserName])
|
if (!mainActiveUser && [user.name isEqualToString:[MPMacConfig get].usedUserName])
|
||||||
|
|||||||
@@ -160,10 +160,10 @@
|
|||||||
- (IBAction)doUnlockUser:(id)sender {
|
- (IBAction)doUnlockUser:(id)sender {
|
||||||
|
|
||||||
[self.progressView startAnimation:self];
|
[self.progressView startAnimation:self];
|
||||||
[MPMacAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *moc) {
|
[MPMacAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
|
||||||
MPUserEntity *activeUser = [[MPMacAppDelegate get] activeUserInContext:moc];
|
MPUserEntity *activeUser = [[MPMacAppDelegate get] activeUserInContext:context];
|
||||||
NSString *userName = activeUser.name;
|
NSString *userName = activeUser.name;
|
||||||
BOOL success = [[MPMacAppDelegate get] signInAsUser:activeUser saveInContext:moc usingMasterPassword:self.masterPassword];
|
BOOL success = [[MPMacAppDelegate get] signInAsUser:activeUser saveInContext:context usingMasterPassword:self.masterPassword];
|
||||||
|
|
||||||
PearlMainQueue( ^{
|
PearlMainQueue( ^{
|
||||||
self.masterPassword = nil;
|
self.masterPassword = nil;
|
||||||
@@ -547,15 +547,15 @@
|
|||||||
|
|
||||||
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:NSStringFromClass( [MPSiteEntity class] )];
|
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:NSStringFromClass( [MPSiteEntity class] )];
|
||||||
fetchRequest.sortDescriptors = @[ [[NSSortDescriptor alloc] initWithKey:@"lastUsed" ascending:NO] ];
|
fetchRequest.sortDescriptors = @[ [[NSSortDescriptor alloc] initWithKey:@"lastUsed" ascending:NO] ];
|
||||||
fetchRequest.predicate = [NSPredicate predicateWithFormat:@"(%@ == '' OR name LIKE[cd] %@) AND user == %@",
|
fetchRequest.predicate =
|
||||||
queryPattern, queryPattern, [MPMacAppDelegate get].activeUserOID];
|
[NSPredicate predicateWithFormat:@"name LIKE[cd] %@ AND user == %@", queryPattern, [MPMacAppDelegate get].activeUserOID];
|
||||||
prof_rewind( @"fetchRequest" );
|
prof_rewind( @"fetchRequest" );
|
||||||
|
|
||||||
NSError *error = nil;
|
NSError *error = nil;
|
||||||
NSArray *siteResults = [context executeFetchRequest:fetchRequest error:&error];
|
NSArray *siteResults = [context executeFetchRequest:fetchRequest error:&error];
|
||||||
if (!siteResults) {
|
if (!siteResults) {
|
||||||
prof_finish( @"executeFetchRequest: %@ // %@", fetchRequest.predicate, [error fullDescription] );
|
prof_finish( @"executeFetchRequest: %@ // %@", fetchRequest.predicate, [error fullDescription] );
|
||||||
err( @"While fetching sites for completion: %@", [error fullDescription] );
|
MPError( error, @"While fetching sites for completion." );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
prof_rewind( @"executeFetchRequest: %@", fetchRequest.predicate );
|
prof_rewind( @"executeFetchRequest: %@", fetchRequest.predicate );
|
||||||
@@ -633,9 +633,9 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
[MPMacAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *moc) {
|
[MPMacAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
|
||||||
[[self.selectedSite entityInContext:moc] use];
|
[[self.selectedSite entityInContext:context] use];
|
||||||
[moc saveToStore];
|
[context saveToStore];
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -52,9 +52,9 @@
|
|||||||
|
|
||||||
- (void)setEntity:(MPSiteEntity *)entity fuzzyGroups:(NSArray *)fuzzyGroups {
|
- (void)setEntity:(MPSiteEntity *)entity fuzzyGroups:(NSArray *)fuzzyGroups {
|
||||||
|
|
||||||
if ([_entityOID isEqual:entity.objectID])
|
if ([_entityOID isEqual:entity.permanentObjectID])
|
||||||
return;
|
return;
|
||||||
_entityOID = entity.objectID;
|
_entityOID = entity.permanentObjectID;
|
||||||
|
|
||||||
NSString *siteName = entity.name;
|
NSString *siteName = entity.name;
|
||||||
NSMutableAttributedString *attributedSiteName = [[NSMutableAttributedString alloc] initWithString:siteName];
|
NSMutableAttributedString *attributedSiteName = [[NSMutableAttributedString alloc] initWithString:siteName];
|
||||||
@@ -115,7 +115,7 @@
|
|||||||
NSError *error;
|
NSError *error;
|
||||||
MPSiteEntity *entity = (MPSiteEntity *)[moc existingObjectWithID:_entityOID error:&error];
|
MPSiteEntity *entity = (MPSiteEntity *)[moc existingObjectWithID:_entityOID error:&error];
|
||||||
if (!entity)
|
if (!entity)
|
||||||
err( @"Couldn't retrieve active site: %@", [error fullDescription] );
|
MPError( error, @"Couldn't retrieve active site." );
|
||||||
|
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,6 @@
|
|||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<dict>
|
<dict>
|
||||||
<key>_XCCurrentVersionName</key>
|
<key>_XCCurrentVersionName</key>
|
||||||
<string>MasterPassword 8.xcdatamodel</string>
|
<string>MasterPassword 9.xcdatamodel</string>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|||||||
@@ -0,0 +1,57 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||||
|
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="12141" systemVersion="16E195" minimumToolsVersion="Xcode 7.3" sourceLanguage="Objective-C" userDefinedModelVersionIdentifier="">
|
||||||
|
<entity name="MPGeneratedSiteEntity" representedClassName="MPGeneratedSiteEntity" parentEntity="MPSiteEntity" elementID="789304EA-070D-4982-8C20-54EECFC20CB6" syncable="YES">
|
||||||
|
<attribute name="counter_" optional="YES" attributeType="Integer 32" defaultValueString="1" usesScalarValueType="NO" syncable="YES"/>
|
||||||
|
</entity>
|
||||||
|
<entity name="MPSiteEntity" representedClassName="MPSiteEntity" isAbstract="YES" elementID="58EE245C-6827-4C11-BB7E-5722F2426EC2" syncable="YES">
|
||||||
|
<attribute name="content" optional="YES" transient="YES" attributeType="Transformable" syncable="YES"/>
|
||||||
|
<attribute name="lastUsed" attributeType="Date" usesScalarValueType="NO" indexed="YES" syncable="YES"/>
|
||||||
|
<attribute name="loginGenerated_" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="NO" syncable="YES"/>
|
||||||
|
<attribute name="loginName" optional="YES" attributeType="String" elementID="A1B9F981-D33C-4BFE-9F94-C9D3E1F78E51" syncable="YES"/>
|
||||||
|
<attribute name="name" attributeType="String" minValueString="1" indexed="YES" syncable="YES"/>
|
||||||
|
<attribute name="requiresExplicitMigration_" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="NO">
|
||||||
|
<userInfo/>
|
||||||
|
</attribute>
|
||||||
|
<attribute name="type_" attributeType="Integer 16" defaultValueString="17" usesScalarValueType="NO" syncable="YES"/>
|
||||||
|
<attribute name="url" optional="YES" attributeType="String" syncable="YES"/>
|
||||||
|
<attribute name="uses_" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="NO" indexed="YES" syncable="YES"/>
|
||||||
|
<attribute name="version_" attributeType="Integer 16" minValueString="0" defaultValueString="0" usesScalarValueType="NO" syncable="YES"/>
|
||||||
|
<relationship name="questions" optional="YES" toMany="YES" deletionRule="Cascade" ordered="YES" destinationEntity="MPSiteQuestionEntity" inverseName="site" inverseEntity="MPSiteQuestionEntity" syncable="YES"/>
|
||||||
|
<relationship name="user" minCount="1" maxCount="1" deletionRule="Nullify" destinationEntity="MPUserEntity" inverseName="sites" inverseEntity="MPUserEntity" elementID="FC8AE32E-7BE3-4FA6-8611-B7DC0DB063EF" syncable="YES"/>
|
||||||
|
<compoundIndexes>
|
||||||
|
<compoundIndex>
|
||||||
|
<index value="name"/>
|
||||||
|
<index value="user"/>
|
||||||
|
</compoundIndex>
|
||||||
|
</compoundIndexes>
|
||||||
|
</entity>
|
||||||
|
<entity name="MPSiteQuestionEntity" representedClassName="MPSiteQuestionEntity" syncable="YES">
|
||||||
|
<attribute name="keyword" attributeType="String" syncable="YES"/>
|
||||||
|
<relationship name="site" maxCount="1" deletionRule="Nullify" destinationEntity="MPSiteEntity" inverseName="questions" inverseEntity="MPSiteEntity" syncable="YES"/>
|
||||||
|
</entity>
|
||||||
|
<entity name="MPStoredSiteEntity" representedClassName="MPStoredSiteEntity" parentEntity="MPSiteEntity" elementID="BEEF1688-0CCD-4699-A86A-4D860FE2CEB8" syncable="YES">
|
||||||
|
<attribute name="contentObject" optional="YES" attributeType="Transformable" customClassName="NSData" storedInTruthFile="YES" syncable="YES"/>
|
||||||
|
</entity>
|
||||||
|
<entity name="MPUserEntity" representedClassName="MPUserEntity" syncable="YES">
|
||||||
|
<attribute name="avatar_" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="NO" syncable="YES"/>
|
||||||
|
<attribute name="defaultType_" attributeType="Integer 16" defaultValueString="17" usesScalarValueType="NO" syncable="YES"/>
|
||||||
|
<attribute name="keyID" optional="YES" attributeType="Binary" syncable="YES"/>
|
||||||
|
<attribute name="lastUsed" optional="YES" attributeType="Date" usesScalarValueType="NO" syncable="YES"/>
|
||||||
|
<attribute name="name" attributeType="String" syncable="YES"/>
|
||||||
|
<attribute name="saveKey_" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="NO">
|
||||||
|
<userInfo/>
|
||||||
|
</attribute>
|
||||||
|
<attribute name="touchID_" attributeType="Boolean" defaultValueString="0" usesScalarValueType="NO">
|
||||||
|
<userInfo/>
|
||||||
|
</attribute>
|
||||||
|
<attribute name="version_" attributeType="Integer 16" minValueString="0" defaultValueString="2" usesScalarValueType="NO" syncable="YES"/>
|
||||||
|
<relationship name="sites" optional="YES" toMany="YES" deletionRule="Cascade" destinationEntity="MPSiteEntity" inverseName="user" inverseEntity="MPSiteEntity" elementID="D18D6772-040E-4CFE-8F32-A34B08E9E9BC" syncable="YES"/>
|
||||||
|
</entity>
|
||||||
|
<elements>
|
||||||
|
<element name="MPGeneratedSiteEntity" positionX="216" positionY="-288" width="128" height="58"/>
|
||||||
|
<element name="MPSiteEntity" positionX="-0" positionY="-286" width="128" height="225"/>
|
||||||
|
<element name="MPSiteQuestionEntity" positionX="-2" positionY="-9" width="128" height="73"/>
|
||||||
|
<element name="MPStoredSiteEntity" positionX="214" positionY="-171" width="128" height="60"/>
|
||||||
|
<element name="MPUserEntity" positionX="-218" positionY="-288" width="128" height="178"/>
|
||||||
|
</elements>
|
||||||
|
</model>
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
#import <UIKit/UIKit.h>
|
#import <UIKit/UIKit.h>
|
||||||
#import "MPTypeViewController.h"
|
#import "MPTypeViewController.h"
|
||||||
#import "MPSiteQuestionEntity.h"
|
#import "MPSiteQuestionEntity+CoreDataClass.h"
|
||||||
|
|
||||||
@interface MPAnswersViewController : UIViewController
|
@interface MPAnswersViewController : UIViewController
|
||||||
|
|
||||||
|
|||||||
@@ -80,7 +80,7 @@
|
|||||||
|
|
||||||
- (void)setSite:(MPSiteEntity *)site {
|
- (void)setSite:(MPSiteEntity *)site {
|
||||||
|
|
||||||
_siteOID = [site objectID];
|
_siteOID = site.permanentObjectID;
|
||||||
_multiple = [site.questions count] > 0;
|
_multiple = [site.questions count] > 0;
|
||||||
[self.tableView reloadData];
|
[self.tableView reloadData];
|
||||||
[self updateAnimated:NO];
|
[self updateAnimated:NO];
|
||||||
@@ -161,10 +161,9 @@
|
|||||||
MPSiteEntity *site = [self siteInContext:[MPiOSAppDelegate managedObjectContextForMainThreadIfReady]];
|
MPSiteEntity *site = [self siteInContext:[MPiOSAppDelegate managedObjectContextForMainThreadIfReady]];
|
||||||
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
|
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
|
||||||
|
|
||||||
if ([cell isKindOfClass:[MPGlobalAnswersCell class]]) {
|
if ([cell isKindOfClass:[MPGlobalAnswersCell class]])
|
||||||
[PearlOverlay showTemporaryOverlayWithTitle:strl( @"Answer Copied" ) dismissAfter:2];
|
[self copyAnswer:((MPGlobalAnswersCell *)cell).answerField.text];
|
||||||
[UIPasteboard generalPasteboard].string = ((MPGlobalAnswersCell *)cell).answerField.text;
|
|
||||||
}
|
|
||||||
else if ([cell isKindOfClass:[MPMultipleAnswersCell class]]) {
|
else if ([cell isKindOfClass:[MPMultipleAnswersCell class]]) {
|
||||||
if (!_multiple)
|
if (!_multiple)
|
||||||
[self setMultiple:YES animated:YES];
|
[self setMultiple:YES animated:YES];
|
||||||
@@ -192,6 +191,7 @@
|
|||||||
} cancelTitle:@"Cancel" otherTitles:@"Remove Questions", nil];
|
} cancelTitle:@"Cancel" otherTitles:@"Remove Questions", nil];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else if ([cell isKindOfClass:[MPSendAnswersCell class]]) {
|
else if ([cell isKindOfClass:[MPSendAnswersCell class]]) {
|
||||||
NSString *body;
|
NSString *body;
|
||||||
if (!_multiple) {
|
if (!_multiple) {
|
||||||
@@ -215,14 +215,30 @@
|
|||||||
|
|
||||||
[PearlEMail sendEMailTo:nil fromVC:self subject:strf( @"Master Password security answers for %@", site.name ) body:body];
|
[PearlEMail sendEMailTo:nil fromVC:self subject:strf( @"Master Password security answers for %@", site.name ) body:body];
|
||||||
}
|
}
|
||||||
else if ([cell isKindOfClass:[MPAnswersQuestionCell class]]) {
|
|
||||||
[PearlOverlay showTemporaryOverlayWithTitle:strl( @"Answer Copied" ) dismissAfter:2];
|
else if ([cell isKindOfClass:[MPAnswersQuestionCell class]])
|
||||||
[UIPasteboard generalPasteboard].string = ((MPAnswersQuestionCell *)cell).answerField.text;
|
[self copyAnswer:((MPAnswersQuestionCell *)cell).answerField.text];
|
||||||
}
|
|
||||||
|
|
||||||
[tableView deselectRowAtIndexPath:indexPath animated:YES];
|
[tableView deselectRowAtIndexPath:indexPath animated:YES];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)copyAnswer:(NSString *)answer {
|
||||||
|
|
||||||
|
UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
|
||||||
|
if ([pasteboard respondsToSelector:@selector( setItems:options: )]) {
|
||||||
|
[pasteboard setItems:@[ @{ UIPasteboardTypeAutomatic: answer } ]
|
||||||
|
options:@{
|
||||||
|
UIPasteboardOptionLocalOnly : @NO,
|
||||||
|
UIPasteboardOptionExpirationDate: [NSDate dateWithTimeIntervalSinceNow:3 * 60]
|
||||||
|
}];
|
||||||
|
[PearlOverlay showTemporaryOverlayWithTitle:strl( @"Answer Copied (3 min)" ) dismissAfter:2];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
pasteboard.string = answer;
|
||||||
|
[PearlOverlay showTemporaryOverlayWithTitle:strl( @"Answer Copied" ) dismissAfter:2];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#pragma mark - Private
|
#pragma mark - Private
|
||||||
|
|
||||||
- (void)updateAnimated:(BOOL)animated {
|
- (void)updateAnimated:(BOOL)animated {
|
||||||
@@ -285,8 +301,8 @@
|
|||||||
|
|
||||||
- (void)setQuestion:(MPSiteQuestionEntity *)question forSite:(MPSiteEntity *)site inVC:(MPAnswersViewController *)answersVC {
|
- (void)setQuestion:(MPSiteQuestionEntity *)question forSite:(MPSiteEntity *)site inVC:(MPAnswersViewController *)answersVC {
|
||||||
|
|
||||||
_siteOID = site.objectID;
|
_siteOID = site.permanentObjectID;
|
||||||
_questionOID = question.objectID;
|
_questionOID = question.permanentObjectID;
|
||||||
_answersVC = answersVC;
|
_answersVC = answersVC;
|
||||||
|
|
||||||
[self updateAnswerForQuestion:question ofSite:site];
|
[self updateAnswerForQuestion:question ofSite:site];
|
||||||
@@ -317,14 +333,7 @@
|
|||||||
question.keyword = keyword;
|
question.keyword = keyword;
|
||||||
|
|
||||||
if ([context saveToStore]) {
|
if ([context saveToStore]) {
|
||||||
if ([question.objectID isTemporaryID]) {
|
_questionOID = question.permanentObjectID;
|
||||||
NSError *error = nil;
|
|
||||||
[context obtainPermanentIDsForObjects:@[ question ] error:&error];
|
|
||||||
if (error)
|
|
||||||
err( @"Failed to obtain permanent object ID: %@", [error fullDescription] );
|
|
||||||
}
|
|
||||||
|
|
||||||
_questionOID = question.objectID;
|
|
||||||
[self updateAnswerForQuestion:question ofSite:site];
|
[self updateAnswerForQuestion:question ofSite:site];
|
||||||
|
|
||||||
if (didAddQuestionObject)
|
if (didAddQuestionObject)
|
||||||
|
|||||||
@@ -84,8 +84,19 @@
|
|||||||
- (IBAction)copyPassword:(id)sender {
|
- (IBAction)copyPassword:(id)sender {
|
||||||
|
|
||||||
NSString *sitePassword = [self.passwordButton titleForState:UIControlStateNormal];
|
NSString *sitePassword = [self.passwordButton titleForState:UIControlStateNormal];
|
||||||
if ([sitePassword length]) {
|
if (![sitePassword length])
|
||||||
[UIPasteboard generalPasteboard].string = sitePassword;
|
return;
|
||||||
|
|
||||||
|
UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
|
||||||
|
if ([pasteboard respondsToSelector:@selector( setItems:options: )])
|
||||||
|
[pasteboard setItems:@[ @{ UIPasteboardTypeAutomatic: sitePassword } ]
|
||||||
|
options:@{
|
||||||
|
UIPasteboardOptionLocalOnly : @NO,
|
||||||
|
UIPasteboardOptionExpirationDate: [NSDate dateWithTimeIntervalSinceNow:3 * 60]
|
||||||
|
}];
|
||||||
|
else
|
||||||
|
pasteboard.string = sitePassword;
|
||||||
|
|
||||||
[UIView animateWithDuration:0.3f animations:^{
|
[UIView animateWithDuration:0.3f animations:^{
|
||||||
self.tipContainer.visible = YES;
|
self.tipContainer.visible = YES;
|
||||||
} completion:^(BOOL finished) {
|
} completion:^(BOOL finished) {
|
||||||
@@ -95,7 +106,6 @@
|
|||||||
}];
|
}];
|
||||||
} );
|
} );
|
||||||
}];
|
}];
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark - Private
|
#pragma mark - Private
|
||||||
|
|||||||
@@ -171,7 +171,7 @@
|
|||||||
|
|
||||||
- (void)setSite:(MPSiteEntity *)site animated:(BOOL)animated {
|
- (void)setSite:(MPSiteEntity *)site animated:(BOOL)animated {
|
||||||
|
|
||||||
_siteOID = [site objectID];
|
_siteOID = site.permanentObjectID;
|
||||||
[self updateAnimated:animated];
|
[self updateAnimated:animated];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -367,6 +367,31 @@
|
|||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (IBAction)doAction:(UIButton *)sender {
|
||||||
|
|
||||||
|
[MPiOSAppDelegate managedObjectContextForMainThreadPerformBlock:^(NSManagedObjectContext *mainContext) {
|
||||||
|
MPSiteEntity *mainSite = [self siteInContext:mainContext];
|
||||||
|
[PearlAlert showAlertWithTitle:@"Login Page" message:nil
|
||||||
|
viewStyle:UIAlertViewStylePlainTextInput
|
||||||
|
initAlert:^(UIAlertView *alert, UITextField *firstField) {
|
||||||
|
firstField.placeholder = strf( @"Login URL for %@", mainSite.name );
|
||||||
|
firstField.text = mainSite.url;
|
||||||
|
}
|
||||||
|
tappedButtonBlock:^(UIAlertView *alert, NSInteger buttonIndex) {
|
||||||
|
if (buttonIndex == alert.cancelButtonIndex)
|
||||||
|
return;
|
||||||
|
|
||||||
|
[MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
|
||||||
|
MPSiteEntity *site = [self siteInContext:context];
|
||||||
|
NSURL *url = [NSURL URLWithString:[alert textFieldAtIndex:0].text];
|
||||||
|
site.url = [url.host? url: nil absoluteString];
|
||||||
|
[context saveToStore];
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
cancelTitle:@"Cancel" otherTitles:@"Save", nil];
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
- (IBAction)doIncrementCounter:(UIButton *)sender {
|
- (IBAction)doIncrementCounter:(UIButton *)sender {
|
||||||
|
|
||||||
[MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
|
[MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
|
||||||
@@ -493,10 +518,12 @@
|
|||||||
|
|
||||||
- (void)updateAnimated:(BOOL)animated {
|
- (void)updateAnimated:(BOOL)animated {
|
||||||
|
|
||||||
|
Weakify( self );
|
||||||
if (![NSThread isMainThread]) {
|
if (![NSThread isMainThread]) {
|
||||||
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
|
PearlMainQueueOperation( ^{
|
||||||
|
Strongify( self );
|
||||||
[self updateAnimated:animated];
|
[self updateAnimated:animated];
|
||||||
}];
|
} );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -504,6 +531,7 @@
|
|||||||
MPSiteEntity *mainSite = [self siteInContext:[MPiOSAppDelegate managedObjectContextForMainThreadIfReady]];
|
MPSiteEntity *mainSite = [self siteInContext:[MPiOSAppDelegate managedObjectContextForMainThreadIfReady]];
|
||||||
|
|
||||||
// UI
|
// UI
|
||||||
|
self.backgroundColor = mainSite.url? [UIColor greenColor]: [UIColor redColor];
|
||||||
self.upgradeButton.gone = !mainSite.requiresExplicitMigration && ![[MPiOSConfig get].allowDowngrade boolValue];
|
self.upgradeButton.gone = !mainSite.requiresExplicitMigration && ![[MPiOSConfig get].allowDowngrade boolValue];
|
||||||
self.answersButton.gone = ![[MPiOSAppDelegate get] isFeatureUnlocked:MPProductGenerateAnswers];
|
self.answersButton.gone = ![[MPiOSAppDelegate get] isFeatureUnlocked:MPProductGenerateAnswers];
|
||||||
BOOL settingsMode = self.mode == MPPasswordCellModeSettings;
|
BOOL settingsMode = self.mode == MPPasswordCellModeSettings;
|
||||||
@@ -544,11 +572,17 @@
|
|||||||
} );
|
} );
|
||||||
|
|
||||||
// Calculate Fields
|
// Calculate Fields
|
||||||
[MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
|
if (![MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
|
||||||
MPSiteEntity *site = [self siteInContext:context];
|
MPSiteEntity *site = [self siteInContext:context];
|
||||||
MPKey *key = [MPiOSAppDelegate get].key;
|
MPKey *key = [MPiOSAppDelegate get].key;
|
||||||
if (!key)
|
if (!key) {
|
||||||
|
wrn( @"Could not load cell content: key unavailable." );
|
||||||
|
PearlMainQueueOperation( ^{
|
||||||
|
Strongify( self );
|
||||||
|
[self updateAnimated:YES];
|
||||||
|
} );
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
BOOL loginGenerated = site.loginGenerated;
|
BOOL loginGenerated = site.loginGenerated;
|
||||||
NSString *password = nil, *loginName = [site resolveLoginUsingKey:key];
|
NSString *password = nil, *loginName = [site resolveLoginUsingKey:key];
|
||||||
@@ -600,7 +634,13 @@
|
|||||||
else
|
else
|
||||||
self.indicatorView.hidden = YES;
|
self.indicatorView.hidden = YES;
|
||||||
} );
|
} );
|
||||||
}];
|
}]) {
|
||||||
|
wrn( @"Could not load cell content: store unavailable." );
|
||||||
|
PearlMainQueueOperation( ^{
|
||||||
|
Strongify( self );
|
||||||
|
[self updateAnimated:YES];
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
[self.contentView layoutIfNeeded];
|
[self.contentView layoutIfNeeded];
|
||||||
}];
|
}];
|
||||||
@@ -635,8 +675,21 @@
|
|||||||
return NO;
|
return NO;
|
||||||
|
|
||||||
PearlMainQueue( ^{
|
PearlMainQueue( ^{
|
||||||
|
[self.window endEditing:YES];
|
||||||
|
|
||||||
|
UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
|
||||||
|
if ([pasteboard respondsToSelector:@selector(setItems:options:)]) {
|
||||||
|
[pasteboard setItems:@[ @{ UIPasteboardTypeAutomatic: password } ]
|
||||||
|
options:@{
|
||||||
|
UIPasteboardOptionLocalOnly : @NO,
|
||||||
|
UIPasteboardOptionExpirationDate: [NSDate dateWithTimeIntervalSinceNow:3 * 60]
|
||||||
|
}];
|
||||||
|
[PearlOverlay showTemporaryOverlayWithTitle:strl( @"Password Copied (3 min)" ) dismissAfter:2];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
pasteboard.string = password;
|
||||||
[PearlOverlay showTemporaryOverlayWithTitle:strl( @"Password Copied" ) dismissAfter:2];
|
[PearlOverlay showTemporaryOverlayWithTitle:strl( @"Password Copied" ) dismissAfter:2];
|
||||||
[UIPasteboard generalPasteboard].string = password;
|
}
|
||||||
} );
|
} );
|
||||||
|
|
||||||
[site use];
|
[site use];
|
||||||
@@ -652,8 +705,10 @@
|
|||||||
return NO;
|
return NO;
|
||||||
|
|
||||||
PearlMainQueue( ^{
|
PearlMainQueue( ^{
|
||||||
[PearlOverlay showTemporaryOverlayWithTitle:strl( @"Login Name Copied" ) dismissAfter:2];
|
[self.window endEditing:YES];
|
||||||
|
|
||||||
[UIPasteboard generalPasteboard].string = loginName;
|
[UIPasteboard generalPasteboard].string = loginName;
|
||||||
|
[PearlOverlay showTemporaryOverlayWithTitle:strl( @"Login Name Copied" ) dismissAfter:2];
|
||||||
} );
|
} );
|
||||||
|
|
||||||
[site use];
|
[site use];
|
||||||
|
|||||||
@@ -34,7 +34,7 @@
|
|||||||
@property(assign, nonatomic) BOOL active;
|
@property(assign, nonatomic) BOOL active;
|
||||||
|
|
||||||
- (void)setActive:(BOOL)active animated:(BOOL)animated completion:(void ( ^ )(BOOL finished))completion;
|
- (void)setActive:(BOOL)active animated:(BOOL)animated completion:(void ( ^ )(BOOL finished))completion;
|
||||||
- (void)updatePasswords;
|
- (void)reloadPasswords;
|
||||||
|
|
||||||
- (IBAction)dismissPopdown:(id)sender;
|
- (IBAction)dismissPopdown:(id)sender;
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,8 @@
|
|||||||
#import "MPAnswersViewController.h"
|
#import "MPAnswersViewController.h"
|
||||||
#import "MPMessageViewController.h"
|
#import "MPMessageViewController.h"
|
||||||
|
|
||||||
|
static const NSString *MPTransientPasswordItem = @"MPTransientPasswordItem";
|
||||||
|
|
||||||
typedef NS_OPTIONS( NSUInteger, MPPasswordsTips ) {
|
typedef NS_OPTIONS( NSUInteger, MPPasswordsTips ) {
|
||||||
MPPasswordsBadNameTip = 1 << 0,
|
MPPasswordsBadNameTip = 1 << 0,
|
||||||
};
|
};
|
||||||
@@ -32,7 +34,6 @@ typedef NS_OPTIONS( NSUInteger, MPPasswordsTips ) {
|
|||||||
@interface MPPasswordsViewController()<NSFetchedResultsControllerDelegate>
|
@interface MPPasswordsViewController()<NSFetchedResultsControllerDelegate>
|
||||||
|
|
||||||
@property(nonatomic, strong) IBOutlet UINavigationBar *navigationBar;
|
@property(nonatomic, strong) IBOutlet UINavigationBar *navigationBar;
|
||||||
@property(nonatomic, readonly) NSString *query;
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@@ -42,11 +43,9 @@ typedef NS_OPTIONS( NSUInteger, MPPasswordsTips ) {
|
|||||||
UIColor *_backgroundColor;
|
UIColor *_backgroundColor;
|
||||||
UIColor *_darkenedBackgroundColor;
|
UIColor *_darkenedBackgroundColor;
|
||||||
__weak UIViewController *_popdownVC;
|
__weak UIViewController *_popdownVC;
|
||||||
BOOL _showTransientItem;
|
|
||||||
NSUInteger _transientItem;
|
|
||||||
NSCharacterSet *_siteNameAcceptableCharactersSet;
|
NSCharacterSet *_siteNameAcceptableCharactersSet;
|
||||||
NSArray *_fuzzyGroups;
|
NSArray *_fuzzyGroups;
|
||||||
NSMutableArray *_passwordCollectionViewUpdatesBatch;
|
NSMutableArray<NSMutableArray *> *_passwordCollectionSections;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark - Life
|
#pragma mark - Life
|
||||||
@@ -62,8 +61,7 @@ typedef NS_OPTIONS( NSUInteger, MPPasswordsTips ) {
|
|||||||
|
|
||||||
_backgroundColor = self.passwordCollectionView.backgroundColor;
|
_backgroundColor = self.passwordCollectionView.backgroundColor;
|
||||||
_darkenedBackgroundColor = [_backgroundColor colorWithAlphaComponent:0.6f];
|
_darkenedBackgroundColor = [_backgroundColor colorWithAlphaComponent:0.6f];
|
||||||
_transientItem = NSNotFound;
|
_passwordCollectionSections = [NSMutableArray new];
|
||||||
_passwordCollectionViewUpdatesBatch = [NSMutableArray arrayWithCapacity:4];
|
|
||||||
|
|
||||||
self.view.backgroundColor = [UIColor clearColor];
|
self.view.backgroundColor = [UIColor clearColor];
|
||||||
[self.passwordCollectionView automaticallyAdjustInsetsForKeyboard];
|
[self.passwordCollectionView automaticallyAdjustInsetsForKeyboard];
|
||||||
@@ -83,7 +81,24 @@ typedef NS_OPTIONS( NSUInteger, MPPasswordsTips ) {
|
|||||||
|
|
||||||
[self registerObservers];
|
[self registerObservers];
|
||||||
[self updateConfigKey:nil];
|
[self updateConfigKey:nil];
|
||||||
[self updatePasswords];
|
|
||||||
|
static NSRegularExpression *bareHostRE = nil;
|
||||||
|
static dispatch_once_t once = 0;
|
||||||
|
dispatch_once( &once, ^{
|
||||||
|
bareHostRE = [NSRegularExpression regularExpressionWithPattern:@"([^\\.]+\\.[^\\.]+)$" options:0 error:nil];
|
||||||
|
} );
|
||||||
|
|
||||||
|
NSURL *pasteboardURL = nil;
|
||||||
|
UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
|
||||||
|
if ([pasteboard respondsToSelector:@selector( hasURLs )])
|
||||||
|
pasteboardURL = pasteboard.hasURLs? pasteboard.URL: nil;
|
||||||
|
else
|
||||||
|
pasteboardURL = [NSURL URLWithString:pasteboard.string];
|
||||||
|
|
||||||
|
if (pasteboardURL.host)
|
||||||
|
self.query = NSNullToNil( [pasteboardURL.host firstMatchGroupsOfExpression:bareHostRE][0] );
|
||||||
|
else
|
||||||
|
[self reloadPasswords];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)viewDidAppear:(BOOL)animated {
|
- (void)viewDidAppear:(BOOL)animated {
|
||||||
@@ -140,30 +155,43 @@ typedef NS_OPTIONS( NSUInteger, MPPasswordsTips ) {
|
|||||||
return CGSizeMake( itemWidth, 100 );
|
return CGSizeMake( itemWidth, 100 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout
|
||||||
|
insetForSectionAtIndex:(NSInteger)section {
|
||||||
|
|
||||||
|
UICollectionViewFlowLayout *layout = (UICollectionViewFlowLayout *)collectionViewLayout;
|
||||||
|
UIEdgeInsets occludedInsets = [self.passwordCollectionView occludedInsets];
|
||||||
|
UIEdgeInsets insets = layout.sectionInset;
|
||||||
|
insets.top = insets.bottom; // Undo storyboard hack for manual top-occluded insets.
|
||||||
|
|
||||||
|
if (section == 0)
|
||||||
|
insets.top += occludedInsets.top;
|
||||||
|
|
||||||
|
if (section == collectionView.numberOfSections - 1)
|
||||||
|
insets.bottom += occludedInsets.bottom;
|
||||||
|
|
||||||
|
return insets;
|
||||||
|
}
|
||||||
|
|
||||||
#pragma mark - UICollectionViewDataSource
|
#pragma mark - UICollectionViewDataSource
|
||||||
|
|
||||||
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
|
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
|
||||||
|
|
||||||
return [self.fetchedResultsController.sections count];
|
return [_passwordCollectionSections count];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
|
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
|
||||||
|
|
||||||
if (![MPiOSAppDelegate get].activeUserOID || !_fetchedResultsController)
|
return [_passwordCollectionSections[(NSUInteger)section] count];
|
||||||
return 0;
|
|
||||||
|
|
||||||
NSUInteger objects = ((id<NSFetchedResultsSectionInfo>)self.fetchedResultsController.sections[section]).numberOfObjects;
|
|
||||||
_transientItem = _showTransientItem? objects: NSNotFound;
|
|
||||||
return objects + (_showTransientItem? 1: 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
|
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
|
||||||
|
|
||||||
MPPasswordCell *cell = [MPPasswordCell dequeueCellFromCollectionView:collectionView indexPath:indexPath];
|
MPPasswordCell *cell = [MPPasswordCell dequeueCellFromCollectionView:collectionView indexPath:indexPath];
|
||||||
[cell setFuzzyGroups:_fuzzyGroups];
|
[cell setFuzzyGroups:_fuzzyGroups];
|
||||||
if (indexPath.item < ((id<NSFetchedResultsSectionInfo>)self.fetchedResultsController.sections[indexPath.section]).numberOfObjects)
|
id item = _passwordCollectionSections[(NSUInteger)indexPath.section][(NSUInteger)indexPath.item];
|
||||||
[cell setSite:[self.fetchedResultsController objectAtIndexPath:indexPath] animated:NO];
|
if ([item isKindOfClass:[MPSiteEntity class]])
|
||||||
else
|
[cell setSite:item animated:NO];
|
||||||
|
else // item == MPTransientPasswordItem
|
||||||
[cell setTransientSite:self.query animated:NO];
|
[cell setTransientSite:self.query animated:NO];
|
||||||
|
|
||||||
return cell;
|
return cell;
|
||||||
@@ -180,61 +208,14 @@ typedef NS_OPTIONS( NSUInteger, MPPasswordsTips ) {
|
|||||||
|
|
||||||
#pragma mark - NSFetchedResultsControllerDelegate
|
#pragma mark - NSFetchedResultsControllerDelegate
|
||||||
|
|
||||||
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath
|
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
|
||||||
forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath {
|
|
||||||
|
|
||||||
Weakify( self );
|
|
||||||
|
|
||||||
if (controller == _fetchedResultsController) {
|
|
||||||
@synchronized (_passwordCollectionViewUpdatesBatch) {
|
|
||||||
[_passwordCollectionViewUpdatesBatch addObject:[^{
|
|
||||||
Strongify( self );
|
|
||||||
|
|
||||||
switch (type) {
|
|
||||||
case NSFetchedResultsChangeInsert:
|
|
||||||
[self.passwordCollectionView insertItemsAtIndexPaths:@[ newIndexPath ]];
|
|
||||||
break;
|
|
||||||
case NSFetchedResultsChangeDelete:
|
|
||||||
[self.passwordCollectionView deleteItemsAtIndexPaths:@[ indexPath ]];
|
|
||||||
break;
|
|
||||||
case NSFetchedResultsChangeMove:
|
|
||||||
if (![indexPath isEqual:newIndexPath])
|
|
||||||
[self.passwordCollectionView moveItemAtIndexPath:indexPath toIndexPath:newIndexPath];
|
|
||||||
break;
|
|
||||||
case NSFetchedResultsChangeUpdate:
|
|
||||||
[self.passwordCollectionView reloadItemsAtIndexPaths:@[ indexPath ]];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} copy]];
|
|
||||||
}
|
|
||||||
|
|
||||||
[controller.managedObjectContext performBlock:^{
|
|
||||||
PearlMainQueueOperation( ^{
|
|
||||||
@try {
|
|
||||||
[self.passwordCollectionView performBatchUpdates:^{
|
|
||||||
[self updateTransientItem];
|
|
||||||
|
|
||||||
@synchronized (_passwordCollectionViewUpdatesBatch) {
|
|
||||||
for (VoidBlock block in _passwordCollectionViewUpdatesBatch)
|
|
||||||
block();
|
|
||||||
[_passwordCollectionViewUpdatesBatch removeAllObjects];
|
|
||||||
}
|
|
||||||
} completion:nil];
|
|
||||||
}
|
|
||||||
@catch (NSException *exception) {
|
|
||||||
wrn( @"While updating password cells: %@", [exception fullDescription] );
|
|
||||||
[self.passwordCollectionView reloadData];
|
|
||||||
}
|
|
||||||
} );
|
|
||||||
}];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id<NSFetchedResultsSectionInfo>)sectionInfo
|
|
||||||
atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type {
|
|
||||||
|
|
||||||
if (controller == _fetchedResultsController)
|
if (controller == _fetchedResultsController)
|
||||||
[self.passwordCollectionView reloadData];
|
PearlMainQueue( ^{
|
||||||
|
[self.passwordCollectionView updateDataSource:_passwordCollectionSections
|
||||||
|
toSections:[self createPasswordCollectionSections]
|
||||||
|
reloadItems:nil completion:nil];
|
||||||
|
} );
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark - UISearchBarDelegate
|
#pragma mark - UISearchBarDelegate
|
||||||
@@ -266,7 +247,7 @@ typedef NS_OPTIONS( NSUInteger, MPPasswordsTips ) {
|
|||||||
if (_passwordsDismissRecognizer)
|
if (_passwordsDismissRecognizer)
|
||||||
[self.view removeGestureRecognizer:_passwordsDismissRecognizer];
|
[self.view removeGestureRecognizer:_passwordsDismissRecognizer];
|
||||||
|
|
||||||
[self updatePasswords];
|
[self reloadPasswords];
|
||||||
[UIView animateWithDuration:0.3f animations:^{
|
[UIView animateWithDuration:0.3f animations:^{
|
||||||
self.passwordCollectionView.backgroundColor = _backgroundColor;
|
self.passwordCollectionView.backgroundColor = _backgroundColor;
|
||||||
}];
|
}];
|
||||||
@@ -290,7 +271,7 @@ typedef NS_OPTIONS( NSUInteger, MPPasswordsTips ) {
|
|||||||
if ([[self.query stringByTrimmingCharactersInSet:_siteNameAcceptableCharactersSet] length])
|
if ([[self.query stringByTrimmingCharactersInSet:_siteNameAcceptableCharactersSet] length])
|
||||||
[self showTips:MPPasswordsBadNameTip];
|
[self showTips:MPPasswordsBadNameTip];
|
||||||
|
|
||||||
[self updatePasswords];
|
[self reloadPasswords];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -311,49 +292,54 @@ typedef NS_OPTIONS( NSUInteger, MPPasswordsTips ) {
|
|||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)updateTransientItem {
|
- (NSMutableArray<NSMutableArray *> *)createPasswordCollectionSections {
|
||||||
|
|
||||||
NSString *query = self.query;
|
NSString *query = self.query;
|
||||||
_showTransientItem = [query length] > 0 && ![[[self.fetchedResultsController.sections[0] objects] filteredArrayUsingPredicate:
|
BOOL needTransientItem = [query length] > 0;
|
||||||
[NSPredicate predicateWithBlock:^BOOL(MPSiteEntity *site, NSDictionary<NSString *, id> *bindings) {
|
|
||||||
return [site.name isEqualToString:query];
|
NSArray<id<NSFetchedResultsSectionInfo>> *sectionInfos = [self.fetchedResultsController sections];
|
||||||
}]] count];
|
NSMutableArray *sections = [[NSMutableArray alloc] initWithCapacity:[sectionInfos count]];
|
||||||
if (!_showTransientItem && _transientItem != NSNotFound)
|
for (id<NSFetchedResultsSectionInfo> sectionInfo in sectionInfos) {
|
||||||
[self.passwordCollectionView deleteItemsAtIndexPaths:
|
NSArray<MPSiteEntity *> *sites = [sectionInfo.objects copy];
|
||||||
@[ [NSIndexPath indexPathForItem:_transientItem inSection:0] ]];
|
[sections addObject:sites];
|
||||||
else if (_showTransientItem && _transientItem == NSNotFound) {
|
|
||||||
NSUInteger objects = [self.fetchedResultsController.sections[0] numberOfObjects];
|
if (needTransientItem)
|
||||||
[self.passwordCollectionView insertItemsAtIndexPaths:
|
for (MPSiteEntity *site in sites)
|
||||||
@[ [NSIndexPath indexPathForItem:objects inSection:0] ]];
|
if ([site.name isEqualToString:query]) {
|
||||||
|
needTransientItem = NO;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else if (_transientItem != NSNotFound)
|
}
|
||||||
[self.passwordCollectionView reloadItemsAtIndexPaths:
|
|
||||||
@[ [NSIndexPath indexPathForItem:_transientItem inSection:0] ]];
|
if (needTransientItem)
|
||||||
|
[sections addObject:@[ MPTransientPasswordItem ]];
|
||||||
|
|
||||||
|
return sections;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)registerObservers {
|
- (void)registerObservers {
|
||||||
|
|
||||||
PearlRemoveNotificationObservers();
|
PearlRemoveNotificationObservers();
|
||||||
PearlAddNotificationObserver( UIApplicationDidEnterBackgroundNotification, nil, [NSOperationQueue mainQueue],
|
PearlAddNotificationObserver( UIApplicationWillResignActiveNotification, nil, [NSOperationQueue mainQueue],
|
||||||
^(MPPasswordsViewController *self, NSNotification *note) {
|
^(MPPasswordsViewController *self, NSNotification *note) {
|
||||||
|
[self.view endEditing:YES];
|
||||||
self.passwordSelectionContainer.visible = NO;
|
self.passwordSelectionContainer.visible = NO;
|
||||||
} );
|
} );
|
||||||
PearlAddNotificationObserver( UIApplicationWillEnterForegroundNotification, nil, [NSOperationQueue mainQueue],
|
|
||||||
^(MPPasswordsViewController *self, NSNotification *note) {
|
|
||||||
[self updatePasswords];
|
|
||||||
} );
|
|
||||||
PearlAddNotificationObserver( UIApplicationDidBecomeActiveNotification, nil, [NSOperationQueue mainQueue],
|
PearlAddNotificationObserver( UIApplicationDidBecomeActiveNotification, nil, [NSOperationQueue mainQueue],
|
||||||
^(MPPasswordsViewController *self, NSNotification *note) {
|
^(MPPasswordsViewController *self, NSNotification *note) {
|
||||||
[UIView animateWithDuration:0.7f animations:^{
|
[UIView animateWithDuration:0.7f animations:^{
|
||||||
self.passwordSelectionContainer.visible = YES;
|
self.passwordSelectionContainer.visible = YES;
|
||||||
}];
|
}];
|
||||||
} );
|
} );
|
||||||
|
PearlAddNotificationObserver( UIApplicationWillEnterForegroundNotification, nil, [NSOperationQueue mainQueue],
|
||||||
|
^(MPPasswordsViewController *self, NSNotification *note) {
|
||||||
|
[self viewWillAppear:YES];
|
||||||
|
} );
|
||||||
PearlAddNotificationObserver( MPSignedOutNotification, nil, nil,
|
PearlAddNotificationObserver( MPSignedOutNotification, nil, nil,
|
||||||
^(MPPasswordsViewController *self, NSNotification *note) {
|
^(MPPasswordsViewController *self, NSNotification *note) {
|
||||||
PearlMainQueue( ^{
|
PearlMainQueue( ^{
|
||||||
_fetchedResultsController = nil;
|
self->_fetchedResultsController = nil;
|
||||||
self.passwordsSearchBar.text = nil;
|
self.query = nil;
|
||||||
[self.passwordCollectionView reloadData];
|
|
||||||
} );
|
} );
|
||||||
} );
|
} );
|
||||||
PearlAddNotificationObserver( MPCheckConfigNotification, nil, nil,
|
PearlAddNotificationObserver( MPCheckConfigNotification, nil, nil,
|
||||||
@@ -365,26 +351,23 @@ typedef NS_OPTIONS( NSUInteger, MPPasswordsTips ) {
|
|||||||
PearlAddNotificationObserver( NSPersistentStoreCoordinatorStoresWillChangeNotification, nil, nil,
|
PearlAddNotificationObserver( NSPersistentStoreCoordinatorStoresWillChangeNotification, nil, nil,
|
||||||
^(MPPasswordsViewController *self, NSNotification *note) {
|
^(MPPasswordsViewController *self, NSNotification *note) {
|
||||||
self->_fetchedResultsController = nil;
|
self->_fetchedResultsController = nil;
|
||||||
PearlMainQueue( ^{
|
[self reloadPasswords];
|
||||||
[self.passwordCollectionView reloadData];
|
|
||||||
} );
|
|
||||||
} );
|
} );
|
||||||
PearlAddNotificationObserver( NSPersistentStoreCoordinatorStoresDidChangeNotification, nil, nil,
|
PearlAddNotificationObserver( NSPersistentStoreCoordinatorStoresDidChangeNotification, nil, nil,
|
||||||
^(MPPasswordsViewController *self, NSNotification *note) {
|
^(MPPasswordsViewController *self, NSNotification *note) {
|
||||||
PearlMainQueue( ^{
|
PearlMainQueue( ^{
|
||||||
[self updatePasswords];
|
[self reloadPasswords];
|
||||||
[self registerObservers];
|
[self registerObservers];
|
||||||
} );
|
} );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
NSManagedObjectContext *mainContext = [MPiOSAppDelegate managedObjectContextForMainThreadIfReady];
|
[MPiOSAppDelegate managedObjectContextChanged:^(NSDictionary<NSManagedObjectID *, NSString *> *affectedObjects) {
|
||||||
if (mainContext)
|
[MPiOSAppDelegate managedObjectContextForMainThreadPerformBlock:^(NSManagedObjectContext *mainContext) {
|
||||||
PearlAddNotificationObserver( NSManagedObjectContextDidSaveNotification, mainContext, nil,
|
|
||||||
^(MPPasswordsViewController *self, NSNotification *note) {
|
|
||||||
// TODO: either move this into the app delegate or remove the duplicate signOutAnimated: call from the app delegate.
|
// TODO: either move this into the app delegate or remove the duplicate signOutAnimated: call from the app delegate.
|
||||||
if (![[MPiOSAppDelegate get] activeUserInContext:note.object])
|
if (![[MPiOSAppDelegate get] activeUserInContext:mainContext])
|
||||||
[[MPiOSAppDelegate get] signOutAnimated:YES];
|
[[MPiOSAppDelegate get] signOutAnimated:YES];
|
||||||
} );
|
}];
|
||||||
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)updateConfigKey:(NSString *)key {
|
- (void)updateConfigKey:(NSString *)key {
|
||||||
@@ -395,18 +378,9 @@ typedef NS_OPTIONS( NSUInteger, MPPasswordsTips ) {
|
|||||||
[self.passwordCollectionView reloadData];
|
[self.passwordCollectionView reloadData];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)updatePasswords {
|
- (void)reloadPasswords {
|
||||||
|
|
||||||
NSManagedObjectID *activeUserOID = [MPiOSAppDelegate get].activeUserOID;
|
|
||||||
if (!activeUserOID) {
|
|
||||||
PearlMainQueue( ^{
|
|
||||||
self.passwordsSearchBar.text = nil;
|
|
||||||
[self.passwordCollectionView reloadData];
|
|
||||||
[self.passwordCollectionView setContentOffset:CGPointMake( 0, -self.passwordCollectionView.contentInset.top ) animated:YES];
|
|
||||||
} );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
[self.fetchedResultsController.managedObjectContext performBlock:^{
|
||||||
static NSRegularExpression *fuzzyRE;
|
static NSRegularExpression *fuzzyRE;
|
||||||
static dispatch_once_t once = 0;
|
static dispatch_once_t once = 0;
|
||||||
dispatch_once( &once, ^{
|
dispatch_once( &once, ^{
|
||||||
@@ -414,62 +388,28 @@ typedef NS_OPTIONS( NSUInteger, MPPasswordsTips ) {
|
|||||||
} );
|
} );
|
||||||
|
|
||||||
NSString *queryString = self.query;
|
NSString *queryString = self.query;
|
||||||
NSString *queryPattern;
|
NSString *queryPattern = [[queryString stringByReplacingMatchesOfExpression:fuzzyRE withTemplate:@"*$1"]
|
||||||
if ([queryString length] < 13)
|
stringByAppendingString:@"*"];
|
||||||
queryPattern = [queryString stringByReplacingMatchesOfExpression:fuzzyRE withTemplate:@"*$1*"];
|
NSMutableArray *fuzzyGroups = [NSMutableArray new];
|
||||||
else
|
|
||||||
// If query is too long, a wildcard per character makes the CoreData fetch take excessively long.
|
|
||||||
queryPattern = strf( @"*%@*", queryString );
|
|
||||||
NSMutableArray *fuzzyGroups = [NSMutableArray arrayWithCapacity:[queryString length]];
|
|
||||||
[fuzzyRE enumerateMatchesInString:queryString options:0 range:NSMakeRange( 0, queryString.length )
|
[fuzzyRE enumerateMatchesInString:queryString options:0 range:NSMakeRange( 0, queryString.length )
|
||||||
usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) {
|
usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) {
|
||||||
[fuzzyGroups addObject:[queryString substringWithRange:result.range]];
|
[fuzzyGroups addObject:[queryString substringWithRange:result.range]];
|
||||||
}];
|
}];
|
||||||
_fuzzyGroups = fuzzyGroups;
|
_fuzzyGroups = fuzzyGroups;
|
||||||
[self.fetchedResultsController.managedObjectContext performBlock:^{
|
|
||||||
NSArray *oldSectionInfos = [self.fetchedResultsController sections];
|
|
||||||
NSMutableArray *oldSections = [[NSMutableArray alloc] initWithCapacity:[oldSectionInfos count]];
|
|
||||||
for (id<NSFetchedResultsSectionInfo> sectionInfo in oldSectionInfos)
|
|
||||||
[oldSections addObject:[sectionInfo.objects copy]];
|
|
||||||
|
|
||||||
NSError *error = nil;
|
NSError *error = nil;
|
||||||
self.fetchedResultsController.fetchRequest.predicate =
|
self.fetchedResultsController.fetchRequest.predicate =
|
||||||
[NSPredicate predicateWithFormat:@"(%@ == '' OR name LIKE[cd] %@) AND user == %@",
|
[NSPredicate predicateWithFormat:@"name LIKE[cd] %@ AND user == %@", queryPattern, [MPiOSAppDelegate get].activeUserOID];
|
||||||
queryPattern, queryPattern, activeUserOID];
|
|
||||||
if (![self.fetchedResultsController performFetch:&error])
|
if (![self.fetchedResultsController performFetch:&error])
|
||||||
err( @"Couldn't fetch sites: %@", [error fullDescription] );
|
MPError( error, @"Couldn't fetch sites." );
|
||||||
|
|
||||||
PearlMainQueue( ^{
|
PearlMainQueue( ^{
|
||||||
@try {
|
[self.passwordCollectionView updateDataSource:_passwordCollectionSections
|
||||||
[self.passwordCollectionView performBatchUpdates:^{
|
toSections:[self createPasswordCollectionSections]
|
||||||
[self updateTransientItem];
|
reloadItems:@[ MPTransientPasswordItem ] completion:^(BOOL finished) {
|
||||||
|
|
||||||
NSInteger fromSections = self.passwordCollectionView.numberOfSections;
|
|
||||||
NSInteger toSections = [self numberOfSectionsInCollectionView:self.passwordCollectionView];
|
|
||||||
for (NSInteger section = 0; section < MAX( toSections, fromSections ); ++section) {
|
|
||||||
if (section >= fromSections)
|
|
||||||
[self.passwordCollectionView insertSections:[NSIndexSet indexSetWithIndex:section]];
|
|
||||||
else if (section >= toSections)
|
|
||||||
[self.passwordCollectionView deleteSections:[NSIndexSet indexSetWithIndex:section]];
|
|
||||||
else if (section < [oldSections count])
|
|
||||||
[self.passwordCollectionView reloadItemsFromArray:oldSections[section]
|
|
||||||
toArray:[[self.fetchedResultsController sections][section] objects]
|
|
||||||
inSection:section];
|
|
||||||
else
|
|
||||||
[self.passwordCollectionView reloadSections:[NSIndexSet indexSetWithIndex:section]];
|
|
||||||
}
|
|
||||||
} completion:^(BOOL finished) {
|
|
||||||
if (finished)
|
|
||||||
[self.passwordCollectionView setContentOffset:CGPointMake( 0, -self.passwordCollectionView.contentInset.top )
|
|
||||||
animated:YES];
|
|
||||||
for (MPPasswordCell *cell in self.passwordCollectionView.visibleCells)
|
for (MPPasswordCell *cell in self.passwordCollectionView.visibleCells)
|
||||||
[cell setFuzzyGroups:_fuzzyGroups];
|
[cell setFuzzyGroups:_fuzzyGroups];
|
||||||
}];
|
}];
|
||||||
}
|
|
||||||
@catch (NSException *exception) {
|
|
||||||
wrn( @"While updating password cells: %@", [exception fullDescription] );
|
|
||||||
[self.passwordCollectionView reloadData];
|
|
||||||
}
|
|
||||||
} );
|
} );
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
@@ -481,18 +421,24 @@ typedef NS_OPTIONS( NSUInteger, MPPasswordsTips ) {
|
|||||||
return [self.passwordsSearchBar.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
|
return [self.passwordsSearchBar.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)setQuery:(NSString *)query {
|
||||||
|
|
||||||
|
self.passwordsSearchBar.text = [query stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
|
||||||
|
[self reloadPasswords];
|
||||||
|
}
|
||||||
|
|
||||||
- (NSFetchedResultsController *)fetchedResultsController {
|
- (NSFetchedResultsController *)fetchedResultsController {
|
||||||
|
|
||||||
if (!_fetchedResultsController) {
|
if (!_fetchedResultsController) {
|
||||||
_showTransientItem = NO;
|
|
||||||
[MPiOSAppDelegate managedObjectContextForMainThreadPerformBlockAndWait:^(NSManagedObjectContext *mainContext) {
|
[MPiOSAppDelegate managedObjectContextForMainThreadPerformBlockAndWait:^(NSManagedObjectContext *mainContext) {
|
||||||
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:NSStringFromClass( [MPSiteEntity class] )];
|
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:NSStringFromClass( [MPSiteEntity class] )];
|
||||||
fetchRequest.sortDescriptors = @[
|
fetchRequest.sortDescriptors = @[
|
||||||
[[NSSortDescriptor alloc] initWithKey:NSStringFromSelector( @selector( lastUsed ) ) ascending:NO]
|
[[NSSortDescriptor alloc] initWithKey:NSStringFromSelector( @selector( lastUsed ) ) ascending:NO]
|
||||||
];
|
];
|
||||||
fetchRequest.fetchBatchSize = 10;
|
fetchRequest.fetchBatchSize = 10;
|
||||||
_fetchedResultsController = [[NSFetchedResultsController alloc]
|
_fetchedResultsController =
|
||||||
initWithFetchRequest:fetchRequest managedObjectContext:mainContext sectionNameKeyPath:nil cacheName:nil];
|
[[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:mainContext
|
||||||
|
sectionNameKeyPath:nil cacheName:nil];
|
||||||
_fetchedResultsController.delegate = self;
|
_fetchedResultsController.delegate = self;
|
||||||
}];
|
}];
|
||||||
[self registerObservers];
|
[self registerObservers];
|
||||||
|
|||||||
@@ -38,6 +38,7 @@
|
|||||||
metrics:nil views:NSDictionaryOfVariableBindings( popdownView )];
|
metrics:nil views:NSDictionaryOfVariableBindings( popdownView )];
|
||||||
|
|
||||||
[passwordsVC.popdownToTopConstraint layoutIfNeeded];
|
[passwordsVC.popdownToTopConstraint layoutIfNeeded];
|
||||||
|
[passwordsVC.view endEditing:YES];
|
||||||
|
|
||||||
[UIView animateWithDuration:0.6f delay:0 usingSpringWithDamping:0.75f initialSpringVelocity:1
|
[UIView animateWithDuration:0.6f delay:0 usingSpringWithDamping:0.75f initialSpringVelocity:1
|
||||||
options:UIViewAnimationOptionCurveEaseOut animations:^{
|
options:UIViewAnimationOptionCurveEaseOut animations:^{
|
||||||
|
|||||||
@@ -207,13 +207,13 @@
|
|||||||
- (IBAction)homePageButton:(id)sender {
|
- (IBAction)homePageButton:(id)sender {
|
||||||
|
|
||||||
[[self dismissPopup].navigationController performSegueWithIdentifier:@"web" sender:
|
[[self dismissPopup].navigationController performSegueWithIdentifier:@"web" sender:
|
||||||
[NSURL URLWithString:@"http://masterpasswordapp.com"]];
|
[NSURL URLWithString:@"https://ssl.masterpasswordapp.com"]];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (IBAction)securityButton:(id)sender {
|
- (IBAction)securityButton:(id)sender {
|
||||||
|
|
||||||
[[self dismissPopup].navigationController performSegueWithIdentifier:@"web" sender:
|
[[self dismissPopup].navigationController performSegueWithIdentifier:@"web" sender:
|
||||||
[NSURL URLWithString:@"http://masterpasswordapp.com/security.html"]];
|
[NSURL URLWithString:@"https://ssl.masterpasswordapp.com/security.html"]];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (IBAction)sourceButton:(id)sender {
|
- (IBAction)sourceButton:(id)sender {
|
||||||
@@ -225,7 +225,7 @@
|
|||||||
- (IBAction)thanksButton:(id)sender {
|
- (IBAction)thanksButton:(id)sender {
|
||||||
|
|
||||||
[[self dismissPopup].navigationController performSegueWithIdentifier:@"web" sender:
|
[[self dismissPopup].navigationController performSegueWithIdentifier:@"web" sender:
|
||||||
[NSURL URLWithString:@"http://thanks.lhunath.com"]];
|
[NSURL URLWithString:@"https://thanks.lhunath.com"]];
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark - Private
|
#pragma mark - Private
|
||||||
|
|||||||
@@ -17,20 +17,11 @@
|
|||||||
//==============================================================================
|
//==============================================================================
|
||||||
|
|
||||||
#import <UIKit/UIKit.h>
|
#import <UIKit/UIKit.h>
|
||||||
|
#import <StoreKit/StoreKit.h>
|
||||||
|
|
||||||
@class MPStoreProductCell;
|
@class MPStoreProductCell;
|
||||||
|
|
||||||
@interface MPStoreViewController : PearlMutableStaticTableViewController
|
@interface MPStoreViewController : UITableViewController
|
||||||
|
|
||||||
@property(weak, nonatomic) IBOutlet MPStoreProductCell *generateLoginCell;
|
|
||||||
@property(weak, nonatomic) IBOutlet MPStoreProductCell *generateAnswersCell;
|
|
||||||
@property(weak, nonatomic) IBOutlet MPStoreProductCell *iOSIntegrationCell;
|
|
||||||
@property(weak, nonatomic) IBOutlet MPStoreProductCell *touchIDCell;
|
|
||||||
@property(weak, nonatomic) IBOutlet MPStoreProductCell *fuelCell;
|
|
||||||
@property(weak, nonatomic) IBOutlet UITableViewCell *loadingCell;
|
|
||||||
@property(weak, nonatomic) IBOutlet NSLayoutConstraint *fuelMeterConstraint;
|
|
||||||
@property(weak, nonatomic) IBOutlet UIButton *fuelSpeedButton;
|
|
||||||
@property(weak, nonatomic) IBOutlet UILabel *fuelStatusLabel;
|
|
||||||
|
|
||||||
+ (NSString *)latestStoreFeatures;
|
+ (NSString *)latestStoreFeatures;
|
||||||
|
|
||||||
@@ -39,7 +30,23 @@
|
|||||||
@interface MPStoreProductCell : UITableViewCell
|
@interface MPStoreProductCell : UITableViewCell
|
||||||
|
|
||||||
@property(nonatomic) IBOutlet UILabel *priceLabel;
|
@property(nonatomic) IBOutlet UILabel *priceLabel;
|
||||||
|
@property(nonatomic) IBOutlet UILabel *titleLabel;
|
||||||
|
@property(nonatomic) IBOutlet UILabel *descriptionLabel;
|
||||||
|
@property(nonatomic) IBOutlet UIImageView *thumbnailView;
|
||||||
@property(nonatomic) IBOutlet UIActivityIndicatorView *activityIndicator;
|
@property(nonatomic) IBOutlet UIActivityIndicatorView *activityIndicator;
|
||||||
@property(nonatomic) IBOutlet UIView *purchasedIndicator;
|
@property(nonatomic) IBOutlet UIView *purchasedIndicator;
|
||||||
|
|
||||||
|
@property(nonatomic, readonly) SKProduct *product;
|
||||||
|
@property(nonatomic, readonly) NSInteger quantity;
|
||||||
|
|
||||||
|
- (void)updateWithProduct:(SKProduct *)product transaction:(SKPaymentTransaction *)transaction;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface MPStoreFuelProductCell : MPStoreProductCell
|
||||||
|
|
||||||
|
@property(weak, nonatomic) IBOutlet NSLayoutConstraint *fuelMeterConstraint;
|
||||||
|
@property(weak, nonatomic) IBOutlet UIButton *fuelSpeedButton;
|
||||||
|
@property(weak, nonatomic) IBOutlet UILabel *fuelStatusLabel;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -27,8 +27,9 @@ PearlEnum( MPDevelopmentFuelConsumption,
|
|||||||
|
|
||||||
@interface MPStoreViewController()<MPInAppDelegate>
|
@interface MPStoreViewController()<MPInAppDelegate>
|
||||||
|
|
||||||
@property(nonatomic, strong) NSNumberFormatter *currencyFormatter;
|
@property(nonatomic, strong) NSDictionary<NSString *, SKProduct *> *products;
|
||||||
@property(nonatomic, strong) NSArray *products;
|
@property(nonatomic, strong) NSDictionary<NSString *, SKPaymentTransaction *> *transactions;
|
||||||
|
@property(nonatomic, strong) NSMutableArray<NSArray *> *dataSource;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@@ -43,7 +44,7 @@ PearlEnum( MPDevelopmentFuelConsumption,
|
|||||||
];
|
];
|
||||||
NSInteger storeVersion = [[NSUserDefaults standardUserDefaults] integerForKey:@"storeVersion"];
|
NSInteger storeVersion = [[NSUserDefaults standardUserDefaults] integerForKey:@"storeVersion"];
|
||||||
for (; storeVersion < [storeVersions count]; ++storeVersion)
|
for (; storeVersion < [storeVersions count]; ++storeVersion)
|
||||||
[features appendFormat:@"%@\n", storeVersions[storeVersion]];
|
[features appendFormat:@"%@\n", storeVersions[(NSUInteger)storeVersion]];
|
||||||
if (![features length])
|
if (![features length])
|
||||||
return nil;
|
return nil;
|
||||||
|
|
||||||
@@ -57,14 +58,13 @@ PearlEnum( MPDevelopmentFuelConsumption,
|
|||||||
|
|
||||||
[super viewDidLoad];
|
[super viewDidLoad];
|
||||||
|
|
||||||
self.currencyFormatter = [NSNumberFormatter new];
|
|
||||||
self.currencyFormatter.numberStyle = NSNumberFormatterCurrencyStyle;
|
|
||||||
|
|
||||||
self.tableView.tableHeaderView = [UIView new];
|
self.tableView.tableHeaderView = [UIView new];
|
||||||
self.tableView.tableFooterView = [UIView new];
|
self.tableView.tableFooterView = [UIView new];
|
||||||
self.tableView.rowHeight = UITableViewAutomaticDimension;
|
self.tableView.rowHeight = UITableViewAutomaticDimension;
|
||||||
self.tableView.estimatedRowHeight = 400;
|
self.tableView.estimatedRowHeight = 400;
|
||||||
self.view.backgroundColor = [UIColor clearColor];
|
self.view.backgroundColor = [UIColor clearColor];
|
||||||
|
|
||||||
|
self.dataSource = [@[ @[], @[ @"MPStoreCellSpinner", @"MPStoreCellFooter" ] ] mutableCopy];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)viewWillAppear:(BOOL)animated {
|
- (void)viewWillAppear:(BOOL)animated {
|
||||||
@@ -73,50 +73,44 @@ PearlEnum( MPDevelopmentFuelConsumption,
|
|||||||
|
|
||||||
self.tableView.contentInset = UIEdgeInsetsMake( 64, 0, 49, 0 );
|
self.tableView.contentInset = UIEdgeInsetsMake( 64, 0, 49, 0 );
|
||||||
|
|
||||||
[self reloadCellsHiding:self.allCellsBySection[0] showing:@[ self.loadingCell ]];
|
|
||||||
[self.allCellsBySection[0] enumerateObjectsUsingBlock:^(MPStoreProductCell *cell, NSUInteger idx, BOOL *stop) {
|
|
||||||
if ([cell isKindOfClass:[MPStoreProductCell class]]) {
|
|
||||||
cell.purchasedIndicator.visible = NO;
|
|
||||||
[cell.activityIndicator stopAnimating];
|
|
||||||
}
|
|
||||||
}];
|
|
||||||
|
|
||||||
PearlAddNotificationObserver( NSUserDefaultsDidChangeNotification, nil, [NSOperationQueue mainQueue],
|
|
||||||
^(MPStoreViewController *self, NSNotification *note) {
|
|
||||||
[self updateProducts];
|
|
||||||
[self updateFuel];
|
|
||||||
} );
|
|
||||||
[[MPiOSAppDelegate get] registerProductsObserver:self];
|
[[MPiOSAppDelegate get] registerProductsObserver:self];
|
||||||
[self updateFuel];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)viewWillDisappear:(BOOL)animated {
|
- (void)viewWillDisappear:(BOOL)animated {
|
||||||
|
|
||||||
[super viewWillDisappear:animated];
|
[super viewWillDisappear:animated];
|
||||||
|
|
||||||
PearlRemoveNotificationObservers();
|
[[MPiOSAppDelegate get] removeProductsObserver:self];
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark - UITableViewDataSource
|
#pragma mark - UITableViewDataSource
|
||||||
|
|
||||||
- (MPStoreProductCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
|
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
|
||||||
|
|
||||||
MPStoreProductCell *cell = (MPStoreProductCell *)[super tableView:tableView cellForRowAtIndexPath:indexPath];
|
return [self.dataSource count];
|
||||||
if (indexPath.section == 0)
|
|
||||||
cell.selectionStyle = [[MPiOSAppDelegate get] isFeatureUnlocked:[self productForCell:cell].productIdentifier]?
|
|
||||||
UITableViewCellSelectionStyleNone: UITableViewCellSelectionStyleDefault;
|
|
||||||
|
|
||||||
if (cell.selectionStyle != UITableViewCellSelectionStyleNone) {
|
|
||||||
cell.selectedBackgroundView = [[UIView alloc] initWithFrame:cell.bounds];
|
|
||||||
cell.selectedBackgroundView.backgroundColor = [UIColor colorWithRGBAHex:0x78DDFB33];
|
|
||||||
}
|
|
||||||
|
|
||||||
return cell;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
|
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
|
||||||
|
|
||||||
return NO;
|
return [self.dataSource[(NSUInteger)section] count];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (MPStoreProductCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||||
|
|
||||||
|
id content = self.dataSource[(NSUInteger)indexPath.section][(NSUInteger)indexPath.row];
|
||||||
|
if ([content isKindOfClass:[SKProduct class]]) {
|
||||||
|
SKProduct *product = content;
|
||||||
|
MPStoreProductCell *cell;
|
||||||
|
if ([product.productIdentifier isEqualToString:MPProductFuel])
|
||||||
|
cell = [MPStoreFuelProductCell dequeueCellFromTableView:tableView indexPath:indexPath];
|
||||||
|
else
|
||||||
|
cell = [MPStoreProductCell dequeueCellFromTableView:tableView indexPath:indexPath];
|
||||||
|
[cell updateWithProduct:product transaction:self.transactions[product.productIdentifier]];
|
||||||
|
|
||||||
|
return cell;
|
||||||
|
}
|
||||||
|
|
||||||
|
return [tableView dequeueReusableCellWithIdentifier:content forIndexPath:indexPath];
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark - UITableViewDelegate
|
#pragma mark - UITableViewDelegate
|
||||||
@@ -128,14 +122,13 @@ PearlEnum( MPDevelopmentFuelConsumption,
|
|||||||
|
|
||||||
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
|
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||||
|
|
||||||
MPStoreProductCell *cell = (MPStoreProductCell *)[self tableView:tableView cellForRowAtIndexPath:indexPath];
|
UITableViewCell *cell = [self tableView:tableView cellForRowAtIndexPath:indexPath];
|
||||||
if (cell.selectionStyle == UITableViewCellSelectionStyleNone)
|
if (cell.selectionStyle != UITableViewCellSelectionStyleNone && [cell isKindOfClass:[MPStoreProductCell class]]) {
|
||||||
return;
|
MPStoreProductCell *productCell = (MPStoreProductCell *)cell;
|
||||||
|
|
||||||
SKProduct *product = [self productForCell:cell];
|
if (productCell.product && ![[MPAppDelegate_Shared get] isFeatureUnlocked:productCell.product.productIdentifier])
|
||||||
if (product && ![[MPAppDelegate_Shared get] isFeatureUnlocked:product.productIdentifier])
|
[[MPAppDelegate_Shared get] purchaseProductWithIdentifier:productCell.product.productIdentifier quantity:productCell.quantity];
|
||||||
[[MPAppDelegate_Shared get] purchaseProductWithIdentifier:product.productIdentifier
|
}
|
||||||
quantity:[self quantityForProductIdentifier:product.productIdentifier]];
|
|
||||||
|
|
||||||
[tableView deselectRowAtIndexPath:indexPath animated:YES];
|
[tableView deselectRowAtIndexPath:indexPath animated:YES];
|
||||||
}
|
}
|
||||||
@@ -146,7 +139,9 @@ PearlEnum( MPDevelopmentFuelConsumption,
|
|||||||
|
|
||||||
NSUInteger fuelConsumption = [[MPiOSConfig get].developmentFuelConsumption unsignedIntegerValue];
|
NSUInteger fuelConsumption = [[MPiOSConfig get].developmentFuelConsumption unsignedIntegerValue];
|
||||||
[MPiOSConfig get].developmentFuelConsumption = @((fuelConsumption + 1) % MPDevelopmentFuelConsumptionCount);
|
[MPiOSConfig get].developmentFuelConsumption = @((fuelConsumption + 1) % MPDevelopmentFuelConsumptionCount);
|
||||||
[self updateProducts];
|
|
||||||
|
[self.tableView updateDataSource:self.dataSource toSections:nil reloadItems:@[ self.products[MPProductFuel] ]
|
||||||
|
withRowAnimation:UITableViewRowAnimationAutomatic];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (IBAction)restorePurchases:(id)sender {
|
- (IBAction)restorePurchases:(id)sender {
|
||||||
@@ -165,41 +160,33 @@ PearlEnum( MPDevelopmentFuelConsumption,
|
|||||||
- (IBAction)sendThanks:(id)sender {
|
- (IBAction)sendThanks:(id)sender {
|
||||||
|
|
||||||
[[self dismissPopup].navigationController performSegueWithIdentifier:@"web" sender:
|
[[self dismissPopup].navigationController performSegueWithIdentifier:@"web" sender:
|
||||||
[NSURL URLWithString:@"http://thanks.lhunath.com"]];
|
[NSURL URLWithString:@"https://thanks.lhunath.com"]];
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark - MPInAppDelegate
|
#pragma mark - MPInAppDelegate
|
||||||
|
|
||||||
- (void)updateWithProducts:(NSArray *)products {
|
- (void)updateWithProducts:(NSDictionary<NSString *, SKProduct *> *)products
|
||||||
|
transactions:(NSDictionary<NSString *, SKPaymentTransaction *> *)transactions {
|
||||||
|
|
||||||
self.products = products;
|
self.products = products;
|
||||||
|
self.transactions = transactions;
|
||||||
|
NSMutableArray *newDataSource = [NSMutableArray arrayWithCapacity:2];
|
||||||
|
|
||||||
[self updateProducts];
|
// Section 0: products
|
||||||
}
|
[newDataSource addObject:[[products allValues] sortedArrayUsingComparator:
|
||||||
|
^NSComparisonResult(SKProduct *p1, SKProduct *p2) {
|
||||||
|
return [p1.productIdentifier compare:p2.productIdentifier];
|
||||||
|
}]];
|
||||||
|
NSArray *reloadProducts = [newDataSource[0] filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:
|
||||||
|
^BOOL(SKProduct *product, NSDictionary *bindings) {
|
||||||
|
return self.transactions[product.productIdentifier] != nil;
|
||||||
|
}]];
|
||||||
|
|
||||||
- (void)updateWithTransaction:(SKPaymentTransaction *)transaction {
|
// Section 1: information cells
|
||||||
|
[newDataSource addObject:@[ @"MPStoreCellFooter" ]];
|
||||||
|
|
||||||
MPStoreProductCell *cell = [self cellForProductIdentifier:transaction.payment.productIdentifier];
|
[self.tableView updateDataSource:self.dataSource toSections:newDataSource
|
||||||
if (!cell)
|
reloadItems:reloadProducts withRowAnimation:UITableViewRowAnimationAutomatic];
|
||||||
return;
|
|
||||||
|
|
||||||
switch (transaction.transactionState) {
|
|
||||||
case SKPaymentTransactionStatePurchasing:
|
|
||||||
[cell.activityIndicator startAnimating];
|
|
||||||
break;
|
|
||||||
case SKPaymentTransactionStatePurchased:
|
|
||||||
[cell.activityIndicator stopAnimating];
|
|
||||||
break;
|
|
||||||
case SKPaymentTransactionStateFailed:
|
|
||||||
[cell.activityIndicator stopAnimating];
|
|
||||||
break;
|
|
||||||
case SKPaymentTransactionStateRestored:
|
|
||||||
[cell.activityIndicator stopAnimating];
|
|
||||||
break;
|
|
||||||
case SKPaymentTransactionStateDeferred:
|
|
||||||
[cell.activityIndicator startAnimating];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark - Private
|
#pragma mark - Private
|
||||||
@@ -216,60 +203,80 @@ PearlEnum( MPDevelopmentFuelConsumption,
|
|||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (SKProduct *)productForCell:(MPStoreProductCell *)cell {
|
@end
|
||||||
|
|
||||||
for (SKProduct *product in self.products)
|
@implementation MPStoreProductCell
|
||||||
if ([self cellForProductIdentifier:product.productIdentifier] == cell)
|
|
||||||
return product;
|
- (void)updateWithProduct:(SKProduct *)product transaction:(SKPaymentTransaction *)transaction {
|
||||||
|
|
||||||
|
_product = product;
|
||||||
|
|
||||||
|
BOOL purchased = [[MPiOSAppDelegate get] isFeatureUnlocked:self.product.productIdentifier];
|
||||||
|
self.selectionStyle = purchased? UITableViewCellSelectionStyleNone: UITableViewCellSelectionStyleDefault;
|
||||||
|
self.selectedBackgroundView = self.selectionStyle == UITableViewCellSelectionStyleNone? nil: [[UIView alloc] initWithFrame:self.bounds];
|
||||||
|
self.selectedBackgroundView.backgroundColor = [UIColor colorWithRGBAHex:0x78DDFB33];
|
||||||
|
|
||||||
|
self.purchasedIndicator.visible = purchased;
|
||||||
|
self.priceLabel.text = purchased? @"": [self price];
|
||||||
|
self.titleLabel.text = product.localizedTitle;
|
||||||
|
self.descriptionLabel.text = product.localizedDescription;
|
||||||
|
self.thumbnailView.image = [self productImage];
|
||||||
|
|
||||||
|
if (transaction && (transaction.transactionState == SKPaymentTransactionStateDeferred ||
|
||||||
|
transaction.transactionState == SKPaymentTransactionStatePurchasing))
|
||||||
|
[self.activityIndicator startAnimating];
|
||||||
|
else
|
||||||
|
[self.activityIndicator stopAnimating];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UIImage *)productImage {
|
||||||
|
|
||||||
|
if ([MPProductGenerateLogins isEqualToString:self.product.productIdentifier])
|
||||||
|
return [UIImage imageNamed:@"thumb_generated_login"];
|
||||||
|
if ([MPProductGenerateAnswers isEqualToString:self.product.productIdentifier])
|
||||||
|
return [UIImage imageNamed:@"thumb_generated_answers"];
|
||||||
|
if ([MPProductOSIntegration isEqualToString:self.product.productIdentifier])
|
||||||
|
return [UIImage imageNamed:@"thumb_ios_integration"];
|
||||||
|
if ([MPProductTouchID isEqualToString:self.product.productIdentifier])
|
||||||
|
return [UIImage imageNamed:@"thumb_touch_id"];
|
||||||
|
if ([MPProductFuel isEqualToString:self.product.productIdentifier])
|
||||||
|
return [UIImage imageNamed:@"thumb_fuel"];
|
||||||
|
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (MPStoreProductCell *)cellForProductIdentifier:(NSString *)productIdentifier {
|
- (NSString *)price {
|
||||||
|
|
||||||
if ([productIdentifier isEqualToString:MPProductGenerateLogins])
|
NSNumberFormatter *currencyFormatter = [NSNumberFormatter new];
|
||||||
return self.generateLoginCell;
|
currencyFormatter.numberStyle = NSNumberFormatterCurrencyStyle;
|
||||||
if ([productIdentifier isEqualToString:MPProductGenerateAnswers])
|
currencyFormatter.locale = self.product.priceLocale;
|
||||||
return self.generateAnswersCell;
|
|
||||||
if ([productIdentifier isEqualToString:MPProductOSIntegration])
|
|
||||||
return self.iOSIntegrationCell;
|
|
||||||
if ([productIdentifier isEqualToString:MPProductTouchID])
|
|
||||||
return self.touchIDCell;
|
|
||||||
if ([productIdentifier isEqualToString:MPProductFuel])
|
|
||||||
return self.fuelCell;
|
|
||||||
|
|
||||||
return nil;
|
return [currencyFormatter stringFromNumber:@([self.product.price floatValue] * self.quantity)];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)updateProducts {
|
- (NSInteger)quantity {
|
||||||
|
|
||||||
NSMutableArray *showCells = [NSMutableArray array];
|
return 1;
|
||||||
NSMutableArray *hideCells = [NSMutableArray array];
|
|
||||||
[hideCells addObjectsFromArray:[self.allCellsBySection[0] array]];
|
|
||||||
[hideCells addObject:self.loadingCell];
|
|
||||||
|
|
||||||
for (SKProduct *product in self.products) {
|
|
||||||
[self showCellForProductWithIdentifier:MPProductGenerateLogins ifProduct:product showingCells:showCells];
|
|
||||||
[self showCellForProductWithIdentifier:MPProductGenerateAnswers ifProduct:product showingCells:showCells];
|
|
||||||
[self showCellForProductWithIdentifier:MPProductOSIntegration ifProduct:product showingCells:showCells];
|
|
||||||
[self showCellForProductWithIdentifier:MPProductTouchID ifProduct:product showingCells:showCells];
|
|
||||||
[self showCellForProductWithIdentifier:MPProductFuel ifProduct:product showingCells:showCells];
|
|
||||||
}
|
|
||||||
|
|
||||||
[hideCells removeObjectsInArray:showCells];
|
|
||||||
[self reloadCellsHiding:hideCells showing:showCells];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)updateFuel {
|
@end
|
||||||
|
|
||||||
|
@implementation MPStoreFuelProductCell
|
||||||
|
|
||||||
|
- (void)updateWithProduct:(SKProduct *)product transaction:(SKPaymentTransaction *)transaction {
|
||||||
|
|
||||||
|
[super updateWithProduct:product transaction:transaction];
|
||||||
|
|
||||||
CGFloat weeklyFuelConsumption = [self weeklyFuelConsumption]; /* consume x fuel / week */
|
CGFloat weeklyFuelConsumption = [self weeklyFuelConsumption]; /* consume x fuel / week */
|
||||||
|
[self.fuelSpeedButton setTitle:[self weeklyFuelConsumptionTitle] forState:UIControlStateNormal];
|
||||||
|
|
||||||
|
NSTimeInterval fuelSecondsElapsed = 0;
|
||||||
CGFloat fuelRemaining = [[MPiOSConfig get].developmentFuelRemaining floatValue]; /* x fuel left */
|
CGFloat fuelRemaining = [[MPiOSConfig get].developmentFuelRemaining floatValue]; /* x fuel left */
|
||||||
CGFloat fuelInvested = [[MPiOSConfig get].developmentFuelInvested floatValue]; /* x fuel left */
|
CGFloat fuelInvested = [[MPiOSConfig get].developmentFuelInvested floatValue]; /* x fuel left */
|
||||||
NSDate *now = [NSDate date];
|
NSDate *now = [NSDate date], *checked = [MPiOSConfig get].developmentFuelChecked;
|
||||||
NSTimeInterval fuelSecondsElapsed = -[[MPiOSConfig get].developmentFuelChecked timeIntervalSinceDate:now];
|
if (!checked || 3600 < (fuelSecondsElapsed = [now timeIntervalSinceDate:checked])) {
|
||||||
if (fuelSecondsElapsed > 3600 || ![MPiOSConfig get].developmentFuelChecked) {
|
|
||||||
NSTimeInterval weeksElapsed = fuelSecondsElapsed / (3600 * 24 * 7 /* 1 week */); /* x weeks elapsed */
|
NSTimeInterval weeksElapsed = fuelSecondsElapsed / (3600 * 24 * 7 /* 1 week */); /* x weeks elapsed */
|
||||||
NSTimeInterval fuelConsumed = weeklyFuelConsumption * weeksElapsed;
|
NSTimeInterval fuelConsumed = MIN( fuelRemaining, weeklyFuelConsumption * weeksElapsed );
|
||||||
fuelRemaining -= fuelConsumed;
|
fuelRemaining -= fuelConsumed;
|
||||||
fuelInvested += fuelConsumed;
|
fuelInvested += fuelConsumed;
|
||||||
[MPiOSConfig get].developmentFuelChecked = now;
|
[MPiOSConfig get].developmentFuelChecked = now;
|
||||||
@@ -277,54 +284,43 @@ PearlEnum( MPDevelopmentFuelConsumption,
|
|||||||
[MPiOSConfig get].developmentFuelInvested = @(fuelInvested);
|
[MPiOSConfig get].developmentFuelInvested = @(fuelInvested);
|
||||||
}
|
}
|
||||||
|
|
||||||
CGFloat fuelRatio = weeklyFuelConsumption == 0? 0: fuelRemaining / weeklyFuelConsumption; /* x weeks worth of fuel left */
|
CGFloat fuelRatio = weeklyFuelConsumption? fuelRemaining / weeklyFuelConsumption: 0; /* x weeks worth of fuel left */
|
||||||
[self.fuelMeterConstraint updateConstant:MIN( 0.5f, fuelRatio - 0.5f ) * 160]; /* -80pt = 0 weeks left, 80pt = >=1 week left */
|
[self.fuelMeterConstraint updateConstant:MIN( 0.5f, fuelRatio - 0.5f ) * 160]; /* -80pt = 0 weeks left, +80pt = >=1 week left */
|
||||||
self.fuelStatusLabel.text = strf( @"fuel left: %0.1f work hours\ninvested: %0.1f work hours", fuelRemaining, fuelInvested );
|
self.fuelStatusLabel.text = strf( @"Fuel left: %0.1f work hours\nFunded: %0.1f work hours", fuelRemaining, fuelInvested );
|
||||||
self.fuelStatusLabel.hidden = (fuelRemaining + fuelInvested) == 0;
|
self.fuelStatusLabel.hidden = (fuelRemaining + fuelInvested) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (NSInteger)quantity {
|
||||||
|
|
||||||
|
return MAX( 1, (NSInteger)ceil( MP_FUEL_HOURLY_RATE * [self weeklyFuelConsumption] ) );
|
||||||
|
}
|
||||||
|
|
||||||
- (CGFloat)weeklyFuelConsumption {
|
- (CGFloat)weeklyFuelConsumption {
|
||||||
|
|
||||||
switch ((MPDevelopmentFuelConsumption)[[MPiOSConfig get].developmentFuelConsumption unsignedIntegerValue]) {
|
switch ((MPDevelopmentFuelConsumption)[[MPiOSConfig get].developmentFuelConsumption unsignedIntegerValue]) {
|
||||||
case MPDevelopmentFuelConsumptionQuarterly:
|
case MPDevelopmentFuelConsumptionQuarterly:
|
||||||
[self.fuelSpeedButton setTitle:@"1h / quarter" forState:UIControlStateNormal];
|
|
||||||
return 1.f / 12 /* 12 weeks */;
|
return 1.f / 12 /* 12 weeks */;
|
||||||
case MPDevelopmentFuelConsumptionMonthly:
|
case MPDevelopmentFuelConsumptionMonthly:
|
||||||
[self.fuelSpeedButton setTitle:@"1h / month" forState:UIControlStateNormal];
|
|
||||||
return 1.f / 4 /* 4 weeks */;
|
return 1.f / 4 /* 4 weeks */;
|
||||||
case MPDevelopmentFuelWeekly:
|
case MPDevelopmentFuelWeekly:
|
||||||
[self.fuelSpeedButton setTitle:@"1h / week" forState:UIControlStateNormal];
|
return 1.f /* 1 week */;
|
||||||
return 1.f;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)showCellForProductWithIdentifier:(NSString *)productIdentifier ifProduct:(SKProduct *)product
|
- (NSString *)weeklyFuelConsumptionTitle {
|
||||||
showingCells:(NSMutableArray *)showCells {
|
|
||||||
|
|
||||||
if (![product.productIdentifier isEqualToString:productIdentifier])
|
switch ((MPDevelopmentFuelConsumption)[[MPiOSConfig get].developmentFuelConsumption unsignedIntegerValue]) {
|
||||||
return;
|
case MPDevelopmentFuelConsumptionQuarterly:
|
||||||
|
return @"1h / quarter";
|
||||||
|
case MPDevelopmentFuelConsumptionMonthly:
|
||||||
|
return @"1h / month";
|
||||||
|
case MPDevelopmentFuelWeekly:
|
||||||
|
return @"1h / week";
|
||||||
|
}
|
||||||
|
|
||||||
MPStoreProductCell *cell = [self cellForProductIdentifier:productIdentifier];
|
return nil;
|
||||||
[showCells addObject:cell];
|
|
||||||
|
|
||||||
self.currencyFormatter.locale = product.priceLocale;
|
|
||||||
BOOL purchased = [[MPiOSAppDelegate get] isFeatureUnlocked:productIdentifier];
|
|
||||||
NSInteger quantity = [self quantityForProductIdentifier:productIdentifier];
|
|
||||||
cell.priceLabel.text = purchased? @"": [self.currencyFormatter stringFromNumber:@([product.price floatValue] * quantity)];
|
|
||||||
cell.purchasedIndicator.visible = purchased;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSInteger)quantityForProductIdentifier:(NSString *)productIdentifier {
|
|
||||||
|
|
||||||
if ([productIdentifier isEqualToString:MPProductFuel])
|
|
||||||
return (NSInteger)(MP_FUEL_HOURLY_RATE * [self weeklyFuelConsumption] + .5f);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation MPStoreProductCell
|
|
||||||
@end
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
// LICENSE file. Alternatively, see <http://www.gnu.org/licenses/>.
|
// LICENSE file. Alternatively, see <http://www.gnu.org/licenses/>.
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
|
|
||||||
|
#import <Crashlytics/Answers.h>
|
||||||
#import "MPUsersViewController.h"
|
#import "MPUsersViewController.h"
|
||||||
#import "MPEntities.h"
|
#import "MPEntities.h"
|
||||||
#import "MPAvatarCell.h"
|
#import "MPAvatarCell.h"
|
||||||
@@ -58,6 +59,7 @@ typedef NS_ENUM( NSUInteger, MPActiveUserState ) {
|
|||||||
@implementation MPUsersViewController {
|
@implementation MPUsersViewController {
|
||||||
NSString *_masterPasswordChoice;
|
NSString *_masterPasswordChoice;
|
||||||
NSOperationQueue *_afterUpdates;
|
NSOperationQueue *_afterUpdates;
|
||||||
|
__weak id _contextChangedObserver;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)viewDidLoad {
|
- (void)viewDidLoad {
|
||||||
@@ -90,15 +92,6 @@ typedef NS_ENUM( NSUInteger, MPActiveUserState ) {
|
|||||||
self.userSelectionContainer.visible = NO;
|
self.userSelectionContainer.visible = NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)viewWillDisappear:(BOOL)animated {
|
|
||||||
|
|
||||||
[super viewWillDisappear:animated];
|
|
||||||
|
|
||||||
PearlRemoveNotificationObservers();
|
|
||||||
|
|
||||||
[self.marqueeTipTimer invalidate];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)viewDidAppear:(BOOL)animated {
|
- (void)viewDidAppear:(BOOL)animated {
|
||||||
|
|
||||||
[super viewDidAppear:animated];
|
[super viewDidAppear:animated];
|
||||||
@@ -126,8 +119,18 @@ typedef NS_ENUM( NSUInteger, MPActiveUserState ) {
|
|||||||
|
|
||||||
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
|
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
|
||||||
|
|
||||||
if ([segue.identifier isEqualToString:@"web"])
|
if ([segue.identifier isEqualToString:@"thanks"])
|
||||||
((MPWebViewController *)segue.destinationViewController).initialURL = [NSURL URLWithString:@"http://thanks.lhunath.com"];
|
((MPWebViewController *)segue.destinationViewController).initialURL =
|
||||||
|
[NSURL URLWithString:@"https://thanks.lhunath.com"];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)viewWillDisappear:(BOOL)animated {
|
||||||
|
|
||||||
|
[super viewWillDisappear:animated];
|
||||||
|
|
||||||
|
[self removeObservers];
|
||||||
|
|
||||||
|
[self.marqueeTipTimer invalidate];
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark - UITextFieldDelegate
|
#pragma mark - UITextFieldDelegate
|
||||||
@@ -223,6 +226,17 @@ typedef NS_ENUM( NSUInteger, MPActiveUserState ) {
|
|||||||
user.defaultType = user.algorithm.defaultType;
|
user.defaultType = user.algorithm.defaultType;
|
||||||
user.avatar = newUserAvatar;
|
user.avatar = newUserAvatar;
|
||||||
user.name = newUserName;
|
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
|
BOOL signedIn = [[MPiOSAppDelegate get] signInAsUser:user saveInContext:context
|
||||||
@@ -259,6 +273,9 @@ typedef NS_ENUM( NSUInteger, MPActiveUserState ) {
|
|||||||
// This isn't really in UITextFieldDelegate. We fake it from UITextFieldTextDidChangeNotification.
|
// This isn't really in UITextFieldDelegate. We fake it from UITextFieldTextDidChangeNotification.
|
||||||
- (void)textFieldEditingChanged:(UITextField *)textField {
|
- (void)textFieldEditingChanged:(UITextField *)textField {
|
||||||
|
|
||||||
|
if ([[textField.text lowercaseString] isEqualToString:@"hangtest"])
|
||||||
|
[NSThread sleepForTimeInterval:10];
|
||||||
|
|
||||||
if (textField == self.entryField) {
|
if (textField == self.entryField) {
|
||||||
switch (self.activeUserState) {
|
switch (self.activeUserState) {
|
||||||
case MPActiveUserStateNone:
|
case MPActiveUserStateNone:
|
||||||
@@ -368,7 +385,7 @@ referenceSizeForFooterInSection:(NSInteger)section {
|
|||||||
MPAvatarCell *userAvatar = [self selectedAvatar];
|
MPAvatarCell *userAvatar = [self selectedAvatar];
|
||||||
userAvatar.spinnerActive = YES;
|
userAvatar.spinnerActive = YES;
|
||||||
if (!isNew && mainUser && [MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
|
if (!isNew && mainUser && [MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
|
||||||
MPUserEntity *user = [MPUserEntity existingObjectWithID:mainUser.objectID inContext:context];
|
MPUserEntity *user = [MPUserEntity existingObjectWithID:mainUser.permanentObjectID inContext:context];
|
||||||
BOOL signedIn = [[MPiOSAppDelegate get] signInAsUser:user saveInContext:context usingMasterPassword:nil];
|
BOOL signedIn = [[MPiOSAppDelegate get] signInAsUser:user saveInContext:context usingMasterPassword:nil];
|
||||||
|
|
||||||
PearlMainQueue( ^{
|
PearlMainQueue( ^{
|
||||||
@@ -411,10 +428,10 @@ referenceSizeForFooterInSection:(NSInteger)section {
|
|||||||
|
|
||||||
BOOL isNew = NO;
|
BOOL isNew = NO;
|
||||||
MPUserEntity *user = [self userForAvatar:avatarCell inContext:mainContext isNew:&isNew];
|
MPUserEntity *user = [self userForAvatar:avatarCell inContext:mainContext isNew:&isNew];
|
||||||
NSManagedObjectID *userID = user.objectID;
|
|
||||||
if (isNew || !user)
|
if (isNew || !user)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
NSManagedObjectID *userID = user.permanentObjectID;
|
||||||
[PearlSheet showSheetWithTitle:user.name
|
[PearlSheet showSheetWithTitle:user.name
|
||||||
viewStyle:UIActionSheetStyleBlackTranslucent
|
viewStyle:UIActionSheetStyleBlackTranslucent
|
||||||
initSheet:nil tappedButtonBlock:^(UIActionSheet *sheet, NSInteger buttonIndex) {
|
initSheet:nil tappedButtonBlock:^(UIActionSheet *sheet, NSInteger buttonIndex) {
|
||||||
@@ -465,25 +482,23 @@ referenceSizeForFooterInSection:(NSInteger)section {
|
|||||||
- (void)deleteUser:(NSManagedObjectID *)userID {
|
- (void)deleteUser:(NSManagedObjectID *)userID {
|
||||||
|
|
||||||
[MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
|
[MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
|
||||||
MPUserEntity
|
MPUserEntity *user = [MPUserEntity existingObjectWithID:userID inContext:context];
|
||||||
*user_ = [MPUserEntity existingObjectWithID:userID inContext:context];
|
if (!user)
|
||||||
if (!user_)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
[context deleteObject:user_];
|
[context deleteObject:user];
|
||||||
[context saveToStore];
|
[context saveToStore];
|
||||||
[self reloadUsers]; // I do NOT understand why our ObjectsDidChangeNotification isn't firing on saveToStore.
|
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)resetUser:(NSManagedObjectID *)userID avatar:(MPAvatarCell *)avatarCell {
|
- (void)resetUser:(NSManagedObjectID *)userID avatar:(MPAvatarCell *)avatarCell {
|
||||||
|
|
||||||
[MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
|
[MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
|
||||||
MPUserEntity *user_ = [MPUserEntity existingObjectWithID:userID inContext:context];
|
MPUserEntity *user = [MPUserEntity existingObjectWithID:userID inContext:context];
|
||||||
if (!user_)
|
if (!user)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
[[MPiOSAppDelegate get] changeMasterPasswordFor:user_ saveInContext:context didResetBlock:^{
|
[[MPiOSAppDelegate get] changeMasterPasswordFor:user saveInContext:context didResetBlock:^{
|
||||||
PearlMainQueue( ^{
|
PearlMainQueue( ^{
|
||||||
NSIndexPath *avatarIndexPath = [self.avatarCollectionView indexPathForCell:avatarCell];
|
NSIndexPath *avatarIndexPath = [self.avatarCollectionView indexPathForCell:avatarCell];
|
||||||
[self.avatarCollectionView selectItemAtIndexPath:avatarIndexPath animated:NO
|
[self.avatarCollectionView selectItemAtIndexPath:avatarIndexPath animated:NO
|
||||||
@@ -645,15 +660,21 @@ referenceSizeForFooterInSection:(NSInteger)section {
|
|||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)registerObservers {
|
- (void)removeObservers {
|
||||||
|
|
||||||
[self removeKeyPathObservers];
|
[self removeKeyPathObservers];
|
||||||
|
PearlRemoveNotificationObservers();
|
||||||
|
[[NSNotificationCenter defaultCenter] removeObserver:_contextChangedObserver];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)registerObservers {
|
||||||
|
|
||||||
|
[self removeObservers];
|
||||||
[self observeKeyPath:@"avatarCollectionView.contentOffset" withBlock:
|
[self observeKeyPath:@"avatarCollectionView.contentOffset" withBlock:
|
||||||
^(id from, id to, NSKeyValueChange cause, MPUsersViewController *_self) {
|
^(id from, id to, NSKeyValueChange cause, MPUsersViewController *_self) {
|
||||||
[_self updateAvatarVisibility];
|
[_self updateAvatarVisibility];
|
||||||
}];
|
}];
|
||||||
|
|
||||||
PearlRemoveNotificationObservers();
|
|
||||||
PearlAddNotificationObserver( UIApplicationDidEnterBackgroundNotification, nil, [NSOperationQueue mainQueue],
|
PearlAddNotificationObserver( UIApplicationDidEnterBackgroundNotification, nil, [NSOperationQueue mainQueue],
|
||||||
^(MPUsersViewController *self, NSNotification *note) {
|
^(MPUsersViewController *self, NSNotification *note) {
|
||||||
self.userSelectionContainer.visible = NO;
|
self.userSelectionContainer.visible = NO;
|
||||||
@@ -675,37 +696,32 @@ referenceSizeForFooterInSection:(NSInteger)section {
|
|||||||
[self.keyboardHeightConstraint updateConstant:keyboardHeight];
|
[self.keyboardHeightConstraint updateConstant:keyboardHeight];
|
||||||
} );
|
} );
|
||||||
|
|
||||||
NSManagedObjectContext *mainContext = [MPiOSAppDelegate managedObjectContextForMainThreadIfReady];
|
if ((_contextChangedObserver = [MPiOSAppDelegate managedObjectContextChanged:^(NSDictionary<NSManagedObjectID *, NSString *> *affectedObjects) {
|
||||||
[UIView animateWithDuration:0.3f animations:^{
|
if ([[[affectedObjects allKeys] filteredArrayUsingPredicate:
|
||||||
self.avatarCollectionView.visible = mainContext != nil;
|
[NSPredicate predicateWithBlock:^BOOL(NSManagedObjectID *objectID, NSDictionary *bindings) {
|
||||||
}];
|
return [objectID.entity.name isEqualToString:NSStringFromClass( [MPUserEntity class] )];
|
||||||
if (mainContext && self.storeLoadingActivity.isAnimating)
|
|
||||||
[self.storeLoadingActivity stopAnimating];
|
|
||||||
if (!mainContext && !self.storeLoadingActivity.isAnimating)
|
|
||||||
[self.storeLoadingActivity startAnimating];
|
|
||||||
|
|
||||||
if (mainContext)
|
|
||||||
PearlAddNotificationObserver( NSManagedObjectContextObjectsDidChangeNotification, mainContext, nil,
|
|
||||||
^(MPUsersViewController *self, NSNotification *note) {
|
|
||||||
NSSet *insertedObjects = note.userInfo[NSInsertedObjectsKey];
|
|
||||||
NSSet *deletedObjects = note.userInfo[NSDeletedObjectsKey];
|
|
||||||
if ([[NSSetUnion( insertedObjects, deletedObjects )
|
|
||||||
filteredSetUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
|
|
||||||
return [evaluatedObject isKindOfClass:[MPUserEntity class]];
|
|
||||||
}]] count])
|
}]] count])
|
||||||
[self reloadUsers];
|
[self reloadUsers];
|
||||||
} );
|
}]))
|
||||||
|
[UIView animateWithDuration:0.3f animations:^{
|
||||||
|
self.avatarCollectionView.visible = YES;
|
||||||
|
[self.storeLoadingActivity stopAnimating];
|
||||||
|
}];
|
||||||
|
else
|
||||||
|
[UIView animateWithDuration:0.3f animations:^{
|
||||||
|
self.avatarCollectionView.visible = NO;
|
||||||
|
[self.storeLoadingActivity startAnimating];
|
||||||
|
}];
|
||||||
|
|
||||||
PearlAddNotificationObserver( NSPersistentStoreCoordinatorStoresWillChangeNotification, [MPiOSAppDelegate get].storeCoordinator, nil,
|
PearlAddNotificationObserver( NSPersistentStoreCoordinatorStoresWillChangeNotification, [MPiOSAppDelegate get].storeCoordinator, nil,
|
||||||
^(MPUsersViewController *self, NSNotification *note) {
|
^(MPUsersViewController *self, NSNotification *note) {
|
||||||
self.userIDs = nil;
|
self.userIDs = nil;
|
||||||
} );
|
} );
|
||||||
PearlAddNotificationObserver( NSPersistentStoreCoordinatorStoresDidChangeNotification, [MPiOSAppDelegate get].storeCoordinator, nil,
|
PearlAddNotificationObserver( NSPersistentStoreCoordinatorStoresDidChangeNotification, [MPiOSAppDelegate get].storeCoordinator, nil,
|
||||||
^(MPUsersViewController *self, NSNotification *note) {
|
^(MPUsersViewController *self, NSNotification *note) {
|
||||||
PearlMainQueue( ^{
|
|
||||||
[self registerObservers];
|
[self registerObservers];
|
||||||
[self reloadUsers];
|
[self reloadUsers];
|
||||||
} );
|
} );
|
||||||
} );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)reloadUsers {
|
- (void)reloadUsers {
|
||||||
@@ -719,13 +735,13 @@ referenceSizeForFooterInSection:(NSInteger)section {
|
|||||||
];
|
];
|
||||||
NSArray *users = [mainContext executeFetchRequest:fetchRequest error:&error];
|
NSArray *users = [mainContext executeFetchRequest:fetchRequest error:&error];
|
||||||
if (!users) {
|
if (!users) {
|
||||||
err( @"Failed to load users: %@", [error fullDescription] );
|
MPError( error, @"Failed to load users." );
|
||||||
self.userIDs = nil;
|
self.userIDs = nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
NSMutableArray *userIDs = [NSMutableArray arrayWithCapacity:[users count]];
|
NSMutableArray *userIDs = [NSMutableArray arrayWithCapacity:[users count]];
|
||||||
for (MPUserEntity *user in users)
|
for (MPUserEntity *user in users)
|
||||||
[userIDs addObject:user.objectID];
|
[userIDs addObject:user.permanentObjectID];
|
||||||
self.userIDs = userIDs;
|
self.userIDs = userIDs;
|
||||||
}])
|
}])
|
||||||
self.userIDs = nil;
|
self.userIDs = nil;
|
||||||
@@ -753,7 +769,7 @@ referenceSizeForFooterInSection:(NSInteger)section {
|
|||||||
NSManagedObjectID *selectUserID = [MPiOSAppDelegate get].activeUserOID;
|
NSManagedObjectID *selectUserID = [MPiOSAppDelegate get].activeUserOID;
|
||||||
if (!selectUserID)
|
if (!selectUserID)
|
||||||
selectUserID = [self selectedUserInContext:[MPiOSAppDelegate managedObjectContextForMainThreadIfReady]
|
selectUserID = [self selectedUserInContext:[MPiOSAppDelegate managedObjectContextForMainThreadIfReady]
|
||||||
isNew:&isNew].objectID;
|
isNew:&isNew].permanentObjectID;
|
||||||
[self.avatarCollectionView reloadData];
|
[self.avatarCollectionView reloadData];
|
||||||
|
|
||||||
NSUInteger selectedAvatarItem = isNew? [_userIDs count]: selectUserID? [_userIDs indexOfObject:selectUserID]: NSNotFound;
|
NSUInteger selectedAvatarItem = isNew? [_userIDs count]: selectUserID? [_userIDs indexOfObject:selectUserID]: NSNotFound;
|
||||||
|
|||||||
@@ -32,7 +32,7 @@
|
|||||||
[super viewWillAppear:animated];
|
[super viewWillAppear:animated];
|
||||||
|
|
||||||
if (!self.initialURL)
|
if (!self.initialURL)
|
||||||
self.initialURL = [NSURL URLWithString:@"http://masterpasswordapp.com"];
|
self.initialURL = [NSURL URLWithString:@"https://ssl.masterpasswordapp.com"];
|
||||||
|
|
||||||
self.webNavigationItem.title = self.initialURL.host;
|
self.webNavigationItem.title = self.initialURL.host;
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,8 @@
|
|||||||
#import "MPAppDelegate_Store.h"
|
#import "MPAppDelegate_Store.h"
|
||||||
#import "MPStoreViewController.h"
|
#import "MPStoreViewController.h"
|
||||||
|
|
||||||
|
#define MP_HANG_TIME_MAIN 3 // s
|
||||||
|
|
||||||
@interface MPiOSAppDelegate()<UIDocumentInteractionControllerDelegate>
|
@interface MPiOSAppDelegate()<UIDocumentInteractionControllerDelegate>
|
||||||
|
|
||||||
@property(nonatomic, strong) UIDocumentInteractionController *interactionController;
|
@property(nonatomic, strong) UIDocumentInteractionController *interactionController;
|
||||||
@@ -58,10 +60,9 @@
|
|||||||
[[Crashlytics sharedInstance] setUserIdentifier:[PearlKeyChain deviceIdentifier]];
|
[[Crashlytics sharedInstance] setUserIdentifier:[PearlKeyChain deviceIdentifier]];
|
||||||
[[Crashlytics sharedInstance] setObjectValue:[PearlKeyChain deviceIdentifier] forKey:@"deviceIdentifier"];
|
[[Crashlytics sharedInstance] setObjectValue:[PearlKeyChain deviceIdentifier] forKey:@"deviceIdentifier"];
|
||||||
[[Crashlytics sharedInstance] setUserName:@"Anonymous"];
|
[[Crashlytics sharedInstance] setUserName:@"Anonymous"];
|
||||||
[[Crashlytics sharedInstance] setObjectValue:@"Anonymous" forKey:@"username"];
|
|
||||||
[Crashlytics startWithAPIKey:crashlyticsAPIKey];
|
[Crashlytics startWithAPIKey:crashlyticsAPIKey];
|
||||||
[[PearlLogger get] registerListener:^BOOL(PearlLogMessage *message) {
|
[[PearlLogger get] registerListener:^BOOL(PearlLogMessage *message) {
|
||||||
PearlLogLevel level = PearlLogLevelInfo;
|
PearlLogLevel level = PearlLogLevelWarn;
|
||||||
if ([[MPConfig get].sendInfo boolValue])
|
if ([[MPConfig get].sendInfo boolValue])
|
||||||
level = PearlLogLevelDebug;
|
level = PearlLogLevelDebug;
|
||||||
|
|
||||||
@@ -74,6 +75,8 @@
|
|||||||
[Crashlytics sharedInstance].version, [PearlInfoPlist get].CFBundleName, [PearlInfoPlist get].CFBundleVersion );
|
[Crashlytics sharedInstance].version, [PearlInfoPlist get].CFBundleName, [PearlInfoPlist get].CFBundleVersion );
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
[self installHangDetector];
|
||||||
}
|
}
|
||||||
@catch (id exception) {
|
@catch (id exception) {
|
||||||
err( @"During Analytics Setup: %@", exception );
|
err( @"During Analytics Setup: %@", exception );
|
||||||
@@ -82,9 +85,6 @@
|
|||||||
PearlAddNotificationObserver( MPCheckConfigNotification, nil, [NSOperationQueue mainQueue], ^(id self, NSNotification *note) {
|
PearlAddNotificationObserver( MPCheckConfigNotification, nil, [NSOperationQueue mainQueue], ^(id self, NSNotification *note) {
|
||||||
[self updateConfigKey:note.object];
|
[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) {
|
PearlAddNotificationObserver( NSUserDefaultsDidChangeNotification, nil, nil, ^(id self, NSNotification *note) {
|
||||||
[[NSNotificationCenter defaultCenter] postNotificationName:MPCheckConfigNotification object:nil];
|
[[NSNotificationCenter defaultCenter] postNotificationName:MPCheckConfigNotification object:nil];
|
||||||
} );
|
} );
|
||||||
@@ -143,6 +143,31 @@
|
|||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)installHangDetector {
|
||||||
|
|
||||||
|
__block NSDate *latestPing = [NSDate date];
|
||||||
|
__block __weak VoidBlock wPingOp, wPongOp;
|
||||||
|
|
||||||
|
VoidBlock pingOp = ^{
|
||||||
|
latestPing = [NSDate date];
|
||||||
|
dispatch_after( dispatch_time( DISPATCH_TIME_NOW, 100 * NSEC_PER_MSEC ), dispatch_get_main_queue(), wPingOp );
|
||||||
|
}, pongOp = ^{
|
||||||
|
NSTimeInterval hangTime = -[latestPing timeIntervalSinceNow];
|
||||||
|
if (hangTime > MP_HANG_TIME_MAIN) {
|
||||||
|
MPError( [NSError errorWithDomain:MPErrorDomain code:MPErrorHangCode userInfo:@{
|
||||||
|
@"time": @(hangTime)
|
||||||
|
}], @"Timeout waiting for main thread after %fs.", hangTime );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
dbg( @"hangTime=%f", hangTime );
|
||||||
|
|
||||||
|
dispatch_after( dispatch_time( DISPATCH_TIME_NOW, NSEC_PER_SEC ), dispatch_get_global_queue( QOS_CLASS_BACKGROUND, 0 ), wPongOp );
|
||||||
|
};
|
||||||
|
|
||||||
|
(wPingOp = pingOp)();
|
||||||
|
(wPongOp = pongOp)();
|
||||||
|
}
|
||||||
|
|
||||||
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url
|
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url
|
||||||
sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
|
sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
|
||||||
|
|
||||||
@@ -154,7 +179,8 @@
|
|||||||
[[[NSURLSession sharedSession] dataTaskWithURL:url completionHandler:
|
[[[NSURLSession sharedSession] dataTaskWithURL:url completionHandler:
|
||||||
^(NSData *importedSitesData, NSURLResponse *response, NSError *error) {
|
^(NSData *importedSitesData, NSURLResponse *response, NSError *error) {
|
||||||
if (error)
|
if (error)
|
||||||
err( @"While reading imported sites from %@: %@", url, [error fullDescription] );
|
MPError( error, @"While reading imported sites from %@.", url );
|
||||||
|
|
||||||
if (!importedSitesData) {
|
if (!importedSitesData) {
|
||||||
[PearlAlert showError:strf( @"Master Password couldn't read the import sites.\n\n%@",
|
[PearlAlert showError:strf( @"Master Password couldn't read the import sites.\n\n%@",
|
||||||
[error localizedDescription]?: error )];
|
[error localizedDescription]?: error )];
|
||||||
@@ -244,6 +270,44 @@
|
|||||||
if (![[MPiOSConfig get].rememberLogin boolValue])
|
if (![[MPiOSConfig get].rememberLogin boolValue])
|
||||||
[self signOutAnimated:NO];
|
[self signOutAnimated:NO];
|
||||||
|
|
||||||
|
// self.task = [application beginBackgroundTaskWithExpirationHandler:^{
|
||||||
|
// [application endBackgroundTask:self.task];
|
||||||
|
// dbg( @"background expiring" );
|
||||||
|
// }];
|
||||||
|
// PearlNotMainQueueOperation( ^{
|
||||||
|
// NSString *pbstring = [UIPasteboard generalPasteboard].string;
|
||||||
|
// while (YES) {
|
||||||
|
// NSString *newString = [UIPasteboard generalPasteboard].string;
|
||||||
|
// if (![newString isEqualToString:pbstring]) {
|
||||||
|
// dbg( @"pasteboard changed to: %@", newString );
|
||||||
|
// pbstring = newString;
|
||||||
|
// NSURL *url = [NSURL URLWithString:pbstring];
|
||||||
|
// if (url) {
|
||||||
|
// NSString *siteName = [url host];
|
||||||
|
// }
|
||||||
|
// MPKey *key = [MPiOSAppDelegate get].key;
|
||||||
|
// if (key)
|
||||||
|
// [MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
|
||||||
|
// NSFetchRequest<MPSiteEntity *>
|
||||||
|
// *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:NSStringFromClass( [MPSiteEntity class] )];
|
||||||
|
// fetchRequest.sortDescriptors = @[
|
||||||
|
// [[NSSortDescriptor alloc] initWithKey:NSStringFromSelector( @selector( lastUsed ) ) ascending:NO]
|
||||||
|
// ];
|
||||||
|
// fetchRequest.fetchBatchSize = 2;
|
||||||
|
// fetchRequest.predicate = [NSPredicate predicateWithFormat:@"(name LIKE[cd] %@) AND user == %@", siteName,
|
||||||
|
// [[MPiOSAppDelegate get] activeUserOID]];
|
||||||
|
// NSError *error = nil;
|
||||||
|
// NSArray<MPSiteEntity *> *results = [fetchRequest execute:&error];
|
||||||
|
// dbg( @"site search, error: %@, results:\n%@", error, results );
|
||||||
|
// if ([results count]) {
|
||||||
|
// [UIPasteboard generalPasteboard].string = [[results firstObject] resolvePasswordUsingKey:key];
|
||||||
|
// }
|
||||||
|
// }];
|
||||||
|
// }
|
||||||
|
// [NSThread sleepForTimeInterval:5];
|
||||||
|
// }
|
||||||
|
// } );
|
||||||
|
|
||||||
[super applicationDidEnterBackground:application];
|
[super applicationDidEnterBackground:application];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -444,7 +508,7 @@
|
|||||||
NSError *error = nil;
|
NSError *error = nil;
|
||||||
if (![[exportedSites dataUsingEncoding:NSUTF8StringEncoding]
|
if (![[exportedSites dataUsingEncoding:NSUTF8StringEncoding]
|
||||||
writeToURL:exportURL options:NSDataWritingFileProtectionComplete error:&error])
|
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 {
|
else {
|
||||||
self.interactionController = [UIDocumentInteractionController interactionControllerWithURL:exportURL];
|
self.interactionController = [UIDocumentInteractionController interactionControllerWithURL:exportURL];
|
||||||
self.interactionController.UTI = @"com.lyndir.masterpassword.sites";
|
self.interactionController.UTI = @"com.lyndir.masterpassword.sites";
|
||||||
@@ -535,7 +599,7 @@
|
|||||||
static NSDictionary *crashlyticsInfo = nil;
|
static NSDictionary *crashlyticsInfo = nil;
|
||||||
if (crashlyticsInfo == nil)
|
if (crashlyticsInfo == nil)
|
||||||
crashlyticsInfo = [[NSDictionary alloc] initWithContentsOfURL:
|
crashlyticsInfo = [[NSDictionary alloc] initWithContentsOfURL:
|
||||||
[[NSBundle mainBundle] URLForResource:@"Crashlytics" withExtension:@"plist"]];
|
[[NSBundle mainBundle] URLForResource:@"Fabric" withExtension:@"plist"]];
|
||||||
|
|
||||||
return crashlyticsInfo;
|
return crashlyticsInfo;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,7 +60,7 @@
|
|||||||
<key>LSRequiresIPhoneOS</key>
|
<key>LSRequiresIPhoneOS</key>
|
||||||
<true/>
|
<true/>
|
||||||
<key>NSHumanReadableCopyright</key>
|
<key>NSHumanReadableCopyright</key>
|
||||||
<string>© 2011-2016 Lyndir</string>
|
<string>© 2011-2017</string>
|
||||||
<key>UIAppFonts</key>
|
<key>UIAppFonts</key>
|
||||||
<array>
|
<array>
|
||||||
<string>Exo2.0-Bold.otf</string>
|
<string>Exo2.0-Bold.otf</string>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<array>
|
<array>
|
||||||
<dict>
|
<dict>
|
||||||
<key>FooterText</key>
|
<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>
|
<key>Title</key>
|
||||||
<string></string>
|
<string></string>
|
||||||
<key>Type</key>
|
<key>Type</key>
|
||||||
@@ -50,7 +50,7 @@
|
|||||||
<key>Key</key>
|
<key>Key</key>
|
||||||
<string>sendInfo</string>
|
<string>sendInfo</string>
|
||||||
<key>DefaultValue</key>
|
<key>DefaultValue</key>
|
||||||
<false/>
|
<true/>
|
||||||
</dict>
|
</dict>
|
||||||
<dict>
|
<dict>
|
||||||
<key>FooterText</key>
|
<key>FooterText</key>
|
||||||
|
|||||||
@@ -292,7 +292,7 @@
|
|||||||
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
</state>
|
</state>
|
||||||
<connections>
|
<connections>
|
||||||
<segue destination="Sd5-eW-Cx2" kind="modal" identifier="web" id="gtb-zE-u9H"/>
|
<segue destination="Sd5-eW-Cx2" kind="modal" identifier="thanks" id="gtb-zE-u9H"/>
|
||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
<view userInteractionEnabled="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="069-Pu-yXe" userLabel="Thanks Tip">
|
<view userInteractionEnabled="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="069-Pu-yXe" userLabel="Thanks Tip">
|
||||||
@@ -708,13 +708,13 @@
|
|||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" alpha="0.69999999999999996" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="249" text="The password type to use to when creating a new site." lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="mzg-1u-aEg">
|
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" alpha="0.69999999999999996" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="249" text="The password type to use to when creating a new site." lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="mzg-1u-aEg">
|
||||||
<rect key="frame" x="20" y="48" width="335" height="50.5"/>
|
<rect key="frame" x="20" y="48" width="335" height="51"/>
|
||||||
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="12"/>
|
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="12"/>
|
||||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
<segmentedControl opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="bar" translatesAutoresizingMaskIntoConstraints="NO" id="E0r-Ey-eVH" userLabel="Type">
|
<segmentedControl opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="bar" translatesAutoresizingMaskIntoConstraints="NO" id="E0r-Ey-eVH" userLabel="Type">
|
||||||
<rect key="frame" x="131" y="106.5" width="113" height="29"/>
|
<rect key="frame" x="131" y="107" width="113" height="29"/>
|
||||||
<segments>
|
<segments>
|
||||||
<segment title="Phrase"/>
|
<segment title="Phrase"/>
|
||||||
<segment title="Name"/>
|
<segment title="Name"/>
|
||||||
@@ -725,7 +725,7 @@
|
|||||||
</connections>
|
</connections>
|
||||||
</segmentedControl>
|
</segmentedControl>
|
||||||
<segmentedControl opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="bar" selectedSegmentIndex="1" translatesAutoresizingMaskIntoConstraints="NO" id="H8F-E0-dqF" userLabel="Type">
|
<segmentedControl opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="bar" selectedSegmentIndex="1" translatesAutoresizingMaskIntoConstraints="NO" id="H8F-E0-dqF" userLabel="Type">
|
||||||
<rect key="frame" x="41" y="142.5" width="293" height="29"/>
|
<rect key="frame" x="41" y="143" width="293" height="29"/>
|
||||||
<segments>
|
<segments>
|
||||||
<segment title="Max"/>
|
<segment title="Max"/>
|
||||||
<segment title="Long"/>
|
<segment title="Long"/>
|
||||||
@@ -740,7 +740,7 @@
|
|||||||
</connections>
|
</connections>
|
||||||
</segmentedControl>
|
</segmentedControl>
|
||||||
<segmentedControl opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="bar" translatesAutoresizingMaskIntoConstraints="NO" id="Rei-aO-UBD" userLabel="Type">
|
<segmentedControl opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="bar" translatesAutoresizingMaskIntoConstraints="NO" id="Rei-aO-UBD" userLabel="Type">
|
||||||
<rect key="frame" x="86" y="178.5" width="203" height="29"/>
|
<rect key="frame" x="86" y="179" width="203" height="29"/>
|
||||||
<segments>
|
<segments>
|
||||||
<segment title="Personal"/>
|
<segment title="Personal"/>
|
||||||
<segment title="Device Private"/>
|
<segment title="Device Private"/>
|
||||||
@@ -751,7 +751,7 @@
|
|||||||
</connections>
|
</connections>
|
||||||
</segmentedControl>
|
</segmentedControl>
|
||||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" text="eg. LarwPopm4@Zewt" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="lhS-L1-2OB">
|
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" text="eg. LarwPopm4@Zewt" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="lhS-L1-2OB">
|
||||||
<rect key="frame" x="20" y="214.5" width="335" height="14.5"/>
|
<rect key="frame" x="20" y="215" width="335" height="14"/>
|
||||||
<fontDescription key="fontDescription" name="Exo2.0-Thin" family="Exo 2.0" pointSize="12"/>
|
<fontDescription key="fontDescription" name="Exo2.0-Thin" family="Exo 2.0" pointSize="12"/>
|
||||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
@@ -1039,7 +1039,7 @@
|
|||||||
<rect key="frame" x="0.0" y="0.0" width="375" height="249.5"/>
|
<rect key="frame" x="0.0" y="0.0" width="375" height="249.5"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" alpha="0.69999999999999996" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="999" verticalCompressionResistancePriority="1000" text="© 2012-2014, Maarten Billemont (lhunath)" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="sPw-mV-mFF">
|
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" alpha="0.69999999999999996" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="999" verticalCompressionResistancePriority="1000" text="© 2011-2017, Maarten Billemont (lhunath)" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="sPw-mV-mFF">
|
||||||
<rect key="frame" x="20" y="4" width="335" height="105"/>
|
<rect key="frame" x="20" y="4" width="335" height="105"/>
|
||||||
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="11"/>
|
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="11"/>
|
||||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
@@ -1155,19 +1155,18 @@
|
|||||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="K2e-Gh-7hH" userLabel="Passwords Container">
|
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="K2e-Gh-7hH" userLabel="Passwords Container">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<collectionView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" minimumZoomScale="0.0" maximumZoomScale="0.0" keyboardDismissMode="onDrag" dataMode="prototypes" translatesAutoresizingMaskIntoConstraints="NO" id="aXw-tn-8Sj" userLabel="Password Collection">
|
<collectionView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" minimumZoomScale="0.0" maximumZoomScale="0.0" dataMode="prototypes" translatesAutoresizingMaskIntoConstraints="NO" id="aXw-tn-8Sj" userLabel="Password Collection">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<inset key="scrollIndicatorInsets" minX="0.0" minY="108" maxX="0.0" maxY="0.0"/>
|
|
||||||
<collectionViewFlowLayout key="collectionViewLayout" minimumLineSpacing="10" minimumInteritemSpacing="10" id="Mv1-29-TWx">
|
<collectionViewFlowLayout key="collectionViewLayout" minimumLineSpacing="10" minimumInteritemSpacing="10" id="Mv1-29-TWx">
|
||||||
<size key="itemSize" width="355" height="100"/>
|
<size key="itemSize" width="355" height="100"/>
|
||||||
<size key="headerReferenceSize" width="0.0" height="0.0"/>
|
<size key="headerReferenceSize" width="0.0" height="0.0"/>
|
||||||
<size key="footerReferenceSize" width="0.0" height="0.0"/>
|
<size key="footerReferenceSize" width="0.0" height="0.0"/>
|
||||||
<inset key="sectionInset" minX="10" minY="118" maxX="10" maxY="10"/>
|
<inset key="sectionInset" minX="10" minY="200" maxX="10" maxY="10"/>
|
||||||
</collectionViewFlowLayout>
|
</collectionViewFlowLayout>
|
||||||
<cells>
|
<cells>
|
||||||
<collectionViewCell opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" reuseIdentifier="MPPasswordCell" id="W2g-yv-V3V" customClass="MPPasswordCell">
|
<collectionViewCell opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" reuseIdentifier="MPPasswordCell" id="W2g-yv-V3V" customClass="MPPasswordCell">
|
||||||
<rect key="frame" x="10" y="118" width="355" height="100"/>
|
<rect key="frame" x="10" y="200" width="355" height="100"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
|
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="355" height="100"/>
|
<rect key="frame" x="0.0" y="0.0" width="355" height="100"/>
|
||||||
@@ -1210,7 +1209,7 @@
|
|||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
<label opaque="NO" userInteractionEnabled="NO" alpha="0.20000000000000001" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="⚙" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="z3Z-Zc-1EC">
|
<label opaque="NO" userInteractionEnabled="NO" alpha="0.20000000000000001" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="⚙" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="z3Z-Zc-1EC">
|
||||||
<rect key="frame" x="332" y="5" width="15" height="13"/>
|
<rect key="frame" x="332" y="4.5" width="15" height="13.5"/>
|
||||||
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="11"/>
|
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="11"/>
|
||||||
<nil key="textColor"/>
|
<nil key="textColor"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
@@ -1247,12 +1246,12 @@
|
|||||||
</constraints>
|
</constraints>
|
||||||
</view>
|
</view>
|
||||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="2tX-WK-ASq" userLabel="Password Container">
|
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="2tX-WK-ASq" userLabel="Password Container">
|
||||||
<rect key="frame" x="0.0" y="20" width="355" height="43"/>
|
<rect key="frame" x="0.0" y="19" width="355" height="45"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" enabled="NO" contentHorizontalAlignment="left" contentVerticalAlignment="center" text="CuzaSasy3*Rimo" textAlignment="center" minimumFontSize="17" clearButtonMode="whileEditing" translatesAutoresizingMaskIntoConstraints="NO" id="blw-Ou-8I8" userLabel="Password">
|
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" enabled="NO" contentHorizontalAlignment="left" contentVerticalAlignment="center" text="CuzaSasy3*Rimo" textAlignment="center" minimumFontSize="17" clearButtonMode="whileEditing" translatesAutoresizingMaskIntoConstraints="NO" id="blw-Ou-8I8" userLabel="Password">
|
||||||
<rect key="frame" x="8" y="0.0" width="339" height="31"/>
|
<rect key="frame" x="8" y="0.0" width="339" height="33"/>
|
||||||
<color key="textColor" red="0.40000000600000002" green="0.80000001190000003" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="textColor" red="0.40000000600000002" green="0.80000001190000003" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<fontDescription key="fontDescription" name="SourceCodePro-Black" family="Source Code Pro" pointSize="24"/>
|
<fontDescription key="fontDescription" name="SourceCodePro-Black" family="Source Code Pro" pointSize="26"/>
|
||||||
<textInputTraits key="textInputTraits" autocorrectionType="no" keyboardType="alphabet" keyboardAppearance="alert" returnKeyType="next"/>
|
<textInputTraits key="textInputTraits" autocorrectionType="no" keyboardType="alphabet" keyboardAppearance="alert" returnKeyType="next"/>
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="textFieldDidChange:" destination="W2g-yv-V3V" eventType="editingChanged" id="gTE-0d-r2l"/>
|
<action selector="textFieldDidChange:" destination="W2g-yv-V3V" eventType="editingChanged" id="gTE-0d-r2l"/>
|
||||||
@@ -1260,7 +1259,7 @@
|
|||||||
</connections>
|
</connections>
|
||||||
</textField>
|
</textField>
|
||||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" tag="3" contentMode="left" text="> age of the universe" textAlignment="center" lineBreakMode="tailTruncation" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="wfM-xz-roR" userLabel="Strength">
|
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" tag="3" contentMode="left" text="> age of the universe" textAlignment="center" lineBreakMode="tailTruncation" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="wfM-xz-roR" userLabel="Strength">
|
||||||
<rect key="frame" x="0.0" y="31" width="355" height="12"/>
|
<rect key="frame" x="0.0" y="33" width="355" height="12"/>
|
||||||
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="10"/>
|
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="10"/>
|
||||||
<color key="textColor" red="0.66666666666666663" green="0.66666666666666663" blue="0.66666666666666663" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="textColor" red="0.66666666666666663" green="0.66666666666666663" blue="0.66666666666666663" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
@@ -1308,9 +1307,12 @@
|
|||||||
</view>
|
</view>
|
||||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="LvK-28-fbm" userLabel="Settings Container">
|
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="LvK-28-fbm" userLabel="Settings Container">
|
||||||
<rect key="frame" x="355" y="0.0" width="355" height="100"/>
|
<rect key="frame" x="355" y="0.0" width="355" height="100"/>
|
||||||
|
<subviews>
|
||||||
|
<stackView opaque="NO" contentMode="scaleToFill" alignment="center" translatesAutoresizingMaskIntoConstraints="NO" id="kfn-Wq-g5M">
|
||||||
|
<rect key="frame" x="-4" y="56" width="315" height="44"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<button opaque="NO" alpha="0.5" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" showsTouchWhenHighlighted="YES" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="IKd-Ot-0n4" userLabel="Upgrade">
|
<button opaque="NO" alpha="0.5" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" showsTouchWhenHighlighted="YES" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="IKd-Ot-0n4" userLabel="Upgrade">
|
||||||
<rect key="frame" x="40" y="56" width="44" height="44"/>
|
<rect key="frame" x="0.0" y="0.0" width="44" height="44"/>
|
||||||
<accessibility key="accessibilityConfiguration" hint="Upgrades the password."/>
|
<accessibility key="accessibilityConfiguration" hint="Upgrades the password."/>
|
||||||
<gestureRecognizers/>
|
<gestureRecognizers/>
|
||||||
<constraints>
|
<constraints>
|
||||||
@@ -1330,8 +1332,29 @@
|
|||||||
<action selector="doUpgrade:" destination="W2g-yv-V3V" eventType="touchUpInside" id="kTZ-AM-qGa"/>
|
<action selector="doUpgrade:" destination="W2g-yv-V3V" eventType="touchUpInside" id="kTZ-AM-qGa"/>
|
||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
|
<button opaque="NO" alpha="0.5" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" showsTouchWhenHighlighted="YES" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="yPG-30-POQ" userLabel="Action">
|
||||||
|
<rect key="frame" x="44" y="0.0" width="44" height="44"/>
|
||||||
|
<accessibility key="accessibilityConfiguration" hint="Upgrades the password."/>
|
||||||
|
<gestureRecognizers/>
|
||||||
|
<constraints>
|
||||||
|
<constraint firstAttribute="width" constant="44" id="Ruj-lV-Vr6"/>
|
||||||
|
<constraint firstAttribute="height" constant="44" id="fkk-9t-ufv"/>
|
||||||
|
</constraints>
|
||||||
|
<fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
|
||||||
|
<inset key="contentEdgeInsets" minX="6" minY="6" maxX="6" maxY="6"/>
|
||||||
|
<state key="normal" image="icon_action.png">
|
||||||
|
<color key="titleColor" red="0.19607843459999999" green="0.30980393290000002" blue="0.52156865600000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
|
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
|
</state>
|
||||||
|
<state key="highlighted">
|
||||||
|
<color key="titleColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
|
</state>
|
||||||
|
<connections>
|
||||||
|
<action selector="doAction:" destination="W2g-yv-V3V" eventType="touchUpInside" id="pGL-dJ-lDW"/>
|
||||||
|
</connections>
|
||||||
|
</button>
|
||||||
<button opaque="NO" alpha="0.5" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" showsTouchWhenHighlighted="YES" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="vGk-t6-hZn" userLabel="Answers">
|
<button opaque="NO" alpha="0.5" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" showsTouchWhenHighlighted="YES" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="vGk-t6-hZn" userLabel="Answers">
|
||||||
<rect key="frame" x="84" y="56" width="44" height="44"/>
|
<rect key="frame" x="88" y="0.0" width="44" height="44"/>
|
||||||
<accessibility key="accessibilityConfiguration" hint="Upgrades the password."/>
|
<accessibility key="accessibilityConfiguration" hint="Upgrades the password."/>
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstAttribute="width" constant="44" id="8gK-8v-Q0K"/>
|
<constraint firstAttribute="width" constant="44" id="8gK-8v-Q0K"/>
|
||||||
@@ -1351,7 +1374,7 @@
|
|||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" alpha="0.5" contentMode="left" text="1" textAlignment="right" lineBreakMode="tailTruncation" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="PKP-M9-T8E" userLabel="Counter">
|
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" alpha="0.5" contentMode="left" text="1" textAlignment="right" lineBreakMode="tailTruncation" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="PKP-M9-T8E" userLabel="Counter">
|
||||||
<rect key="frame" x="128" y="67.5" width="7" height="21"/>
|
<rect key="frame" x="132" y="11.5" width="7" height="21.5"/>
|
||||||
<accessibility key="accessibilityConfiguration" hint="Site's counter."/>
|
<accessibility key="accessibilityConfiguration" hint="Site's counter."/>
|
||||||
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="17"/>
|
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="17"/>
|
||||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
@@ -1360,7 +1383,7 @@
|
|||||||
<size key="shadowOffset" width="0.0" height="1"/>
|
<size key="shadowOffset" width="0.0" height="1"/>
|
||||||
</label>
|
</label>
|
||||||
<button opaque="NO" alpha="0.5" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" showsTouchWhenHighlighted="YES" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="uZi-FT-Fe8" userLabel="Incrementer">
|
<button opaque="NO" alpha="0.5" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" showsTouchWhenHighlighted="YES" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="uZi-FT-Fe8" userLabel="Incrementer">
|
||||||
<rect key="frame" x="135" y="56" width="44" height="44"/>
|
<rect key="frame" x="139" y="0.0" width="44" height="44"/>
|
||||||
<accessibility key="accessibilityConfiguration" hint="Increments the site counter."/>
|
<accessibility key="accessibilityConfiguration" hint="Increments the site counter."/>
|
||||||
<gestureRecognizers/>
|
<gestureRecognizers/>
|
||||||
<constraints>
|
<constraints>
|
||||||
@@ -1381,7 +1404,7 @@
|
|||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
<button opaque="NO" alpha="0.5" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" showsTouchWhenHighlighted="YES" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="qBo-Kw-vN9" userLabel="Edit">
|
<button opaque="NO" alpha="0.5" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" showsTouchWhenHighlighted="YES" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="qBo-Kw-vN9" userLabel="Edit">
|
||||||
<rect key="frame" x="179" y="56" width="44" height="44"/>
|
<rect key="frame" x="183" y="0.0" width="44" height="44"/>
|
||||||
<accessibility key="accessibilityConfiguration" hint="Edits the password."/>
|
<accessibility key="accessibilityConfiguration" hint="Edits the password."/>
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstAttribute="width" constant="44" id="j1z-K8-OXJ"/>
|
<constraint firstAttribute="width" constant="44" id="j1z-K8-OXJ"/>
|
||||||
@@ -1401,7 +1424,7 @@
|
|||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
<button opaque="NO" alpha="0.5" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" showsTouchWhenHighlighted="YES" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="I0v-ou-hDb" userLabel="Delete">
|
<button opaque="NO" alpha="0.5" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" showsTouchWhenHighlighted="YES" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="I0v-ou-hDb" userLabel="Delete">
|
||||||
<rect key="frame" x="223" y="56" width="44" height="44"/>
|
<rect key="frame" x="227" y="0.0" width="44" height="44"/>
|
||||||
<accessibility key="accessibilityConfiguration" hint="Edits the password."/>
|
<accessibility key="accessibilityConfiguration" hint="Edits the password."/>
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstAttribute="height" constant="44" id="XvV-Lr-Z21"/>
|
<constraint firstAttribute="height" constant="44" id="XvV-Lr-Z21"/>
|
||||||
@@ -1421,7 +1444,7 @@
|
|||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
<button opaque="NO" alpha="0.5" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" showsTouchWhenHighlighted="YES" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="K8q-bM-tzh" userLabel="Type">
|
<button opaque="NO" alpha="0.5" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" showsTouchWhenHighlighted="YES" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="K8q-bM-tzh" userLabel="Type">
|
||||||
<rect key="frame" x="267" y="56" width="44" height="44"/>
|
<rect key="frame" x="271" y="0.0" width="44" height="44"/>
|
||||||
<accessibility key="accessibilityConfiguration" hint="Edits the password."/>
|
<accessibility key="accessibilityConfiguration" hint="Edits the password."/>
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstAttribute="height" constant="44" id="K3c-Ok-krB"/>
|
<constraint firstAttribute="height" constant="44" id="K3c-Ok-krB"/>
|
||||||
@@ -1441,17 +1464,12 @@
|
|||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
</subviews>
|
</subviews>
|
||||||
|
</stackView>
|
||||||
|
</subviews>
|
||||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstItem="PKP-M9-T8E" firstAttribute="leading" secondItem="IKd-Ot-0n4" secondAttribute="trailing" priority="750" id="3sN-hc-iUd"/>
|
<constraint firstAttribute="trailing" secondItem="kfn-Wq-g5M" secondAttribute="trailing" constant="44" id="lGN-Bt-mrg"/>
|
||||||
<constraint firstItem="PKP-M9-T8E" firstAttribute="leading" secondItem="vGk-t6-hZn" secondAttribute="trailing" id="47y-gh-Ibs"/>
|
<constraint firstAttribute="bottom" secondItem="kfn-Wq-g5M" secondAttribute="bottom" id="lcH-Rb-skY"/>
|
||||||
<constraint firstItem="PKP-M9-T8E" firstAttribute="centerY" secondItem="uZi-FT-Fe8" secondAttribute="centerY" id="KEK-0r-cob"/>
|
|
||||||
<constraint firstItem="qBo-Kw-vN9" firstAttribute="leading" secondItem="uZi-FT-Fe8" secondAttribute="trailing" id="LLk-5B-1g9"/>
|
|
||||||
<constraint firstItem="vGk-t6-hZn" firstAttribute="leading" secondItem="IKd-Ot-0n4" secondAttribute="trailing" id="e2D-Rg-OQz"/>
|
|
||||||
<constraint firstItem="K8q-bM-tzh" firstAttribute="leading" secondItem="I0v-ou-hDb" secondAttribute="trailing" id="il2-7H-Hgk"/>
|
|
||||||
<constraint firstItem="I0v-ou-hDb" firstAttribute="leading" secondItem="qBo-Kw-vN9" secondAttribute="trailing" id="myx-31-6tz"/>
|
|
||||||
<constraint firstAttribute="trailing" secondItem="K8q-bM-tzh" secondAttribute="trailing" constant="44" id="qQK-ts-seh"/>
|
|
||||||
<constraint firstItem="uZi-FT-Fe8" firstAttribute="leading" secondItem="PKP-M9-T8E" secondAttribute="trailing" id="xFJ-GZ-jp9"/>
|
|
||||||
</constraints>
|
</constraints>
|
||||||
<userDefinedRuntimeAttributes>
|
<userDefinedRuntimeAttributes>
|
||||||
<userDefinedRuntimeAttribute type="boolean" keyPath="ignoreTouches" value="YES"/>
|
<userDefinedRuntimeAttribute type="boolean" keyPath="ignoreTouches" value="YES"/>
|
||||||
@@ -1479,7 +1497,7 @@
|
|||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="⬇︎" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="tuh-Au-J9k">
|
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="⬇︎" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="tuh-Au-J9k">
|
||||||
<rect key="frame" x="325" y="36" width="17" height="20"/>
|
<rect key="frame" x="325" y="35.5" width="17" height="20.5"/>
|
||||||
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="17"/>
|
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="17"/>
|
||||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
@@ -1488,20 +1506,14 @@
|
|||||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstAttribute="bottom" secondItem="tl3-hd-x35" secondAttribute="bottom" id="2x2-iA-utK"/>
|
<constraint firstAttribute="bottom" secondItem="tl3-hd-x35" secondAttribute="bottom" id="2x2-iA-utK"/>
|
||||||
<constraint firstItem="b5f-wN-2xb" firstAttribute="centerY" secondItem="I0v-ou-hDb" secondAttribute="centerY" id="KPv-e0-uR0"/>
|
|
||||||
<constraint firstItem="LvK-28-fbm" firstAttribute="leading" secondItem="tl3-hd-x35" secondAttribute="trailing" id="NXL-Fd-whf"/>
|
<constraint firstItem="LvK-28-fbm" firstAttribute="leading" secondItem="tl3-hd-x35" secondAttribute="trailing" id="NXL-Fd-whf"/>
|
||||||
<constraint firstItem="b5f-wN-2xb" firstAttribute="top" secondItem="tuh-Au-J9k" secondAttribute="bottom" id="SBC-kJ-Gku"/>
|
<constraint firstItem="b5f-wN-2xb" firstAttribute="top" secondItem="tuh-Au-J9k" secondAttribute="bottom" id="SBC-kJ-Gku"/>
|
||||||
<constraint firstAttribute="bottom" secondItem="LvK-28-fbm" secondAttribute="bottom" id="ZBx-Lf-XHF"/>
|
<constraint firstAttribute="bottom" secondItem="LvK-28-fbm" secondAttribute="bottom" id="ZBx-Lf-XHF"/>
|
||||||
<constraint firstItem="b5f-wN-2xb" firstAttribute="centerY" secondItem="vGk-t6-hZn" secondAttribute="centerY" id="fGB-8g-u5b"/>
|
|
||||||
<constraint firstItem="tl3-hd-x35" firstAttribute="leading" secondItem="bff-RU-OcY" secondAttribute="leading" id="fx5-KQ-LSM"/>
|
<constraint firstItem="tl3-hd-x35" firstAttribute="leading" secondItem="bff-RU-OcY" secondAttribute="leading" id="fx5-KQ-LSM"/>
|
||||||
<constraint firstItem="tl3-hd-x35" firstAttribute="top" secondItem="bff-RU-OcY" secondAttribute="top" id="jc9-39-FY3"/>
|
<constraint firstItem="tl3-hd-x35" firstAttribute="top" secondItem="bff-RU-OcY" secondAttribute="top" id="jc9-39-FY3"/>
|
||||||
<constraint firstItem="b5f-wN-2xb" firstAttribute="centerY" secondItem="IKd-Ot-0n4" secondAttribute="centerY" id="mCJ-ug-mmv"/>
|
|
||||||
<constraint firstItem="K8q-bM-tzh" firstAttribute="centerY" secondItem="b5f-wN-2xb" secondAttribute="centerY" id="ofO-r3-bjz"/>
|
|
||||||
<constraint firstItem="b5f-wN-2xb" firstAttribute="centerX" secondItem="tuh-Au-J9k" secondAttribute="centerX" id="pYG-bz-kd8"/>
|
<constraint firstItem="b5f-wN-2xb" firstAttribute="centerX" secondItem="tuh-Au-J9k" secondAttribute="centerX" id="pYG-bz-kd8"/>
|
||||||
<constraint firstAttribute="trailing" secondItem="LvK-28-fbm" secondAttribute="trailing" id="r9d-ym-Frs"/>
|
<constraint firstAttribute="trailing" secondItem="LvK-28-fbm" secondAttribute="trailing" id="r9d-ym-Frs"/>
|
||||||
<constraint firstItem="LvK-28-fbm" firstAttribute="top" secondItem="bff-RU-OcY" secondAttribute="top" id="uqb-hB-Iq8"/>
|
<constraint firstItem="LvK-28-fbm" firstAttribute="top" secondItem="bff-RU-OcY" secondAttribute="top" id="uqb-hB-Iq8"/>
|
||||||
<constraint firstItem="b5f-wN-2xb" firstAttribute="centerY" secondItem="uZi-FT-Fe8" secondAttribute="centerY" id="xz2-kK-B4g"/>
|
|
||||||
<constraint firstItem="b5f-wN-2xb" firstAttribute="centerY" secondItem="qBo-Kw-vN9" secondAttribute="centerY" id="zaR-iF-Hea"/>
|
|
||||||
</constraints>
|
</constraints>
|
||||||
<connections>
|
<connections>
|
||||||
<outlet property="delegate" destination="W2g-yv-V3V" id="HgX-fq-za5"/>
|
<outlet property="delegate" destination="W2g-yv-V3V" id="HgX-fq-za5"/>
|
||||||
@@ -1576,6 +1588,7 @@
|
|||||||
<constraint firstItem="aXw-tn-8Sj" firstAttribute="top" secondItem="K2e-Gh-7hH" secondAttribute="top" id="0SC-ZK-6ib"/>
|
<constraint firstItem="aXw-tn-8Sj" firstAttribute="top" secondItem="K2e-Gh-7hH" secondAttribute="top" id="0SC-ZK-6ib"/>
|
||||||
<constraint firstAttribute="bottom" secondItem="aXw-tn-8Sj" secondAttribute="bottom" id="4bI-12-Qmv"/>
|
<constraint firstAttribute="bottom" secondItem="aXw-tn-8Sj" secondAttribute="bottom" id="4bI-12-Qmv"/>
|
||||||
<constraint firstItem="aXw-tn-8Sj" firstAttribute="leading" secondItem="K2e-Gh-7hH" secondAttribute="leading" id="Tjh-fE-esc"/>
|
<constraint firstItem="aXw-tn-8Sj" firstAttribute="leading" secondItem="K2e-Gh-7hH" secondAttribute="leading" id="Tjh-fE-esc"/>
|
||||||
|
<constraint firstItem="aXw-tn-8Sj" firstAttribute="top" secondItem="K2e-Gh-7hH" secondAttribute="top" id="XfY-8C-DuI"/>
|
||||||
<constraint firstAttribute="trailing" secondItem="aXw-tn-8Sj" secondAttribute="trailing" id="Z9z-S5-CEh"/>
|
<constraint firstAttribute="trailing" secondItem="aXw-tn-8Sj" secondAttribute="trailing" id="Z9z-S5-CEh"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
</view>
|
</view>
|
||||||
@@ -1611,7 +1624,7 @@
|
|||||||
<outlet property="delegate" destination="nkY-z6-8jd" id="ENG-q5-XwX"/>
|
<outlet property="delegate" destination="nkY-z6-8jd" id="ENG-q5-XwX"/>
|
||||||
</connections>
|
</connections>
|
||||||
</searchBar>
|
</searchBar>
|
||||||
<view userInteractionEnabled="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="LEX-BK-PdS" userLabel="Bad Name Tip">
|
<view hidden="YES" userInteractionEnabled="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="LEX-BK-PdS" userLabel="Bad Name Tip">
|
||||||
<rect key="frame" x="37.5" y="86" width="300.5" height="75.5"/>
|
<rect key="frame" x="37.5" y="86" width="300.5" height="75.5"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" image="tip_basic_black_top.png" translatesAutoresizingMaskIntoConstraints="NO" id="Rt5-v4-I0R">
|
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" image="tip_basic_black_top.png" translatesAutoresizingMaskIntoConstraints="NO" id="Rt5-v4-I0R">
|
||||||
@@ -2550,36 +2563,34 @@ See </string>
|
|||||||
<scene sceneID="j3J-72-mva">
|
<scene sceneID="j3J-72-mva">
|
||||||
<objects>
|
<objects>
|
||||||
<tableViewController automaticallyAdjustsScrollViewInsets="NO" id="pdl-xv-zjX" customClass="MPStoreViewController" sceneMemberID="viewController">
|
<tableViewController automaticallyAdjustsScrollViewInsets="NO" id="pdl-xv-zjX" customClass="MPStoreViewController" sceneMemberID="viewController">
|
||||||
<tableView key="view" opaque="NO" clipsSubviews="YES" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="static" style="plain" separatorStyle="default" rowHeight="400" sectionHeaderHeight="22" sectionFooterHeight="22" id="Yd8-L6-OMk">
|
<tableView key="view" opaque="NO" clipsSubviews="YES" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="380" sectionHeaderHeight="22" sectionFooterHeight="22" id="Yd8-L6-OMk">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<color key="backgroundColor" red="0.12549020350000001" green="0.1411764771" blue="0.14901961389999999" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="backgroundColor" red="0.12549020350000001" green="0.1411764771" blue="0.14901961389999999" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<inset key="scrollIndicatorInsets" minX="0.0" minY="64" maxX="0.0" maxY="49"/>
|
<inset key="scrollIndicatorInsets" minX="0.0" minY="64" maxX="0.0" maxY="49"/>
|
||||||
<color key="separatorColor" red="0.37254901959999998" green="0.3921568627" blue="0.42745098040000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="separatorColor" red="0.37254901959999998" green="0.3921568627" blue="0.42745098040000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<sections>
|
<prototypes>
|
||||||
<tableViewSection id="efu-Mw-9J5">
|
<tableViewCell contentMode="scaleToFill" selectionStyle="default" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" shouldIndentWhileEditing="NO" reuseIdentifier="MPStoreProductCell" id="JVW-tG-xxe" userLabel="Product" customClass="MPStoreProductCell">
|
||||||
<cells>
|
<rect key="frame" x="0.0" y="22" width="375" height="380"/>
|
||||||
<tableViewCell contentMode="scaleToFill" selectionStyle="default" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" shouldIndentWhileEditing="NO" reuseIdentifier="MPStoreProductCellGenerateLogin" id="JVW-tG-xxe" userLabel="Generate Login" customClass="MPStoreProductCell">
|
|
||||||
<rect key="frame" x="0.0" y="0.0" width="375" height="400"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="JVW-tG-xxe" id="CLQ-CW-NGn">
|
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="JVW-tG-xxe" id="CLQ-CW-NGn">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="375" height="399.5"/>
|
<rect key="frame" x="0.0" y="0.0" width="375" height="379.5"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="751" verticalCompressionResistancePriority="751" text="Generate Login Names" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="12" adjustsLetterSpacingToFitWidth="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Pax-1J-IZi">
|
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="751" verticalCompressionResistancePriority="751" text="Negare non possum" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="12" adjustsLetterSpacingToFitWidth="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Pax-1J-IZi">
|
||||||
<rect key="frame" x="20" y="226" width="291" height="20"/>
|
<rect key="frame" x="20" y="226" width="291" height="21"/>
|
||||||
<fontDescription key="fontDescription" name="Exo2.0-Bold" family="Exo 2.0" pointSize="17"/>
|
<fontDescription key="fontDescription" name="Exo2.0-Bold" family="Exo 2.0" pointSize="17"/>
|
||||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" alpha="0.69999999999999996" contentMode="left" horizontalHuggingPriority="251" verticalCompressionResistancePriority="749" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Ra0-yS-99P">
|
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" alpha="0.69999999999999996" contentMode="left" horizontalHuggingPriority="251" verticalCompressionResistancePriority="749" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Ra0-yS-99P">
|
||||||
<rect key="frame" x="20" y="254" width="335" height="125"/>
|
<rect key="frame" x="20" y="255" width="335" height="104.5"/>
|
||||||
<string key="text">Master Password is great for making your passwords immune to loss, and it even lets you save your login name. But saved login names can't be recovered when all is lost. Generated login names use the same algorithm to generate a good login name to use for each of your sites. In addition, using unique non-identifying login names for your sites helps protect against companies working together to build a bigger picture on your identity.</string>
|
<string key="text">Lorem ipsum dolor sit amet, consectetur adipiscing elit. At multis se probavit. Sic consequentibus vestris sublatis prima tolluntur. Nescio quo modo praetervolavit oratio. Reguli reiciendam; Theophrastus mediocriterne delectat, cum tractat locos ab Aristotele ante tractatos? Duo Reges: constructio interrete.</string>
|
||||||
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="12"/>
|
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="12"/>
|
||||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="thumb_generated_login.png" translatesAutoresizingMaskIntoConstraints="NO" id="DMJ-sd-eNJ">
|
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="thumb_generated_answers.png" translatesAutoresizingMaskIntoConstraints="NO" id="DMJ-sd-eNJ">
|
||||||
<rect key="frame" x="88.5" y="20" width="198" height="198"/>
|
<rect key="frame" x="88.5" y="20" width="198" height="198"/>
|
||||||
</imageView>
|
</imageView>
|
||||||
<activityIndicatorView hidden="YES" opaque="NO" tag="2" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" hidesWhenStopped="YES" style="whiteLarge" translatesAutoresizingMaskIntoConstraints="NO" id="cef-sc-aph">
|
<activityIndicatorView hidden="YES" opaque="NO" tag="2" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" hidesWhenStopped="YES" style="whiteLarge" translatesAutoresizingMaskIntoConstraints="NO" id="cef-sc-aph">
|
||||||
@@ -2588,13 +2599,13 @@ See </string>
|
|||||||
<label opaque="NO" userInteractionEnabled="NO" tag="3" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="✔︎" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="FWu-V6-mLT">
|
<label opaque="NO" userInteractionEnabled="NO" tag="3" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="✔︎" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="FWu-V6-mLT">
|
||||||
<rect key="frame" x="200.5" y="-6" width="93" height="132"/>
|
<rect key="frame" x="200.5" y="-6" width="93" height="132"/>
|
||||||
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="110"/>
|
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="110"/>
|
||||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="textColor" red="0.47450980390000003" green="0.86666666670000003" blue="0.98431372549999996" alpha="1" colorSpace="calibratedRGB"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" tag="1" contentMode="left" horizontalHuggingPriority="750" verticalHuggingPriority="251" horizontalCompressionResistancePriority="751" verticalCompressionResistancePriority="751" text="$0.95" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="68f-wn-UlS">
|
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" tag="1" contentMode="left" horizontalHuggingPriority="750" verticalHuggingPriority="251" horizontalCompressionResistancePriority="751" verticalCompressionResistancePriority="751" text="$0.95" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="68f-wn-UlS">
|
||||||
<rect key="frame" x="319" y="226" width="36" height="20"/>
|
<rect key="frame" x="319" y="226" width="36" height="21"/>
|
||||||
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="14"/>
|
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="14"/>
|
||||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="textColor" red="0.47450980390000003" green="0.86666666670000003" blue="0.98431372549999996" alpha="1" colorSpace="calibratedRGB"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
</subviews>
|
</subviews>
|
||||||
@@ -2620,210 +2631,18 @@ See </string>
|
|||||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<connections>
|
<connections>
|
||||||
<outlet property="activityIndicator" destination="cef-sc-aph" id="VmL-AX-R3f"/>
|
<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="priceLabel" destination="68f-wn-UlS" id="e99-ys-HtZ"/>
|
||||||
<outlet property="purchasedIndicator" destination="FWu-V6-mLT" id="Zqt-GG-e5v"/>
|
<outlet property="purchasedIndicator" destination="FWu-V6-mLT" id="Zqt-GG-e5v"/>
|
||||||
|
<outlet property="thumbnailView" destination="DMJ-sd-eNJ" id="hCQ-2c-nti"/>
|
||||||
|
<outlet property="titleLabel" destination="Pax-1J-IZi" id="kVH-n6-mDs"/>
|
||||||
</connections>
|
</connections>
|
||||||
</tableViewCell>
|
</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">
|
<tableViewCell contentMode="scaleToFill" selectionStyle="default" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" shouldIndentWhileEditing="NO" reuseIdentifier="MPStoreFuelProductCell" id="le3-Q5-MSO" userLabel="Fuel" customClass="MPStoreFuelProductCell">
|
||||||
<rect key="frame" x="0.0" y="400" width="375" height="400"/>
|
<rect key="frame" x="0.0" y="402" width="375" height="380"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="l1g-Ul-Vg8" id="FWE-cE-L02">
|
|
||||||
<rect key="frame" x="0.0" y="0.0" width="375" height="399.5"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<subviews>
|
|
||||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="751" verticalCompressionResistancePriority="751" text="Generate Security Answers" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="12" adjustsLetterSpacingToFitWidth="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Kkl-gT-YAO">
|
|
||||||
<rect key="frame" x="20" y="226" width="291" height="20"/>
|
|
||||||
<fontDescription key="fontDescription" name="Exo2.0-Bold" family="Exo 2.0" pointSize="17"/>
|
|
||||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
|
||||||
<nil key="highlightedColor"/>
|
|
||||||
</label>
|
|
||||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" alpha="0.69999999999999996" contentMode="left" horizontalHuggingPriority="251" verticalCompressionResistancePriority="749" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="yRH-27-edZ">
|
|
||||||
<rect key="frame" x="20" y="254" width="335" height="125"/>
|
|
||||||
<string key="text">The infamous security questions are in fact a veritable assault on your security. For starters, they weaken the protection of your account by allowing an attacker in by simply knowing enough about you, allowing him to bypass guessing your strong password. Arguably worse is the amount of highly personal and private information you're "willingly" divulging to these websites, under the assumption that only you know the answers. Generating security answers allows you to stop sharing your highly personal details and weakening your acccounts by generating unguessable answers to these questions.</string>
|
|
||||||
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="12"/>
|
|
||||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
|
||||||
<nil key="highlightedColor"/>
|
|
||||||
</label>
|
|
||||||
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="thumb_generated_answers.png" translatesAutoresizingMaskIntoConstraints="NO" id="6km-y3-4gu">
|
|
||||||
<rect key="frame" x="88.5" y="20" width="198" height="198"/>
|
|
||||||
</imageView>
|
|
||||||
<activityIndicatorView hidden="YES" opaque="NO" tag="2" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" hidesWhenStopped="YES" style="whiteLarge" translatesAutoresizingMaskIntoConstraints="NO" id="X2g-Go-2Hz">
|
|
||||||
<rect key="frame" x="169.5" y="100" width="37" height="37"/>
|
|
||||||
</activityIndicatorView>
|
|
||||||
<label opaque="NO" userInteractionEnabled="NO" tag="2" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="✔︎" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="N9y-ue-L8d">
|
|
||||||
<rect key="frame" x="200.5" y="-6" width="93" height="132"/>
|
|
||||||
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="110"/>
|
|
||||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
|
||||||
<nil key="highlightedColor"/>
|
|
||||||
</label>
|
|
||||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" tag="1" contentMode="left" horizontalHuggingPriority="750" verticalHuggingPriority="251" horizontalCompressionResistancePriority="751" verticalCompressionResistancePriority="751" text="$0.95" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="9ct-IM-QKR">
|
|
||||||
<rect key="frame" x="319" y="226" width="36" height="20"/>
|
|
||||||
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="14"/>
|
|
||||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
|
||||||
<nil key="highlightedColor"/>
|
|
||||||
</label>
|
|
||||||
</subviews>
|
|
||||||
<constraints>
|
|
||||||
<constraint firstItem="6km-y3-4gu" firstAttribute="centerY" secondItem="X2g-Go-2Hz" secondAttribute="centerY" id="8cn-tp-Vfc"/>
|
|
||||||
<constraint firstItem="yRH-27-edZ" firstAttribute="leading" secondItem="FWE-cE-L02" secondAttribute="leading" constant="20" symbolic="YES" id="DSv-a4-VPg"/>
|
|
||||||
<constraint firstItem="9ct-IM-QKR" firstAttribute="leading" secondItem="Kkl-gT-YAO" secondAttribute="trailing" constant="8" symbolic="YES" id="Fov-kQ-Wkn"/>
|
|
||||||
<constraint firstItem="6km-y3-4gu" firstAttribute="top" secondItem="FWE-cE-L02" secondAttribute="top" constant="20" symbolic="YES" id="Kdx-UC-Q2x"/>
|
|
||||||
<constraint firstItem="Kkl-gT-YAO" firstAttribute="leading" secondItem="FWE-cE-L02" secondAttribute="leading" constant="20" symbolic="YES" id="Nsd-7W-1Tq"/>
|
|
||||||
<constraint firstItem="Kkl-gT-YAO" firstAttribute="bottom" secondItem="9ct-IM-QKR" secondAttribute="bottom" id="Oo3-Q5-Dzd"/>
|
|
||||||
<constraint firstItem="N9y-ue-L8d" firstAttribute="centerX" secondItem="6km-y3-4gu" secondAttribute="trailing" constant="-40" id="PNi-RN-ybE"/>
|
|
||||||
<constraint firstItem="Kkl-gT-YAO" firstAttribute="top" secondItem="6km-y3-4gu" secondAttribute="bottom" constant="8" symbolic="YES" id="UPs-VG-2ND"/>
|
|
||||||
<constraint firstItem="6km-y3-4gu" firstAttribute="centerX" secondItem="X2g-Go-2Hz" secondAttribute="centerX" id="Zpt-vq-iVk"/>
|
|
||||||
<constraint firstItem="yRH-27-edZ" firstAttribute="top" secondItem="Kkl-gT-YAO" secondAttribute="bottom" constant="8" symbolic="YES" id="eHf-L3-Ong"/>
|
|
||||||
<constraint firstAttribute="trailing" secondItem="yRH-27-edZ" secondAttribute="trailing" constant="20" id="eUN-6Y-FEC"/>
|
|
||||||
<constraint firstAttribute="centerX" secondItem="6km-y3-4gu" secondAttribute="centerX" id="gv6-jC-Gaa"/>
|
|
||||||
<constraint firstAttribute="trailing" secondItem="9ct-IM-QKR" secondAttribute="trailing" constant="20" id="iAM-za-9Ev"/>
|
|
||||||
<constraint firstAttribute="bottom" secondItem="yRH-27-edZ" secondAttribute="bottom" constant="20" symbolic="YES" id="krK-MM-VKm"/>
|
|
||||||
<constraint firstItem="Kkl-gT-YAO" firstAttribute="top" secondItem="9ct-IM-QKR" secondAttribute="top" id="lie-rM-flE"/>
|
|
||||||
<constraint firstItem="6km-y3-4gu" firstAttribute="top" secondItem="N9y-ue-L8d" secondAttribute="centerY" constant="-40" id="z16-aI-lwY"/>
|
|
||||||
</constraints>
|
|
||||||
</tableViewCellContentView>
|
|
||||||
<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="priceLabel" destination="9ct-IM-QKR" id="UTQ-L7-vbu"/>
|
|
||||||
<outlet property="purchasedIndicator" destination="N9y-ue-L8d" id="Ppv-ay-M1J"/>
|
|
||||||
</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">
|
|
||||||
<rect key="frame" x="0.0" y="800" width="375" height="400"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="9Na-CL-jBq" id="ETY-Ou-DW7">
|
|
||||||
<rect key="frame" x="0.0" y="0.0" width="375" height="399.5"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<subviews>
|
|
||||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="751" verticalCompressionResistancePriority="751" text="iOS Integration" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="12" adjustsLetterSpacingToFitWidth="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Zch-DS-J3I">
|
|
||||||
<rect key="frame" x="20" y="226" width="244" height="20"/>
|
|
||||||
<fontDescription key="fontDescription" name="Exo2.0-Bold" family="Exo 2.0" pointSize="17"/>
|
|
||||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
|
||||||
<nil key="highlightedColor"/>
|
|
||||||
</label>
|
|
||||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" alpha="0.69999999999999996" contentMode="left" horizontalHuggingPriority="251" verticalCompressionResistancePriority="749" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="riF-bB-x5g">
|
|
||||||
<rect key="frame" x="20" y="254" width="335" height="125"/>
|
|
||||||
<string key="text">Up to now, the best way to use your passwords in other iOS apps was by copy/pasting them from Master Password. With iOS integration, you can access your Master Password passwords directly from other applications, without having to switch back and forth between it and Master Password.</string>
|
|
||||||
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="12"/>
|
|
||||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
|
||||||
<nil key="highlightedColor"/>
|
|
||||||
</label>
|
|
||||||
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="thumb_ios_integration.png" translatesAutoresizingMaskIntoConstraints="NO" id="yAc-Sm-IVo">
|
|
||||||
<rect key="frame" x="88.5" y="20" width="198" height="198"/>
|
|
||||||
</imageView>
|
|
||||||
<activityIndicatorView hidden="YES" opaque="NO" tag="2" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" hidesWhenStopped="YES" style="whiteLarge" translatesAutoresizingMaskIntoConstraints="NO" id="yUe-TX-fli">
|
|
||||||
<rect key="frame" x="169.5" y="100" width="37" height="37"/>
|
|
||||||
</activityIndicatorView>
|
|
||||||
<label opaque="NO" userInteractionEnabled="NO" tag="2" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="✔︎" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ec8-P9-KPY">
|
|
||||||
<rect key="frame" x="200.5" y="-6" width="93" height="132"/>
|
|
||||||
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="110"/>
|
|
||||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
|
||||||
<nil key="highlightedColor"/>
|
|
||||||
</label>
|
|
||||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" tag="1" contentMode="left" horizontalHuggingPriority="750" verticalHuggingPriority="251" horizontalCompressionResistancePriority="751" verticalCompressionResistancePriority="751" text="Coming Soon" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="3jH-eX-9N2">
|
|
||||||
<rect key="frame" x="272" y="226" width="83" height="20"/>
|
|
||||||
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="14"/>
|
|
||||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
|
||||||
<nil key="highlightedColor"/>
|
|
||||||
</label>
|
|
||||||
</subviews>
|
|
||||||
<constraints>
|
|
||||||
<constraint firstItem="Zch-DS-J3I" firstAttribute="top" secondItem="yAc-Sm-IVo" secondAttribute="bottom" constant="8" symbolic="YES" id="0M4-0I-kCB"/>
|
|
||||||
<constraint firstItem="ec8-P9-KPY" firstAttribute="centerX" secondItem="yAc-Sm-IVo" secondAttribute="trailing" constant="-40" id="31k-Co-bGU"/>
|
|
||||||
<constraint firstItem="yAc-Sm-IVo" firstAttribute="top" secondItem="ETY-Ou-DW7" secondAttribute="top" constant="20" symbolic="YES" id="PnQ-1d-y9S"/>
|
|
||||||
<constraint firstItem="Zch-DS-J3I" firstAttribute="bottom" secondItem="3jH-eX-9N2" secondAttribute="bottom" id="XMk-An-t5v"/>
|
|
||||||
<constraint firstItem="riF-bB-x5g" firstAttribute="top" secondItem="Zch-DS-J3I" secondAttribute="bottom" constant="8" symbolic="YES" id="ZMH-Sv-ttk"/>
|
|
||||||
<constraint firstAttribute="trailing" secondItem="3jH-eX-9N2" secondAttribute="trailing" constant="20" id="diQ-Rs-Vrj"/>
|
|
||||||
<constraint firstAttribute="centerX" secondItem="yAc-Sm-IVo" secondAttribute="centerX" id="fsX-dO-EGx"/>
|
|
||||||
<constraint firstItem="Zch-DS-J3I" firstAttribute="top" secondItem="3jH-eX-9N2" secondAttribute="top" id="gZU-lV-XZJ"/>
|
|
||||||
<constraint firstAttribute="bottom" secondItem="riF-bB-x5g" secondAttribute="bottom" constant="20" symbolic="YES" id="hQZ-Qb-A7u"/>
|
|
||||||
<constraint firstAttribute="trailing" secondItem="riF-bB-x5g" secondAttribute="trailing" constant="20" id="iCn-kq-xNy"/>
|
|
||||||
<constraint firstItem="yAc-Sm-IVo" firstAttribute="centerX" secondItem="yUe-TX-fli" secondAttribute="centerX" id="kUQ-lP-EQP"/>
|
|
||||||
<constraint firstItem="3jH-eX-9N2" firstAttribute="leading" secondItem="Zch-DS-J3I" secondAttribute="trailing" constant="8" symbolic="YES" id="qqB-1E-QPE"/>
|
|
||||||
<constraint firstItem="yAc-Sm-IVo" firstAttribute="top" secondItem="ec8-P9-KPY" secondAttribute="centerY" constant="-40" id="swf-Ua-uwD"/>
|
|
||||||
<constraint firstItem="yAc-Sm-IVo" firstAttribute="centerY" secondItem="yUe-TX-fli" secondAttribute="centerY" id="tha-UC-Hwi"/>
|
|
||||||
<constraint firstItem="Zch-DS-J3I" firstAttribute="leading" secondItem="ETY-Ou-DW7" secondAttribute="leading" constant="20" symbolic="YES" id="uV9-xY-ayE"/>
|
|
||||||
<constraint firstItem="riF-bB-x5g" firstAttribute="leading" secondItem="ETY-Ou-DW7" secondAttribute="leading" constant="20" symbolic="YES" id="y9l-fO-HMK"/>
|
|
||||||
</constraints>
|
|
||||||
</tableViewCellContentView>
|
|
||||||
<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="priceLabel" destination="3jH-eX-9N2" id="agT-az-dVU"/>
|
|
||||||
<outlet property="purchasedIndicator" destination="ec8-P9-KPY" id="M39-bc-Ksp"/>
|
|
||||||
</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">
|
|
||||||
<rect key="frame" x="0.0" y="1200" width="375" height="400"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="8en-6R-GvR" id="NKB-rd-1Vy">
|
|
||||||
<rect key="frame" x="0.0" y="0.0" width="375" height="399.5"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<subviews>
|
|
||||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="751" verticalCompressionResistancePriority="751" text="TouchID Login" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="12" adjustsLetterSpacingToFitWidth="YES" translatesAutoresizingMaskIntoConstraints="NO" id="e1D-jp-GBs">
|
|
||||||
<rect key="frame" x="20" y="226" width="291.5" height="20"/>
|
|
||||||
<fontDescription key="fontDescription" name="Exo2.0-Bold" family="Exo 2.0" pointSize="17"/>
|
|
||||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
|
||||||
<nil key="highlightedColor"/>
|
|
||||||
</label>
|
|
||||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" alpha="0.69999999999999996" contentMode="left" horizontalHuggingPriority="251" verticalCompressionResistancePriority="749" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Yxc-Lr-382">
|
|
||||||
<rect key="frame" x="20" y="254" width="335" height="125"/>
|
|
||||||
<string key="text">Since the iPhone 5s, all iPhones are now equipped with an advanced Touch ID fingerprint sensor in the home button. This sensor allows you to quickly and easily identify yourself to the system. With Touch ID support, you will be able to skip the step of entering your Master Password manually and gain the ability to unlock your user using Touch ID instead.</string>
|
|
||||||
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="12"/>
|
|
||||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
|
||||||
<nil key="highlightedColor"/>
|
|
||||||
</label>
|
|
||||||
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="thumb_touch_id.png" translatesAutoresizingMaskIntoConstraints="NO" id="8v7-JH-mzu">
|
|
||||||
<rect key="frame" x="88.5" y="20" width="198" height="198"/>
|
|
||||||
</imageView>
|
|
||||||
<activityIndicatorView hidden="YES" opaque="NO" tag="2" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" hidesWhenStopped="YES" style="whiteLarge" translatesAutoresizingMaskIntoConstraints="NO" id="Dv5-t7-lL1">
|
|
||||||
<rect key="frame" x="169.5" y="100" width="37" height="37"/>
|
|
||||||
</activityIndicatorView>
|
|
||||||
<label opaque="NO" userInteractionEnabled="NO" tag="2" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="✔︎" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="yZX-ns-8oV">
|
|
||||||
<rect key="frame" x="200.5" y="-6" width="93" height="132"/>
|
|
||||||
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="110"/>
|
|
||||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
|
||||||
<nil key="highlightedColor"/>
|
|
||||||
</label>
|
|
||||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" tag="1" contentMode="left" horizontalHuggingPriority="750" verticalHuggingPriority="251" horizontalCompressionResistancePriority="751" verticalCompressionResistancePriority="751" text="$0.95" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ZGg-O6-rsg">
|
|
||||||
<rect key="frame" x="319.5" y="226" width="35.5" height="20"/>
|
|
||||||
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="14"/>
|
|
||||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
|
||||||
<nil key="highlightedColor"/>
|
|
||||||
</label>
|
|
||||||
</subviews>
|
|
||||||
<constraints>
|
|
||||||
<constraint firstItem="Yxc-Lr-382" firstAttribute="top" secondItem="e1D-jp-GBs" secondAttribute="bottom" constant="8" symbolic="YES" id="BMp-dh-Elb"/>
|
|
||||||
<constraint firstItem="e1D-jp-GBs" firstAttribute="top" secondItem="8v7-JH-mzu" secondAttribute="bottom" constant="8" symbolic="YES" id="CCe-dk-eBT"/>
|
|
||||||
<constraint firstItem="Dv5-t7-lL1" firstAttribute="centerY" secondItem="8v7-JH-mzu" secondAttribute="centerY" id="DUJ-Xb-503"/>
|
|
||||||
<constraint firstItem="e1D-jp-GBs" firstAttribute="bottom" secondItem="ZGg-O6-rsg" secondAttribute="bottom" id="MPG-Zj-vDr"/>
|
|
||||||
<constraint firstItem="e1D-jp-GBs" firstAttribute="leading" secondItem="NKB-rd-1Vy" secondAttribute="leading" constant="20" symbolic="YES" id="N8Z-X2-ir7"/>
|
|
||||||
<constraint firstItem="8v7-JH-mzu" firstAttribute="top" secondItem="NKB-rd-1Vy" secondAttribute="top" constant="20" symbolic="YES" id="PEc-aa-i3N"/>
|
|
||||||
<constraint firstAttribute="trailing" secondItem="ZGg-O6-rsg" secondAttribute="trailing" constant="20" id="QAy-Rp-XJc"/>
|
|
||||||
<constraint firstItem="Yxc-Lr-382" firstAttribute="leading" secondItem="NKB-rd-1Vy" secondAttribute="leading" constant="20" symbolic="YES" id="UvU-wL-3WN"/>
|
|
||||||
<constraint firstAttribute="centerX" secondItem="8v7-JH-mzu" secondAttribute="centerX" id="XVh-6p-4qT"/>
|
|
||||||
<constraint firstAttribute="trailing" secondItem="Yxc-Lr-382" secondAttribute="trailing" constant="20" id="YMA-ID-9KD"/>
|
|
||||||
<constraint firstItem="Dv5-t7-lL1" firstAttribute="centerX" secondItem="8v7-JH-mzu" secondAttribute="centerX" id="bWe-Wx-6CH"/>
|
|
||||||
<constraint firstItem="8v7-JH-mzu" firstAttribute="top" secondItem="yZX-ns-8oV" secondAttribute="centerY" constant="-40" id="n0h-tr-yA0"/>
|
|
||||||
<constraint firstItem="e1D-jp-GBs" firstAttribute="top" secondItem="ZGg-O6-rsg" secondAttribute="top" id="oZN-4h-Awv"/>
|
|
||||||
<constraint firstAttribute="bottom" secondItem="Yxc-Lr-382" secondAttribute="bottom" constant="20" symbolic="YES" id="pFY-vd-3UR"/>
|
|
||||||
<constraint firstItem="ZGg-O6-rsg" firstAttribute="leading" secondItem="e1D-jp-GBs" secondAttribute="trailing" constant="8" symbolic="YES" id="stO-51-Mlk"/>
|
|
||||||
<constraint firstItem="yZX-ns-8oV" firstAttribute="centerX" secondItem="8v7-JH-mzu" secondAttribute="trailing" constant="-40" id="yyS-FS-gvJ"/>
|
|
||||||
</constraints>
|
|
||||||
</tableViewCellContentView>
|
|
||||||
<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="priceLabel" destination="ZGg-O6-rsg" id="dAn-xu-gut"/>
|
|
||||||
<outlet property="purchasedIndicator" destination="yZX-ns-8oV" id="7x0-eq-oSs"/>
|
|
||||||
</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">
|
|
||||||
<rect key="frame" x="0.0" y="1600" width="375" height="400"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="le3-Q5-MSO" id="SzQ-Y5-XIF">
|
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="le3-Q5-MSO" id="SzQ-Y5-XIF">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="375" height="399.5"/>
|
<rect key="frame" x="0.0" y="0.0" width="375" height="379.5"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="751" verticalCompressionResistancePriority="751" text="Fuel Top-Up" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="12" adjustsLetterSpacingToFitWidth="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Jnv-uN-xeg">
|
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="751" verticalCompressionResistancePriority="751" text="Fuel Top-Up" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="12" adjustsLetterSpacingToFitWidth="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Jnv-uN-xeg">
|
||||||
@@ -2833,14 +2652,8 @@ See </string>
|
|||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" alpha="0.69999999999999996" contentMode="left" horizontalHuggingPriority="251" verticalCompressionResistancePriority="749" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="fz2-AO-aGW">
|
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" alpha="0.69999999999999996" contentMode="left" horizontalHuggingPriority="251" verticalCompressionResistancePriority="749" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="fz2-AO-aGW">
|
||||||
<rect key="frame" x="20" y="254" width="335" height="125"/>
|
<rect key="frame" x="20" y="254" width="335" height="105.5"/>
|
||||||
<string key="text">You really love Master Password and how it's solving your password problems. You're eager to encourage the maintenance, technical support and development of new features. I am a one-man shop, fuel enables me to allocate more work hours to Master Password.
|
<string key="text">You really love Master Password and how it's solving your password problems. You're eager to encourage the maintenance, technical support and development of new features. I am a one-man shop, fuel enables me to allocate more work hours to Master Password.</string>
|
||||||
|
|
||||||
UPCOMING:
|
|
||||||
– Safari integration
|
|
||||||
– Touch ID support
|
|
||||||
– Multi-platform support
|
|
||||||
– Your feedback</string>
|
|
||||||
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="12"/>
|
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="12"/>
|
||||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
@@ -2849,17 +2662,20 @@ UPCOMING:
|
|||||||
<rect key="frame" x="88.5" y="20" width="198" height="198"/>
|
<rect key="frame" x="88.5" y="20" width="198" height="198"/>
|
||||||
</imageView>
|
</imageView>
|
||||||
<activityIndicatorView hidden="YES" opaque="NO" tag="2" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" hidesWhenStopped="YES" style="whiteLarge" translatesAutoresizingMaskIntoConstraints="NO" id="eS4-59-Xny">
|
<activityIndicatorView hidden="YES" opaque="NO" tag="2" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" hidesWhenStopped="YES" style="whiteLarge" translatesAutoresizingMaskIntoConstraints="NO" id="eS4-59-Xny">
|
||||||
<rect key="frame" x="169.5" y="100" width="37" height="37"/>
|
<rect key="frame" x="169.5" y="101" width="37" height="37"/>
|
||||||
</activityIndicatorView>
|
</activityIndicatorView>
|
||||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" tag="1" contentMode="left" horizontalHuggingPriority="750" verticalHuggingPriority="251" horizontalCompressionResistancePriority="751" verticalCompressionResistancePriority="751" text="$2.95" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="EbU-DV-fKF">
|
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" tag="1" contentMode="left" horizontalHuggingPriority="750" verticalHuggingPriority="251" horizontalCompressionResistancePriority="751" verticalCompressionResistancePriority="751" text="$2.95" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="EbU-DV-fKF">
|
||||||
<rect key="frame" x="320" y="226" width="35" height="20"/>
|
<rect key="frame" x="320" y="226" width="35" height="20"/>
|
||||||
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="14"/>
|
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="14"/>
|
||||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="textColor" red="0.47450980390000003" green="0.86666666670000003" blue="0.98431372549999996" alpha="1" colorSpace="calibratedRGB"/>
|
||||||
|
<nil key="highlightedColor"/>
|
||||||
|
</label>
|
||||||
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="▲" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="aGb-QC-A92">
|
||||||
|
<rect key="frame" x="261.5" y="201" width="13" height="17"/>
|
||||||
|
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||||
|
<color key="textColor" red="0.47450980390000003" green="0.86666666670000003" blue="0.98431372549999996" alpha="1" colorSpace="calibratedRGB"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="meter_fuel.png" translatesAutoresizingMaskIntoConstraints="NO" id="aGb-QC-A92">
|
|
||||||
<rect key="frame" x="262.5" y="209" width="11" height="9"/>
|
|
||||||
</imageView>
|
|
||||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="dsR-fr-dY4">
|
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="dsR-fr-dY4">
|
||||||
<rect key="frame" x="20" y="20" width="111" height="44"/>
|
<rect key="frame" x="20" y="20" width="111" height="44"/>
|
||||||
<constraints>
|
<constraints>
|
||||||
@@ -2874,9 +2690,9 @@ UPCOMING:
|
|||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" alpha="0.69999999999999996" contentMode="left" horizontalHuggingPriority="251" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="kYb-j4-32C">
|
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" alpha="0.69999999999999996" contentMode="left" horizontalHuggingPriority="251" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="kYb-j4-32C">
|
||||||
<rect key="frame" x="20" y="64" width="131.5" height="29"/>
|
<rect key="frame" x="20" y="64" width="132" height="29"/>
|
||||||
<string key="text">fuel left: 0.3 work hours
|
<string key="text">Fuel left: 0.3 work hours
|
||||||
invested: 3.7 work hours</string>
|
Invested: 3.7 work hours</string>
|
||||||
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="12"/>
|
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="12"/>
|
||||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
@@ -2908,92 +2724,93 @@ 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"/>
|
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<connections>
|
<connections>
|
||||||
<outlet property="activityIndicator" destination="eS4-59-Xny" id="kGW-fn-VqH"/>
|
<outlet property="activityIndicator" destination="eS4-59-Xny" id="kGW-fn-VqH"/>
|
||||||
|
<outlet property="descriptionLabel" destination="fz2-AO-aGW" id="xkc-xV-Z6Y"/>
|
||||||
|
<outlet property="fuelMeterConstraint" destination="eMa-Gj-BUc" id="1uc-fa-b20"/>
|
||||||
|
<outlet property="fuelSpeedButton" destination="dsR-fr-dY4" id="7yS-9g-xkM"/>
|
||||||
|
<outlet property="fuelStatusLabel" destination="kYb-j4-32C" id="ctc-ES-lGR"/>
|
||||||
<outlet property="priceLabel" destination="EbU-DV-fKF" id="pg2-8o-7We"/>
|
<outlet property="priceLabel" destination="EbU-DV-fKF" id="pg2-8o-7We"/>
|
||||||
|
<outlet property="thumbnailView" destination="PnG-hP-syh" id="zHB-jE-rZ4"/>
|
||||||
|
<outlet property="titleLabel" destination="Jnv-uN-xeg" id="Kxi-RE-ipa"/>
|
||||||
</connections>
|
</connections>
|
||||||
</tableViewCell>
|
</tableViewCell>
|
||||||
</cells>
|
<tableViewCell contentMode="scaleToFill" selectionStyle="none" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" shouldIndentWhileEditing="NO" reuseIdentifier="MPStoreCellSpinner" rowHeight="170" id="LOh-72-Ifp" userLabel="Spinner">
|
||||||
</tableViewSection>
|
<rect key="frame" x="0.0" y="782" width="375" height="170"/>
|
||||||
<tableViewSection id="hN1-J4-w3w">
|
|
||||||
<cells>
|
|
||||||
<tableViewCell contentMode="scaleToFill" selectionStyle="none" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" shouldIndentWhileEditing="NO" reuseIdentifier="MPStoreCellSpinner" rowHeight="150" id="u3P-ng-YHc" userLabel="Spinner">
|
|
||||||
<rect key="frame" x="0.0" y="2000" width="375" height="150"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="u3P-ng-YHc" id="y85-0Q-tbK">
|
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="LOh-72-Ifp" id="gjr-8l-JJ0">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="375" height="149.5"/>
|
<rect key="frame" x="0.0" y="0.0" width="375" height="169.5"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<activityIndicatorView opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" hidesWhenStopped="YES" animating="YES" style="whiteLarge" translatesAutoresizingMaskIntoConstraints="NO" id="Vjt-7c-BJ4">
|
<activityIndicatorView opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" hidesWhenStopped="YES" animating="YES" style="whiteLarge" translatesAutoresizingMaskIntoConstraints="NO" id="MIJ-rP-BeU">
|
||||||
<rect key="frame" x="169" y="20" width="37" height="21"/>
|
<rect key="frame" x="169" y="20" width="37" height="37"/>
|
||||||
</activityIndicatorView>
|
</activityIndicatorView>
|
||||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="751" verticalCompressionResistancePriority="751" text="Loading products..." textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="12" adjustsLetterSpacingToFitWidth="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ARC-xH-0U0">
|
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="751" verticalCompressionResistancePriority="751" text="Loading products..." textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="12" adjustsLetterSpacingToFitWidth="YES" translatesAutoresizingMaskIntoConstraints="NO" id="NPg-it-juF">
|
||||||
<rect key="frame" x="115" y="81" width="145.5" height="20"/>
|
<rect key="frame" x="115" y="97" width="145.5" height="24.5"/>
|
||||||
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="17"/>
|
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="17"/>
|
||||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
</subviews>
|
</subviews>
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstAttribute="bottom" secondItem="ARC-xH-0U0" secondAttribute="bottom" constant="48" id="5L9-Ag-d1G"/>
|
<constraint firstAttribute="centerX" secondItem="MIJ-rP-BeU" secondAttribute="centerX" id="DXM-74-LKR"/>
|
||||||
<constraint firstAttribute="centerX" secondItem="ARC-xH-0U0" secondAttribute="centerX" id="asI-QK-u6O"/>
|
<constraint firstAttribute="bottom" secondItem="NPg-it-juF" secondAttribute="bottom" constant="48" id="aCB-sK-ZCP"/>
|
||||||
<constraint firstItem="ARC-xH-0U0" firstAttribute="top" secondItem="Vjt-7c-BJ4" secondAttribute="bottom" constant="40" id="g1T-rA-vOW"/>
|
<constraint firstAttribute="centerX" secondItem="NPg-it-juF" secondAttribute="centerX" id="fGb-Sq-nBz"/>
|
||||||
<constraint firstAttribute="centerX" secondItem="Vjt-7c-BJ4" secondAttribute="centerX" id="j2l-mA-Duf"/>
|
<constraint firstItem="MIJ-rP-BeU" firstAttribute="top" secondItem="gjr-8l-JJ0" secondAttribute="top" constant="20" id="nh6-ca-qKI"/>
|
||||||
<constraint firstItem="Vjt-7c-BJ4" firstAttribute="top" secondItem="y85-0Q-tbK" secondAttribute="top" constant="20" id="v16-PA-82f"/>
|
<constraint firstItem="NPg-it-juF" firstAttribute="top" secondItem="MIJ-rP-BeU" secondAttribute="bottom" constant="40" id="s5N-EF-Rd4"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
</tableViewCellContentView>
|
</tableViewCellContentView>
|
||||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
</tableViewCell>
|
</tableViewCell>
|
||||||
<tableViewCell contentMode="scaleToFill" selectionStyle="none" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" shouldIndentWhileEditing="NO" reuseIdentifier="MPStoreCellFooter" id="UUA-xl-CAh" userLabel="Footer">
|
<tableViewCell contentMode="scaleToFill" selectionStyle="none" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" shouldIndentWhileEditing="NO" reuseIdentifier="MPStoreCellFooter" rowHeight="100" id="jsY-TE-4y5" userLabel="Footer">
|
||||||
<rect key="frame" x="0.0" y="2150" width="375" height="400"/>
|
<rect key="frame" x="0.0" y="952" width="375" height="100"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="UUA-xl-CAh" id="4Zu-Ig-Ws4">
|
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="jsY-TE-4y5" id="guB-Eb-KpI">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="375" height="399.5"/>
|
<rect key="frame" x="0.0" y="0.0" width="375" height="99.5"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" alpha="0.69999999999999996" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="749" verticalCompressionResistancePriority="751" text="© 2012-2014, Maarten Billemont (lhunath)" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="DxV-2L-bxL">
|
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" alpha="0.69999998807907104" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="749" verticalCompressionResistancePriority="751" text="© 2012-2014, Maarten Billemont (lhunath)" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="26U-st-xNs">
|
||||||
<rect key="frame" x="20" y="4" width="335" height="305.5"/>
|
<rect key="frame" x="20" y="4" width="335" height="21.5"/>
|
||||||
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="11"/>
|
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="11"/>
|
||||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
<button opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="750" verticalCompressionResistancePriority="751" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="IOk-WZ-HJ8">
|
<button opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="750" verticalCompressionResistancePriority="751" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="lQ1-b9-Xp4">
|
||||||
<rect key="frame" x="20" y="317.5" width="335" height="27"/>
|
<rect key="frame" x="20" y="33.5" width="335" height="27"/>
|
||||||
<fontDescription key="fontDescription" name="Exo2.0-Bold" family="Exo 2.0" pointSize="12"/>
|
<fontDescription key="fontDescription" name="Exo2.0-Bold" family="Exo 2.0" pointSize="12"/>
|
||||||
<state key="normal" title="Restore Previous Purchases">
|
<state key="normal" title="Restore Previous Purchases">
|
||||||
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
</state>
|
</state>
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="restorePurchases:" destination="pdl-xv-zjX" eventType="touchUpInside" id="lKu-PL-PfX"/>
|
<action selector="restorePurchases:" destination="pdl-xv-zjX" eventType="touchUpInside" id="Q8M-ud-OHL"/>
|
||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
<button opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="750" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="bCe-a3-cDC">
|
<button opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="750" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="eus-kQ-emn">
|
||||||
<rect key="frame" x="8" y="352.5" width="359" height="27"/>
|
<rect key="frame" x="8" y="68.5" width="359" height="27"/>
|
||||||
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="12"/>
|
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="12"/>
|
||||||
<state key="normal" title="Send Thanks">
|
<state key="normal" title="Send Thanks">
|
||||||
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
</state>
|
</state>
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="sendThanks:" destination="pdl-xv-zjX" eventType="touchUpInside" id="r5l-3U-jCA"/>
|
<action selector="sendThanks:" destination="pdl-xv-zjX" eventType="touchUpInside" id="IrU-IR-em1"/>
|
||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
</subviews>
|
</subviews>
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstAttribute="bottom" secondItem="bCe-a3-cDC" secondAttribute="bottom" constant="20" symbolic="YES" id="84k-uv-gb7"/>
|
<constraint firstItem="lQ1-b9-Xp4" firstAttribute="leading" secondItem="guB-Eb-KpI" secondAttribute="leading" constant="20" symbolic="YES" id="A2j-I5-HlU"/>
|
||||||
<constraint firstAttribute="trailing" secondItem="IOk-WZ-HJ8" secondAttribute="trailing" constant="20" symbolic="YES" id="CuJ-h7-aGJ"/>
|
<constraint firstAttribute="bottom" secondItem="eus-kQ-emn" secondAttribute="bottom" constant="4" id="Cw6-qh-jbe"/>
|
||||||
<constraint firstAttribute="trailing" secondItem="bCe-a3-cDC" secondAttribute="trailing" constant="8" id="Lfp-Hx-vLN"/>
|
<constraint firstAttribute="trailing" secondItem="lQ1-b9-Xp4" secondAttribute="trailing" constant="20" symbolic="YES" id="I2K-u3-cOn"/>
|
||||||
<constraint firstAttribute="trailing" secondItem="DxV-2L-bxL" secondAttribute="trailing" constant="20" symbolic="YES" id="QHU-Jw-LPy"/>
|
<constraint firstItem="26U-st-xNs" firstAttribute="top" secondItem="guB-Eb-KpI" secondAttribute="top" constant="4" id="I2p-hX-EOW"/>
|
||||||
<constraint firstItem="bCe-a3-cDC" firstAttribute="top" secondItem="IOk-WZ-HJ8" secondAttribute="bottom" constant="8" symbolic="YES" id="XJh-dK-J4C"/>
|
<constraint firstItem="lQ1-b9-Xp4" firstAttribute="top" secondItem="26U-st-xNs" secondAttribute="bottom" constant="8" symbolic="YES" id="IXV-6Z-hyF"/>
|
||||||
<constraint firstItem="DxV-2L-bxL" firstAttribute="leading" secondItem="4Zu-Ig-Ws4" secondAttribute="leading" constant="20" symbolic="YES" id="fAD-At-gqS"/>
|
<constraint firstItem="eus-kQ-emn" firstAttribute="leading" secondItem="guB-Eb-KpI" secondAttribute="leading" constant="8" id="Kkk-AE-iWm"/>
|
||||||
<constraint firstItem="DxV-2L-bxL" firstAttribute="top" secondItem="4Zu-Ig-Ws4" secondAttribute="top" constant="4" id="hTN-Cx-hOS"/>
|
<constraint firstItem="eus-kQ-emn" firstAttribute="top" secondItem="lQ1-b9-Xp4" secondAttribute="bottom" constant="8" symbolic="YES" id="UMw-e1-O9o"/>
|
||||||
<constraint firstItem="bCe-a3-cDC" firstAttribute="leading" secondItem="4Zu-Ig-Ws4" secondAttribute="leading" constant="8" id="l4A-fH-9fA"/>
|
<constraint firstAttribute="trailing" secondItem="26U-st-xNs" secondAttribute="trailing" constant="20" symbolic="YES" id="eOG-B5-WwQ"/>
|
||||||
<constraint firstItem="IOk-WZ-HJ8" firstAttribute="top" secondItem="DxV-2L-bxL" secondAttribute="bottom" constant="8" symbolic="YES" id="lq6-sj-DVg"/>
|
<constraint firstAttribute="trailing" secondItem="eus-kQ-emn" secondAttribute="trailing" constant="8" id="hYo-sy-8wY"/>
|
||||||
<constraint firstItem="IOk-WZ-HJ8" firstAttribute="leading" secondItem="4Zu-Ig-Ws4" secondAttribute="leading" constant="20" symbolic="YES" id="mx2-Jk-5jo"/>
|
<constraint firstItem="26U-st-xNs" firstAttribute="leading" secondItem="guB-Eb-KpI" secondAttribute="leading" constant="20" symbolic="YES" id="xfW-Sz-Kuz"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
</tableViewCellContentView>
|
</tableViewCellContentView>
|
||||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
</tableViewCell>
|
</tableViewCell>
|
||||||
</cells>
|
</prototypes>
|
||||||
</tableViewSection>
|
<sections/>
|
||||||
</sections>
|
|
||||||
<connections>
|
<connections>
|
||||||
<outlet property="dataSource" destination="pdl-xv-zjX" id="ZOr-qJ-zl2"/>
|
<outlet property="dataSource" destination="pdl-xv-zjX" id="ZOr-qJ-zl2"/>
|
||||||
<outlet property="delegate" destination="pdl-xv-zjX" id="xkn-ZJ-BPX"/>
|
<outlet property="delegate" destination="pdl-xv-zjX" id="xkn-ZJ-BPX"/>
|
||||||
@@ -3002,17 +2819,6 @@ invested: 3.7 work hours</string>
|
|||||||
<tabBarItem key="tabBarItem" title="Store" image="icon_star-hollow.png" id="j4c-Kp-fnH"/>
|
<tabBarItem key="tabBarItem" title="Store" image="icon_star-hollow.png" id="j4c-Kp-fnH"/>
|
||||||
<nil key="simulatedStatusBarMetrics"/>
|
<nil key="simulatedStatusBarMetrics"/>
|
||||||
<nil key="simulatedBottomBarMetrics"/>
|
<nil key="simulatedBottomBarMetrics"/>
|
||||||
<connections>
|
|
||||||
<outlet property="fuelCell" destination="le3-Q5-MSO" id="oAk-6g-cFj"/>
|
|
||||||
<outlet property="fuelMeterConstraint" destination="eMa-Gj-BUc" id="9iF-EO-UU6"/>
|
|
||||||
<outlet property="fuelSpeedButton" destination="dsR-fr-dY4" id="XGI-PE-9mh"/>
|
|
||||||
<outlet property="fuelStatusLabel" destination="kYb-j4-32C" id="o5R-0u-kGL"/>
|
|
||||||
<outlet property="generateAnswersCell" destination="l1g-Ul-Vg8" id="GlG-iZ-7FP"/>
|
|
||||||
<outlet property="generateLoginCell" destination="JVW-tG-xxe" id="PXM-WX-8Qe"/>
|
|
||||||
<outlet property="iOSIntegrationCell" destination="9Na-CL-jBq" id="LSO-OV-9KA"/>
|
|
||||||
<outlet property="loadingCell" destination="u3P-ng-YHc" id="gzb-K3-nKN"/>
|
|
||||||
<outlet property="touchIDCell" destination="8en-6R-GvR" id="edt-KM-iU1"/>
|
|
||||||
</connections>
|
|
||||||
</tableViewController>
|
</tableViewController>
|
||||||
<placeholder placeholderIdentifier="IBFirstResponder" id="WvF-bk-cgx" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
<placeholder placeholderIdentifier="IBFirstResponder" id="WvF-bk-cgx" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||||
</objects>
|
</objects>
|
||||||
@@ -3317,11 +3123,11 @@ You can temporarily reveal a password by holding your finger down on the site's
|
|||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<toolbar opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" barStyle="black" translatesAutoresizingMaskIntoConstraints="NO" id="aNU-Nq-clY">
|
<toolbar opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" barStyle="black" translatesAutoresizingMaskIntoConstraints="NO" id="aNU-Nq-clY">
|
||||||
<rect key="frame" x="0.0" y="342.5" width="375" height="324.5"/>
|
<rect key="frame" x="0.0" y="341.5" width="375" height="325.5"/>
|
||||||
<items/>
|
<items/>
|
||||||
</toolbar>
|
</toolbar>
|
||||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="252" verticalHuggingPriority="251" horizontalCompressionResistancePriority="751" text="You have sites that can be upgraded." lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="3Qi-GN-vhQ" userLabel="Title Label">
|
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="252" verticalHuggingPriority="251" horizontalCompressionResistancePriority="751" text="Lorem ipsum dolor sit amet." lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="3Qi-GN-vhQ" userLabel="Title Label">
|
||||||
<rect key="frame" x="16" y="362.5" width="343" height="20"/>
|
<rect key="frame" x="16" y="361.5" width="343" height="21"/>
|
||||||
<fontDescription key="fontDescription" name="Exo2.0-Bold" family="Exo 2.0" pointSize="17"/>
|
<fontDescription key="fontDescription" name="Exo2.0-Bold" family="Exo 2.0" pointSize="17"/>
|
||||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
@@ -3330,49 +3136,13 @@ You can temporarily reveal a password by holding your finger down on the site's
|
|||||||
<rect key="frame" x="16" y="390.5" width="343" height="216.5"/>
|
<rect key="frame" x="16" y="390.5" width="343" height="216.5"/>
|
||||||
<attributedString key="attributedText">
|
<attributedString key="attributedText">
|
||||||
<fragment>
|
<fragment>
|
||||||
<string key="content">Upgrading a site allows it to take advantage of
|
<string key="content">Prodest, inquit, mihi eo esse animo. Sed residamus, inquit, si placet. Istam voluptatem, inquit, Epicurus ignorat?
|
||||||
the latest improvements in the Master Password algorithm.
|
|
||||||
</string>
|
|
||||||
<attributes>
|
|
||||||
<color key="NSBackgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
|
||||||
<color key="NSColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
|
||||||
<font key="NSFont" size="12" name="Exo2.0-Regular"/>
|
|
||||||
<paragraphStyle key="NSParagraphStyle" alignment="left" lineBreakMode="wordWrapping" baseWritingDirection="natural"/>
|
|
||||||
</attributes>
|
|
||||||
</fragment>
|
|
||||||
<fragment>
|
|
||||||
<string key="content">
|
|
||||||
When you upgrade a site, </string>
|
|
||||||
<attributes>
|
|
||||||
<color key="NSBackgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
|
||||||
<color key="NSColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
|
||||||
<font key="NSFont" size="12" name="Exo2.0-Regular"/>
|
|
||||||
<paragraphStyle key="NSParagraphStyle" alignment="justified" lineBreakMode="wordWrapping" baseWritingDirection="natural"/>
|
|
||||||
</attributes>
|
|
||||||
</fragment>
|
|
||||||
<fragment content="a new and stronger password will be generated for it">
|
|
||||||
<attributes>
|
|
||||||
<color key="NSBackgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
|
||||||
<color key="NSColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
|
||||||
<font key="NSFont" size="12" name="Exo2.0-Bold"/>
|
|
||||||
<paragraphStyle key="NSParagraphStyle" alignment="justified" lineBreakMode="wordWrapping" baseWritingDirection="natural"/>
|
|
||||||
</attributes>
|
|
||||||
</fragment>
|
|
||||||
<fragment>
|
|
||||||
<string key="content">. To upgrade a site, first log into the site, navigate to your account preferences where you can change the site's password. Make sure you fill in any "current password" fields on the website first, then press the upgrade button here to get your new site password.
|
|
||||||
</string>
|
|
||||||
<attributes>
|
|
||||||
<color key="NSBackgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
|
||||||
<color key="NSColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
|
||||||
<font key="NSFont" size="12" name="Exo2.0-Regular"/>
|
|
||||||
<paragraphStyle key="NSParagraphStyle" alignment="justified" lineBreakMode="wordWrapping" baseWritingDirection="natural"/>
|
|
||||||
</attributes>
|
|
||||||
</fragment>
|
|
||||||
<fragment>
|
|
||||||
<string key="content">
|
|
||||||
You can then update your site's account with the new and stronger password.
|
|
||||||
|
|
||||||
</string>
|
Qualem igitur hominem natura inchoavit? Duo Reges: constructio interrete. Iam id ipsum absurdum, maximum malum neglegi. Quod cum dixissent, ille contra.
|
||||||
|
|
||||||
|
Nihil sane. Erat enim Polemonis. Sumenda potius quam expetenda. Sed ad illum redeo. Equidem e Cn.
|
||||||
|
|
||||||
|
Ut in geometria, prima si dederis, danda sunt omnia. Nonne igitur tibi videntur, inquit, mala? Quasi vero, inquit, perpetua oratio rhetorum solum, non etiam philosophorum sit. Tuo vero id quidem, inquam, arbitratu. A mene tu? Quid enim ab antiquis ex eo genere, quod ad disserendum valet, praetermissum est.</string>
|
||||||
<attributes>
|
<attributes>
|
||||||
<color key="NSBackgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
<color key="NSBackgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||||
<color key="NSColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
<color key="NSColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||||
@@ -3380,14 +3150,6 @@ You can then update your site's account with the new and stronger password.
|
|||||||
<paragraphStyle key="NSParagraphStyle" alignment="left" lineBreakMode="wordWrapping" baseWritingDirection="natural"/>
|
<paragraphStyle key="NSParagraphStyle" alignment="left" lineBreakMode="wordWrapping" baseWritingDirection="natural"/>
|
||||||
</attributes>
|
</attributes>
|
||||||
</fragment>
|
</fragment>
|
||||||
<fragment content="The upgrade button can be found in the site's settings and looks like this:">
|
|
||||||
<attributes>
|
|
||||||
<color key="NSBackgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
|
||||||
<color key="NSColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
|
||||||
<font key="NSFont" size="12" name="Exo2.0-Regular"/>
|
|
||||||
<paragraphStyle key="NSParagraphStyle" alignment="center" lineBreakMode="wordWrapping" baseWritingDirection="natural"/>
|
|
||||||
</attributes>
|
|
||||||
</fragment>
|
|
||||||
</attributedString>
|
</attributedString>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
@@ -3500,6 +3262,7 @@ You can then update your site's account with the new and stronger password.
|
|||||||
<resources>
|
<resources>
|
||||||
<image name="avatar-0.png" width="110" height="110"/>
|
<image name="avatar-0.png" width="110" height="110"/>
|
||||||
<image name="background.png" width="736" height="736"/>
|
<image name="background.png" width="736" height="736"/>
|
||||||
|
<image name="icon_action.png" width="32" height="32"/>
|
||||||
<image name="icon_book.png" width="32" height="32"/>
|
<image name="icon_book.png" width="32" height="32"/>
|
||||||
<image name="icon_cancel.png" width="32" height="32"/>
|
<image name="icon_cancel.png" width="32" height="32"/>
|
||||||
<image name="icon_edit.png" width="32" height="32"/>
|
<image name="icon_edit.png" width="32" height="32"/>
|
||||||
@@ -3516,12 +3279,8 @@ You can then update your site's account with the new and stronger password.
|
|||||||
<image name="icon_up.png" width="32" height="32"/>
|
<image name="icon_up.png" width="32" height="32"/>
|
||||||
<image name="identity.png" width="82" height="79"/>
|
<image name="identity.png" width="82" height="79"/>
|
||||||
<image name="initial.png" width="320" height="568"/>
|
<image name="initial.png" width="320" height="568"/>
|
||||||
<image name="meter_fuel.png" width="11" height="9"/>
|
|
||||||
<image name="thumb_fuel.png" width="198" height="198"/>
|
<image name="thumb_fuel.png" width="198" height="198"/>
|
||||||
<image name="thumb_generated_answers.png" width="198" height="198"/>
|
<image name="thumb_generated_answers.png" width="198" height="198"/>
|
||||||
<image name="thumb_generated_login.png" width="198" height="198"/>
|
|
||||||
<image name="thumb_ios_integration.png" width="198" height="198"/>
|
|
||||||
<image name="thumb_touch_id.png" width="198" height="198"/>
|
|
||||||
<image name="tip_basic_black.png" width="210" height="60"/>
|
<image name="tip_basic_black.png" width="210" height="60"/>
|
||||||
<image name="tip_basic_black_top.png" width="210" height="60"/>
|
<image name="tip_basic_black_top.png" width="210" height="60"/>
|
||||||
<image name="ui_spinner.png" width="75" height="75"/>
|
<image name="ui_spinner.png" width="75" height="75"/>
|
||||||
@@ -3534,8 +3293,8 @@ You can then update your site's account with the new and stronger password.
|
|||||||
<simulatedScreenMetrics key="destination" type="retina4_7.fullscreen"/>
|
<simulatedScreenMetrics key="destination" type="retina4_7.fullscreen"/>
|
||||||
</simulatedMetricsContainer>
|
</simulatedMetricsContainer>
|
||||||
<inferredMetricsTieBreakers>
|
<inferredMetricsTieBreakers>
|
||||||
<segue reference="GZk-I4-JyH"/>
|
<segue reference="gtb-zE-u9H"/>
|
||||||
<segue reference="Ql4-wf-T8u"/>
|
<segue reference="Ql4-wf-T8u"/>
|
||||||
</inferredMetricsTieBreakers>
|
</inferredMetricsTieBreakers>
|
||||||
<color key="tintColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="tintColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||||
</document>
|
</document>
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
mpw-2.5-cli-1-0-gb01e370f.tar.gz
|
mpw-2.5-cli-2-0-g3ed6b937.tar.gz
|
||||||
@@ -1 +1 @@
|
|||||||
mpw-2.5-cli-1-0-gb01e370f.tar.gz.sig
|
mpw-2.5-cli-2-0-g3ed6b937.tar.gz.sig
|
||||||
BIN
public/site/2013-05/mpw-2.5-cli-2-0-g3ed6b937.tar.gz
Normal file
BIN
public/site/2013-05/mpw-2.5-cli-2-0-g3ed6b937.tar.gz
Normal file
Binary file not shown.
BIN
public/site/2013-05/mpw-2.5-cli-2-0-g3ed6b937.tar.gz.sig
Normal file
BIN
public/site/2013-05/mpw-2.5-cli-2-0-g3ed6b937.tar.gz.sig
Normal file
Binary file not shown.
Reference in New Issue
Block a user