Merge branch 'develop' into feature/listLeftVariableIconWithRightCaretAllTextLinks
* develop: review changes file updates Changes for file movement Initial file movement # Conflicts: # MVMCoreUI.xcodeproj/project.pbxproj
This commit is contained in:
commit
3b7bcfee1d
@ -265,6 +265,8 @@
|
||||
BB2FB3BB247E7EBC00DF73CD /* TagCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB2FB3BA247E7EBC00DF73CD /* TagCollectionViewCell.swift */; };
|
||||
BB2FB3BD247E7EF200DF73CD /* Tags.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB2FB3BC247E7EF200DF73CD /* Tags.swift */; };
|
||||
BB2FB3BF247E7F0900DF73CD /* TagsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB2FB3BE247E7F0900DF73CD /* TagsModel.swift */; };
|
||||
BB3BC12F2550094500297977 /* ListLeftVariableIconWithRightCaretAllTextLinks.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB3BC12D2550094500297977 /* ListLeftVariableIconWithRightCaretAllTextLinks.swift */; };
|
||||
BB3BC1302550094500297977 /* ListLeftVariableIconWithRightCaretAllTextLinksModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB3BC12E2550094500297977 /* ListLeftVariableIconWithRightCaretAllTextLinksModel.swift */; };
|
||||
BB47A586241615EF002BB23C /* ListOneColumnFullWidthTextDividerSubsectionModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB47A585241615EF002BB23C /* ListOneColumnFullWidthTextDividerSubsectionModel.swift */; };
|
||||
BB47A588241615FA002BB23C /* ListOneColumnFullWidthTextDividerSubsection.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB47A587241615FA002BB23C /* ListOneColumnFullWidthTextDividerSubsection.swift */; };
|
||||
BB54C5202434D92F0038326C /* ListRightVariableButtonAllTextAndLinks.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB54C51E2434D92F0038326C /* ListRightVariableButtonAllTextAndLinks.swift */; };
|
||||
@ -282,8 +284,6 @@
|
||||
BBBBC87D24374A4900B0F079 /* ListThreeColumnBillChangesDividerModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBBBC87B24374A4900B0F079 /* ListThreeColumnBillChangesDividerModel.swift */; };
|
||||
BBC0C4FD24811DBC0087C44F /* Tag.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBC0C4FC24811DBC0087C44F /* Tag.swift */; };
|
||||
BBC0C4FF24811DCA0087C44F /* TagModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBC0C4FE24811DCA0087C44F /* TagModel.swift */; };
|
||||
BBF2CDB4254697C00024472A /* ListLeftVariableIconWithRightCaretAllTextLinksModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBF2CDB3254697C00024472A /* ListLeftVariableIconWithRightCaretAllTextLinksModel.swift */; };
|
||||
BBF2CDB7254697CF0024472A /* ListLeftVariableIconWithRightCaretAllTextLinks.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBF2CDB6254697CF0024472A /* ListLeftVariableIconWithRightCaretAllTextLinks.swift */; };
|
||||
C003506123AA94CD00B6AC29 /* Button.swift in Sources */ = {isa = PBXBuildFile; fileRef = C003506023AA94CD00B6AC29 /* Button.swift */; };
|
||||
C07065C42395677300FBF997 /* Link.swift in Sources */ = {isa = PBXBuildFile; fileRef = C07065C32395677300FBF997 /* Link.swift */; };
|
||||
C695A67F23C9830600BFB94E /* UnOrderedListModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C695A67E23C9830600BFB94E /* UnOrderedListModel.swift */; };
|
||||
@ -503,6 +503,31 @@
|
||||
D2EC7BD52527B7A600F540AF /* MoleculeSectionHeaderModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2EC7BD42527B7A600F540AF /* MoleculeSectionHeaderModel.swift */; };
|
||||
D2EC7BD92527B7CF00F540AF /* MoleculeSectionHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2EC7BD82527B7CF00F540AF /* MoleculeSectionHeader.swift */; };
|
||||
D2EC7BDD2527B83700F540AF /* SectionHeaderFooterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2EC7BDC2527B83700F540AF /* SectionHeaderFooterView.swift */; };
|
||||
D2ED27EB254B0CE700A1C293 /* UIAlertActionStyle+Codable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2ED27E6254B0CE600A1C293 /* UIAlertActionStyle+Codable.swift */; };
|
||||
D2ED27EC254B0CE700A1C293 /* UIAlertControllerStyle+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2ED27E7254B0CE600A1C293 /* UIAlertControllerStyle+Extension.swift */; };
|
||||
D2ED27ED254B0CE700A1C293 /* ActionPopupModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2ED27E8254B0CE600A1C293 /* ActionPopupModel.swift */; };
|
||||
D2ED27EE254B0CE700A1C293 /* ActionAlertModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2ED27E9254B0CE600A1C293 /* ActionAlertModel.swift */; };
|
||||
D2ED27EF254B0CE700A1C293 /* AlertModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2ED27EA254B0CE700A1C293 /* AlertModel.swift */; };
|
||||
D2ED27FB254B0E0300A1C293 /* MVMCoreAlertDelegateProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = D2ED27F2254B0E0200A1C293 /* MVMCoreAlertDelegateProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
D2ED27FC254B0E0300A1C293 /* MVMCoreAlertObject+Swift.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2ED27F3254B0E0200A1C293 /* MVMCoreAlertObject+Swift.swift */; };
|
||||
D2ED27FD254B0E0300A1C293 /* MVMCoreAlertOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = D2ED27F4254B0E0200A1C293 /* MVMCoreAlertOperation.m */; };
|
||||
D2ED27FE254B0E0300A1C293 /* MVMCoreAlertObject.h in Headers */ = {isa = PBXBuildFile; fileRef = D2ED27F5254B0E0200A1C293 /* MVMCoreAlertObject.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
D2ED27FF254B0E0300A1C293 /* MVMCoreAlertHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = D2ED27F6254B0E0200A1C293 /* MVMCoreAlertHandler.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
D2ED2800254B0E0300A1C293 /* MVMCoreAlertHandler+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2ED27F7254B0E0200A1C293 /* MVMCoreAlertHandler+Extension.swift */; };
|
||||
D2ED2801254B0E0300A1C293 /* MVMCoreAlertOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = D2ED27F8254B0E0200A1C293 /* MVMCoreAlertOperation.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
D2ED2802254B0E0300A1C293 /* MVMCoreAlertObject.m in Sources */ = {isa = PBXBuildFile; fileRef = D2ED27F9254B0E0200A1C293 /* MVMCoreAlertObject.m */; };
|
||||
D2ED2803254B0E0300A1C293 /* MVMCoreAlertHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = D2ED27FA254B0E0300A1C293 /* MVMCoreAlertHandler.m */; };
|
||||
D2ED280C254B0EB800A1C293 /* MVMCoreTopAlertAnimationDelegateProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = D2ED2805254B0EB700A1C293 /* MVMCoreTopAlertAnimationDelegateProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
D2ED280D254B0EB800A1C293 /* MVMCoreTopAlertOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = D2ED2806254B0EB700A1C293 /* MVMCoreTopAlertOperation.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
D2ED280E254B0EB800A1C293 /* MVMCoreTopAlertOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = D2ED2807254B0EB700A1C293 /* MVMCoreTopAlertOperation.m */; };
|
||||
D2ED280F254B0EB800A1C293 /* MVMCoreTopAlertViewProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = D2ED2808254B0EB700A1C293 /* MVMCoreTopAlertViewProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
D2ED2810254B0EB800A1C293 /* MVMCoreTopAlertDelegateProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = D2ED2809254B0EB700A1C293 /* MVMCoreTopAlertDelegateProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
D2ED2811254B0EB800A1C293 /* MVMCoreTopAlertObject.h in Headers */ = {isa = PBXBuildFile; fileRef = D2ED280A254B0EB700A1C293 /* MVMCoreTopAlertObject.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
D2ED2812254B0EB800A1C293 /* MVMCoreTopAlertObject.m in Sources */ = {isa = PBXBuildFile; fileRef = D2ED280B254B0EB800A1C293 /* MVMCoreTopAlertObject.m */; };
|
||||
D2ED2815254B0EE400A1C293 /* MVMCoreGlobalTopAlertDelegateProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = D2ED2814254B0EE400A1C293 /* MVMCoreGlobalTopAlertDelegateProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
D2ED2818254B115400A1C293 /* MVMCoreUIActionDelegateProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = D2ED2817254B112900A1C293 /* MVMCoreUIActionDelegateProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
D2ED281D254B119D00A1C293 /* MVMCoreUIActionHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = D2ED281B254B119D00A1C293 /* MVMCoreUIActionHandler.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
D2ED281E254B119D00A1C293 /* MVMCoreUIActionHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = D2ED281C254B119D00A1C293 /* MVMCoreUIActionHandler.m */; };
|
||||
D2FA83D22513EA6900564112 /* NotificationXButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2FA83D12513EA6900564112 /* NotificationXButton.swift */; };
|
||||
D2FA83D42514F80C00564112 /* CollapsableNotification.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2FA83D32514F80C00564112 /* CollapsableNotification.swift */; };
|
||||
D2FA83D62515021F00564112 /* CollapsableNotificationTopView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2FA83D52515021F00564112 /* CollapsableNotificationTopView.swift */; };
|
||||
@ -779,6 +804,8 @@
|
||||
BB2FB3BA247E7EBC00DF73CD /* TagCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TagCollectionViewCell.swift; sourceTree = "<group>"; };
|
||||
BB2FB3BC247E7EF200DF73CD /* Tags.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tags.swift; sourceTree = "<group>"; };
|
||||
BB2FB3BE247E7F0900DF73CD /* TagsModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TagsModel.swift; sourceTree = "<group>"; };
|
||||
BB3BC12D2550094500297977 /* ListLeftVariableIconWithRightCaretAllTextLinks.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListLeftVariableIconWithRightCaretAllTextLinks.swift; sourceTree = "<group>"; };
|
||||
BB3BC12E2550094500297977 /* ListLeftVariableIconWithRightCaretAllTextLinksModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListLeftVariableIconWithRightCaretAllTextLinksModel.swift; sourceTree = "<group>"; };
|
||||
BB47A585241615EF002BB23C /* ListOneColumnFullWidthTextDividerSubsectionModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListOneColumnFullWidthTextDividerSubsectionModel.swift; sourceTree = "<group>"; };
|
||||
BB47A587241615FA002BB23C /* ListOneColumnFullWidthTextDividerSubsection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListOneColumnFullWidthTextDividerSubsection.swift; sourceTree = "<group>"; };
|
||||
BB54C51E2434D92F0038326C /* ListRightVariableButtonAllTextAndLinks.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListRightVariableButtonAllTextAndLinks.swift; sourceTree = "<group>"; };
|
||||
@ -796,8 +823,6 @@
|
||||
BBBBC87B24374A4900B0F079 /* ListThreeColumnBillChangesDividerModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListThreeColumnBillChangesDividerModel.swift; sourceTree = "<group>"; };
|
||||
BBC0C4FC24811DBC0087C44F /* Tag.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tag.swift; sourceTree = "<group>"; };
|
||||
BBC0C4FE24811DCA0087C44F /* TagModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TagModel.swift; sourceTree = "<group>"; };
|
||||
BBF2CDB3254697C00024472A /* ListLeftVariableIconWithRightCaretAllTextLinksModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListLeftVariableIconWithRightCaretAllTextLinksModel.swift; sourceTree = "<group>"; };
|
||||
BBF2CDB6254697CF0024472A /* ListLeftVariableIconWithRightCaretAllTextLinks.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListLeftVariableIconWithRightCaretAllTextLinks.swift; sourceTree = "<group>"; };
|
||||
C003506023AA94CD00B6AC29 /* Button.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Button.swift; sourceTree = "<group>"; };
|
||||
C07065C32395677300FBF997 /* Link.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Link.swift; sourceTree = "<group>"; };
|
||||
C695A67E23C9830600BFB94E /* UnOrderedListModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UnOrderedListModel.swift; sourceTree = "<group>"; };
|
||||
@ -1018,6 +1043,31 @@
|
||||
D2EC7BD42527B7A600F540AF /* MoleculeSectionHeaderModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoleculeSectionHeaderModel.swift; sourceTree = "<group>"; };
|
||||
D2EC7BD82527B7CF00F540AF /* MoleculeSectionHeader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoleculeSectionHeader.swift; sourceTree = "<group>"; };
|
||||
D2EC7BDC2527B83700F540AF /* SectionHeaderFooterView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SectionHeaderFooterView.swift; sourceTree = "<group>"; };
|
||||
D2ED27E6254B0CE600A1C293 /* UIAlertActionStyle+Codable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIAlertActionStyle+Codable.swift"; sourceTree = "<group>"; };
|
||||
D2ED27E7254B0CE600A1C293 /* UIAlertControllerStyle+Extension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIAlertControllerStyle+Extension.swift"; sourceTree = "<group>"; };
|
||||
D2ED27E8254B0CE600A1C293 /* ActionPopupModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActionPopupModel.swift; sourceTree = "<group>"; };
|
||||
D2ED27E9254B0CE600A1C293 /* ActionAlertModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActionAlertModel.swift; sourceTree = "<group>"; };
|
||||
D2ED27EA254B0CE700A1C293 /* AlertModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AlertModel.swift; sourceTree = "<group>"; };
|
||||
D2ED27F2254B0E0200A1C293 /* MVMCoreAlertDelegateProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVMCoreAlertDelegateProtocol.h; sourceTree = "<group>"; };
|
||||
D2ED27F3254B0E0200A1C293 /* MVMCoreAlertObject+Swift.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "MVMCoreAlertObject+Swift.swift"; sourceTree = "<group>"; };
|
||||
D2ED27F4254B0E0200A1C293 /* MVMCoreAlertOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MVMCoreAlertOperation.m; sourceTree = "<group>"; };
|
||||
D2ED27F5254B0E0200A1C293 /* MVMCoreAlertObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVMCoreAlertObject.h; sourceTree = "<group>"; };
|
||||
D2ED27F6254B0E0200A1C293 /* MVMCoreAlertHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVMCoreAlertHandler.h; sourceTree = "<group>"; };
|
||||
D2ED27F7254B0E0200A1C293 /* MVMCoreAlertHandler+Extension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "MVMCoreAlertHandler+Extension.swift"; sourceTree = "<group>"; };
|
||||
D2ED27F8254B0E0200A1C293 /* MVMCoreAlertOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVMCoreAlertOperation.h; sourceTree = "<group>"; };
|
||||
D2ED27F9254B0E0200A1C293 /* MVMCoreAlertObject.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MVMCoreAlertObject.m; sourceTree = "<group>"; };
|
||||
D2ED27FA254B0E0300A1C293 /* MVMCoreAlertHandler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MVMCoreAlertHandler.m; sourceTree = "<group>"; };
|
||||
D2ED2805254B0EB700A1C293 /* MVMCoreTopAlertAnimationDelegateProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVMCoreTopAlertAnimationDelegateProtocol.h; sourceTree = "<group>"; };
|
||||
D2ED2806254B0EB700A1C293 /* MVMCoreTopAlertOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVMCoreTopAlertOperation.h; sourceTree = "<group>"; };
|
||||
D2ED2807254B0EB700A1C293 /* MVMCoreTopAlertOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MVMCoreTopAlertOperation.m; sourceTree = "<group>"; };
|
||||
D2ED2808254B0EB700A1C293 /* MVMCoreTopAlertViewProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVMCoreTopAlertViewProtocol.h; sourceTree = "<group>"; };
|
||||
D2ED2809254B0EB700A1C293 /* MVMCoreTopAlertDelegateProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVMCoreTopAlertDelegateProtocol.h; sourceTree = "<group>"; };
|
||||
D2ED280A254B0EB700A1C293 /* MVMCoreTopAlertObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVMCoreTopAlertObject.h; sourceTree = "<group>"; };
|
||||
D2ED280B254B0EB800A1C293 /* MVMCoreTopAlertObject.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MVMCoreTopAlertObject.m; sourceTree = "<group>"; };
|
||||
D2ED2814254B0EE400A1C293 /* MVMCoreGlobalTopAlertDelegateProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVMCoreGlobalTopAlertDelegateProtocol.h; sourceTree = "<group>"; };
|
||||
D2ED2817254B112900A1C293 /* MVMCoreUIActionDelegateProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreUIActionDelegateProtocol.h; sourceTree = "<group>"; };
|
||||
D2ED281B254B119D00A1C293 /* MVMCoreUIActionHandler.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreUIActionHandler.h; sourceTree = "<group>"; };
|
||||
D2ED281C254B119D00A1C293 /* MVMCoreUIActionHandler.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MVMCoreUIActionHandler.m; sourceTree = "<group>"; };
|
||||
D2FA83D12513EA6900564112 /* NotificationXButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationXButton.swift; sourceTree = "<group>"; };
|
||||
D2FA83D32514F80C00564112 /* CollapsableNotification.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollapsableNotification.swift; sourceTree = "<group>"; };
|
||||
D2FA83D52515021F00564112 /* CollapsableNotificationTopView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollapsableNotificationTopView.swift; sourceTree = "<group>"; };
|
||||
@ -1247,6 +1297,9 @@
|
||||
94C0150924215643005811A9 /* ActionTopAlertModel.swift */,
|
||||
94C0150B2421564A005811A9 /* ActionCollapseNotificationModel.swift */,
|
||||
D2C78CD124228BBD00B69FDE /* ActionOpenPanelModel.swift */,
|
||||
D2ED27E9254B0CE600A1C293 /* ActionAlertModel.swift */,
|
||||
D2ED27EA254B0CE700A1C293 /* AlertModel.swift */,
|
||||
D2ED27E8254B0CE600A1C293 /* ActionPopupModel.swift */,
|
||||
);
|
||||
path = Actions;
|
||||
sourceTree = "<group>";
|
||||
@ -1312,6 +1365,8 @@
|
||||
0A7ECC6F2441001C00C828E8 /* UIToolbar+Extension.swift */,
|
||||
0AB764D024460F6300E7FE72 /* UIDatePicker+Extension.swift */,
|
||||
0AB764D224460FA400E7FE72 /* UIPickerView+Extension.swift */,
|
||||
D2ED27E6254B0CE600A1C293 /* UIAlertActionStyle+Codable.swift */,
|
||||
D2ED27E7254B0CE600A1C293 /* UIAlertControllerStyle+Extension.swift */,
|
||||
);
|
||||
path = Extensions;
|
||||
sourceTree = "<group>";
|
||||
@ -1491,12 +1546,12 @@
|
||||
AA69AAF52445BF5700AF3D3B /* ListLeftVariableCheckboxBodyText.swift */,
|
||||
522679C023FE886900906CBA /* ListLeftVariableCheckboxAllTextAndLinksModel.swift */,
|
||||
522679BF23FE886900906CBA /* ListLeftVariableCheckboxAllTextAndLinks.swift */,
|
||||
BB3BC12D2550094500297977 /* ListLeftVariableIconWithRightCaretAllTextLinks.swift */,
|
||||
BB3BC12E2550094500297977 /* ListLeftVariableIconWithRightCaretAllTextLinksModel.swift */,
|
||||
8D24041423E7FC0B009E23BE /* ListLeftVariableIconWithRightCaretModel.swift */,
|
||||
8D24041023E7FB9E009E23BE /* ListLeftVariableIconWithRightCaret.swift */,
|
||||
AA0A257724766C8A00862F64 /* ListLeftVariableIconWithRightCaretBodyTextModel.swift */,
|
||||
AA0A257924766CA200862F64 /* ListLeftVariableIconWithRightCaretBodyText.swift */,
|
||||
BBF2CDB3254697C00024472A /* ListLeftVariableIconWithRightCaretAllTextLinksModel.swift */,
|
||||
BBF2CDB6254697CF0024472A /* ListLeftVariableIconWithRightCaretAllTextLinks.swift */,
|
||||
0A6682A32434DB8D00AD3CA1 /* ListLeftVariableRadioButtonBodyTextModel.swift */,
|
||||
0A6682A12434DB4F00AD3CA1 /* ListLeftVariableRadioButtonBodyText.swift */,
|
||||
AA7F32AA246C0F7900C965BA /* ListLeftVariableRadioButtonAllTextAndLinksModel.swift */,
|
||||
@ -1690,6 +1745,7 @@
|
||||
D29DF0CE21E404D4003B2FB9 /* MVMCoreUI */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D2ED27D8254B0C1F00A1C293 /* Alerts */,
|
||||
27F973512466071600CAB5C5 /* Behaviors */,
|
||||
D2C78CD324252F4E00B69FDE /* Atomic */,
|
||||
012A88EF23985E0100FE3DA1 /* CustomPrimitives */,
|
||||
@ -1704,7 +1760,6 @@
|
||||
D22D1F582204D2590077CEC0 /* Legacy */,
|
||||
D29DF10F21E67A7D003B2FB9 /* BaseControllers */,
|
||||
D29DF11E21E6851E003B2FB9 /* TopAlert */,
|
||||
94C01508242155FE005811A9 /* Actions */,
|
||||
D29DF0CF21E404D4003B2FB9 /* MVMCoreUI.h */,
|
||||
D29DF0D021E404D4003B2FB9 /* Info.plist */,
|
||||
);
|
||||
@ -1827,6 +1882,14 @@
|
||||
D29DF11E21E6851E003B2FB9 /* TopAlert */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D2ED2814254B0EE400A1C293 /* MVMCoreGlobalTopAlertDelegateProtocol.h */,
|
||||
D2ED2805254B0EB700A1C293 /* MVMCoreTopAlertAnimationDelegateProtocol.h */,
|
||||
D2ED2809254B0EB700A1C293 /* MVMCoreTopAlertDelegateProtocol.h */,
|
||||
D2ED280A254B0EB700A1C293 /* MVMCoreTopAlertObject.h */,
|
||||
D2ED280B254B0EB800A1C293 /* MVMCoreTopAlertObject.m */,
|
||||
D2ED2806254B0EB700A1C293 /* MVMCoreTopAlertOperation.h */,
|
||||
D2ED2807254B0EB700A1C293 /* MVMCoreTopAlertOperation.m */,
|
||||
D2ED2808254B0EB700A1C293 /* MVMCoreTopAlertViewProtocol.h */,
|
||||
D20C7008250BF99B0095B21C /* TopNotificationModel.swift */,
|
||||
D20C700A250BFDE40095B21C /* MVMCoreUITopAlertView+Extension.swift */,
|
||||
D29DF12021E6851E003B2FB9 /* MVMCoreUITopAlertView.h */,
|
||||
@ -1994,6 +2057,9 @@
|
||||
D2C5001721F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.m */,
|
||||
D2092352244F7D630044AD09 /* MVMCoreUIViewControllerMappingObject+Extension.swift */,
|
||||
D296E14622A597490051EBE7 /* MVMCoreUIViewConstrainingProtocol.h */,
|
||||
D2ED2817254B112900A1C293 /* MVMCoreUIActionDelegateProtocol.h */,
|
||||
D2ED281B254B119D00A1C293 /* MVMCoreUIActionHandler.h */,
|
||||
D2ED281C254B119D00A1C293 /* MVMCoreUIActionHandler.m */,
|
||||
);
|
||||
path = OtherHandlers;
|
||||
sourceTree = "<group>";
|
||||
@ -2111,6 +2177,7 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
017BEB7E23676E870024EF95 /* MoleculeObjectMapping.swift */,
|
||||
94C01508242155FE005811A9 /* Actions */,
|
||||
D202AFE2242A5F1400E5BEDF /* Extensions */,
|
||||
D2C78CD424252F5D00B69FDE /* Protocols */,
|
||||
D29DF10D21E67A70003B2FB9 /* Atoms */,
|
||||
@ -2179,6 +2246,22 @@
|
||||
path = HeadersAndFooters;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
D2ED27D8254B0C1F00A1C293 /* Alerts */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D2ED27F2254B0E0200A1C293 /* MVMCoreAlertDelegateProtocol.h */,
|
||||
D2ED27F6254B0E0200A1C293 /* MVMCoreAlertHandler.h */,
|
||||
D2ED27FA254B0E0300A1C293 /* MVMCoreAlertHandler.m */,
|
||||
D2ED27F7254B0E0200A1C293 /* MVMCoreAlertHandler+Extension.swift */,
|
||||
D2ED27F5254B0E0200A1C293 /* MVMCoreAlertObject.h */,
|
||||
D2ED27F9254B0E0200A1C293 /* MVMCoreAlertObject.m */,
|
||||
D2ED27F3254B0E0200A1C293 /* MVMCoreAlertObject+Swift.swift */,
|
||||
D2ED27F8254B0E0200A1C293 /* MVMCoreAlertOperation.h */,
|
||||
D2ED27F4254B0E0200A1C293 /* MVMCoreAlertOperation.m */,
|
||||
);
|
||||
path = Alerts;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXHeadersBuildPhase section */
|
||||
@ -2212,11 +2295,23 @@
|
||||
D29DF2EE21ECEADF003B2FB9 /* MFFonts.h in Headers */,
|
||||
D29DF12D21E6851E003B2FB9 /* MVMCoreUITopAlertBaseView.h in Headers */,
|
||||
D2C5001821F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.h in Headers */,
|
||||
D2ED2811254B0EB800A1C293 /* MVMCoreTopAlertObject.h in Headers */,
|
||||
D2ED27FE254B0E0300A1C293 /* MVMCoreAlertObject.h in Headers */,
|
||||
D2ED280F254B0EB800A1C293 /* MVMCoreTopAlertViewProtocol.h in Headers */,
|
||||
D2ED280C254B0EB800A1C293 /* MVMCoreTopAlertAnimationDelegateProtocol.h in Headers */,
|
||||
D2ED280D254B0EB800A1C293 /* MVMCoreTopAlertOperation.h in Headers */,
|
||||
D2ED2801254B0E0300A1C293 /* MVMCoreAlertOperation.h in Headers */,
|
||||
D2ED2818254B115400A1C293 /* MVMCoreUIActionDelegateProtocol.h in Headers */,
|
||||
D2ED27FB254B0E0300A1C293 /* MVMCoreAlertDelegateProtocol.h in Headers */,
|
||||
D2ED2810254B0EB800A1C293 /* MVMCoreTopAlertDelegateProtocol.h in Headers */,
|
||||
D2ED27FF254B0E0300A1C293 /* MVMCoreAlertHandler.h in Headers */,
|
||||
D2ED2815254B0EE400A1C293 /* MVMCoreGlobalTopAlertDelegateProtocol.h in Headers */,
|
||||
D29DF26F21E6AA0B003B2FB9 /* FLAnimatedImageView.h in Headers */,
|
||||
D29DF2A121E7AF4E003B2FB9 /* MVMCoreUIUtility.h in Headers */,
|
||||
D29DF2C821E7BFC1003B2FB9 /* MFSizeObject.h in Headers */,
|
||||
D29DF2E121E9240B003B2FB9 /* MVMCoreUIPanelProtocol.h in Headers */,
|
||||
D29DF12921E6851E003B2FB9 /* MVMCoreUITopAlertMainView.h in Headers */,
|
||||
D2ED281D254B119D00A1C293 /* MVMCoreUIActionHandler.h in Headers */,
|
||||
D29DF12C21E6851E003B2FB9 /* MVMCoreUITopAlertShortView.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
@ -2325,6 +2420,7 @@
|
||||
AAB9C10824346F4B00151545 /* RadioSwatches.swift in Sources */,
|
||||
94C2D9A923872E5E0006CF46 /* LabelAttributeImageModel.swift in Sources */,
|
||||
DBC4391922442197001AB423 /* DashLine.swift in Sources */,
|
||||
D2ED27FC254B0E0300A1C293 /* MVMCoreAlertObject+Swift.swift in Sources */,
|
||||
D264FAAA2440F97600D98315 /* CollectionView.swift in Sources */,
|
||||
AAC23FAD24D92A0D009208DF /* ListThreeColumnSpeedTestModel.swift in Sources */,
|
||||
BBC0C4FF24811DCA0087C44F /* TagModel.swift in Sources */,
|
||||
@ -2372,6 +2468,7 @@
|
||||
012A88C8238DB02000FE3DA1 /* MoleculeDelegateProtocol.swift in Sources */,
|
||||
8D8067D12444472F00203BE8 /* ListRightVariablePriceChangeAllTextAndLinksModel.swift in Sources */,
|
||||
0A7EF86123D8AC2500B2AAD1 /* DigitEntryFieldModel.swift in Sources */,
|
||||
D2ED2802254B0E0300A1C293 /* MVMCoreAlertObject.m in Sources */,
|
||||
D224798C231450C8003FCCF9 /* HeadlineBodyToggle.swift in Sources */,
|
||||
9458C3182406C8FD00930963 /* UIFont+FontWrapping.m in Sources */,
|
||||
522679C123FE886900906CBA /* ListLeftVariableCheckboxAllTextAndLinks.swift in Sources */,
|
||||
@ -2395,7 +2492,8 @@
|
||||
D2E2A99823D8D63C000B42E6 /* ActionDetailWithImageModel.swift in Sources */,
|
||||
D28764AC245898A400CB882D /* ThreeLayerFillMiddleTemplateModel.swift in Sources */,
|
||||
BBBBC87D24374A4900B0F079 /* ListThreeColumnBillChangesDividerModel.swift in Sources */,
|
||||
BBF2CDB7254697CF0024472A /* ListLeftVariableIconWithRightCaretAllTextLinks.swift in Sources */,
|
||||
D2ED2800254B0E0300A1C293 /* MVMCoreAlertHandler+Extension.swift in Sources */,
|
||||
D2ED27EE254B0CE700A1C293 /* ActionAlertModel.swift in Sources */,
|
||||
D2E2A99D23DA3217000B42E6 /* UIStackViewAlignment+Extension.swift in Sources */,
|
||||
01EB369423609801006832FA /* HeadlineBodyModel.swift in Sources */,
|
||||
D2A92884241ACB25004E01C6 /* ProgrammaticScrollViewController.swift in Sources */,
|
||||
@ -2408,7 +2506,6 @@
|
||||
D2CAC7D3251105A700C75681 /* MVMCoreUITopAlertExpandableView+Extension.swift in Sources */,
|
||||
AA07EA932510A451009A2AE3 /* Star.swift in Sources */,
|
||||
D29DF2CF21E7C104003B2FB9 /* MFLoadingViewController.m in Sources */,
|
||||
BBF2CDB4254697C00024472A /* ListLeftVariableIconWithRightCaretAllTextLinksModel.swift in Sources */,
|
||||
D28A837B23C928DA00DFE4FC /* MoleculeListCellProtocol.swift in Sources */,
|
||||
D28BA74D248589C800B75CB8 /* TabPageModelProtocol.swift in Sources */,
|
||||
014AA72F23C5059B006F3E93 /* ThreeLayerPageTemplateModel.swift in Sources */,
|
||||
@ -2419,6 +2516,7 @@
|
||||
AAA905E124D1759A00D1EFAB /* ListThreeColumnBillHistory.swift in Sources */,
|
||||
C7F8012323E846C300396FBD /* ListRVWheelModel.swift in Sources */,
|
||||
D29DF27621E79E81003B2FB9 /* MVMCoreUILoggingHandler.m in Sources */,
|
||||
D2ED27EC254B0CE700A1C293 /* UIAlertControllerStyle+Extension.swift in Sources */,
|
||||
C695A69623C990BC00BFB94E /* DoughnutChart.swift in Sources */,
|
||||
014AA72D23C5059B006F3E93 /* StackPageTemplateModel.swift in Sources */,
|
||||
0A9D091F2433796500D2E6C0 /* NumericIndicatorView.swift in Sources */,
|
||||
@ -2431,6 +2529,7 @@
|
||||
52B201D324081CFB00D2011E /* ListLeftVariableRadioButtonAndPaymentMethodModel.swift in Sources */,
|
||||
525239C02407BCFF00454969 /* ListTwoColumnPriceDetailsModel.swift in Sources */,
|
||||
D2E2A99A23D8D6B4000B42E6 /* HeadlineBodyButtonModel.swift in Sources */,
|
||||
D2ED280E254B0EB800A1C293 /* MVMCoreTopAlertOperation.m in Sources */,
|
||||
D202AFE6242A6A9C00E5BEDF /* UICollectionViewScrollPosition+Extension.swift in Sources */,
|
||||
D20F3B44252E00E4004B3F56 /* PageProtocol.swift in Sources */,
|
||||
AA37CBD3251907200027344C /* StarsModel.swift in Sources */,
|
||||
@ -2441,6 +2540,7 @@
|
||||
AAC23FAF24D92A1E009208DF /* ListThreeColumnSpeedTest.swift in Sources */,
|
||||
D29DF2A221E7AF4E003B2FB9 /* MVMCoreUIUtility.m in Sources */,
|
||||
D29DF12B21E6851E003B2FB9 /* MVMCoreUITopAlertExpandableView.m in Sources */,
|
||||
D2ED27ED254B0CE700A1C293 /* ActionPopupModel.swift in Sources */,
|
||||
94C2D9A723872DA90006CF46 /* LabelAttributeColorModel.swift in Sources */,
|
||||
943820842432382400B43AF3 /* WebView.swift in Sources */,
|
||||
0103B84E23D7E33A009C315C /* HeadlineBodyToggleModel.swift in Sources */,
|
||||
@ -2458,6 +2558,7 @@
|
||||
944589232385DA9600DE9FD4 /* ImageViewModel.swift in Sources */,
|
||||
D213347723843825008E41B3 /* Line.swift in Sources */,
|
||||
D2E2A99C23D8D975000B42E6 /* ImageHeadlineBodyModel.swift in Sources */,
|
||||
BB3BC1302550094500297977 /* ListLeftVariableIconWithRightCaretAllTextLinksModel.swift in Sources */,
|
||||
525019DE2406430800EED91C /* ListProgressBarData.swift in Sources */,
|
||||
D28A837F23CCA96400DFE4FC /* TabsModel.swift in Sources */,
|
||||
AAB8549A24DC01DB00477C40 /* ListThreeColumnBillHistoryDivider.swift in Sources */,
|
||||
@ -2494,6 +2595,7 @@
|
||||
D2092357244FA1EF0044AD09 /* ThreeLayerModelBase.swift in Sources */,
|
||||
D2FD4A4925199BD9000C28A9 /* AccessibilityProtocol.swift in Sources */,
|
||||
D2CAC7CD251104FE00C75681 /* NotificationModel.swift in Sources */,
|
||||
D2ED2803254B0E0300A1C293 /* MVMCoreAlertHandler.m in Sources */,
|
||||
0A1B4A96233BB18F005B3FB4 /* CheckboxLabel.swift in Sources */,
|
||||
D20923592450ECE00044AD09 /* TableView.swift in Sources */,
|
||||
BB47A586241615EF002BB23C /* ListOneColumnFullWidthTextDividerSubsectionModel.swift in Sources */,
|
||||
@ -2544,6 +2646,7 @@
|
||||
D22479962316AF6E003FCCF9 /* HeadlineBodyLink.swift in Sources */,
|
||||
8DE5BECD2456F7A200772E76 /* ListTwoColumnDropdownSelectorsModel.swift in Sources */,
|
||||
0A41BA7F23453A6400D4C0BC /* TextEntryField.swift in Sources */,
|
||||
D2ED27EB254B0CE700A1C293 /* UIAlertActionStyle+Codable.swift in Sources */,
|
||||
BB55B51D244482C1002001AD /* ListRightVariablePriceChangeBodyText.swift in Sources */,
|
||||
017BEB382360C6AC0024EF95 /* RadioButtonLabel.swift in Sources */,
|
||||
323AC96C24C837FF00F8E4C4 /* ListThreeColumnBillChanges.swift in Sources */,
|
||||
@ -2581,6 +2684,7 @@
|
||||
3265B30224BCA737000D154B /* HeadersH1NoButtonsBodyTextModel.swift in Sources */,
|
||||
D28A838F23CCDEDE00DFE4FC /* TwoButtonViewModel.swift in Sources */,
|
||||
D264FAAC2441009400D98315 /* RadioBoxCollectionViewCell.swift in Sources */,
|
||||
D2ED27FD254B0E0300A1C293 /* MVMCoreAlertOperation.m in Sources */,
|
||||
BB2C969224330F73006FF80C /* ListRightVariableTextLinkAllTextAndLinks.swift in Sources */,
|
||||
D2D90B42240463E100DD6EC9 /* MoleculeHeaderModel.swift in Sources */,
|
||||
012A88B1238C880100FE3DA1 /* CarouselPagingModelProtocol.swift in Sources */,
|
||||
@ -2596,6 +2700,7 @@
|
||||
279B1569242BBC2F00921D6C /* ActionModelAdapter.swift in Sources */,
|
||||
BB6C6AC0242232DF005F7224 /* ListOneColumnTextWithWhitespaceDividerTallModel.swift in Sources */,
|
||||
8DEFA95E243DAC2F000D27E5 /* ListThreeColumnDataUsageDivider.swift in Sources */,
|
||||
D2ED27EF254B0CE700A1C293 /* AlertModel.swift in Sources */,
|
||||
D2EAC0A42541F00F00AA9495 /* CarouselCollectionLayout.swift in Sources */,
|
||||
AAE7270E24AC8B9300A3ED0E /* HeadersH2CaretLink.swift in Sources */,
|
||||
0AD93A9F24C0AA5100E56A97 /* ImageView.swift in Sources */,
|
||||
@ -2613,6 +2718,7 @@
|
||||
BB2FB3BD247E7EF200DF73CD /* Tags.swift in Sources */,
|
||||
AA104ADC244734EA004D2810 /* HeadersH1LandingPageHeaderModel.swift in Sources */,
|
||||
BBAA4F03243D8E3B005AAD5F /* RadioBoxes.swift in Sources */,
|
||||
D2ED281E254B119D00A1C293 /* MVMCoreUIActionHandler.m in Sources */,
|
||||
323AC96A24C837F000F8E4C4 /* ListThreeColumnBillChangesModel.swift in Sources */,
|
||||
D2E1FAE12268E81D00AEFD8C /* MoleculeListTemplate.swift in Sources */,
|
||||
525019E72406853600EED91C /* ListFourColumnDataUsageDivider.swift in Sources */,
|
||||
@ -2631,6 +2737,7 @@
|
||||
D2D90B442404789000DD6EC9 /* MoleculeContainerProtocol.swift in Sources */,
|
||||
0A7ECC5F243CEB1200C828E8 /* ColorViewWithLabel.swift in Sources */,
|
||||
94C0150A24215643005811A9 /* ActionTopAlertModel.swift in Sources */,
|
||||
BB3BC12F2550094500297977 /* ListLeftVariableIconWithRightCaretAllTextLinks.swift in Sources */,
|
||||
012A88DB238ED45900FE3DA1 /* CarouselModel.swift in Sources */,
|
||||
D2092355244FA0FD0044AD09 /* ThreeLayerTemplateModelProtocol.swift in Sources */,
|
||||
0AE14F64238315D2005417F8 /* TextField.swift in Sources */,
|
||||
@ -2708,6 +2815,7 @@
|
||||
D22D8393241C27B100D3DF69 /* TemplateModel.swift in Sources */,
|
||||
012A889C23889E8400FE3DA1 /* TemplateModelProtocol.swift in Sources */,
|
||||
52267A0723FFE25000906CBA /* ListOneColumnFullWidthTextAllTextAndLinks.swift in Sources */,
|
||||
D2ED2812254B0EB800A1C293 /* MVMCoreTopAlertObject.m in Sources */,
|
||||
C003506123AA94CD00B6AC29 /* Button.swift in Sources */,
|
||||
DBC4391B224421A0001AB423 /* CaretLink.swift in Sources */,
|
||||
D264FA90243BCE6800D98315 /* ThreeLayerCollectionViewController.swift in Sources */,
|
||||
|
||||
36
MVMCoreUI/Alerts/MVMCoreAlertDelegateProtocol.h
Normal file
36
MVMCoreUI/Alerts/MVMCoreAlertDelegateProtocol.h
Normal file
@ -0,0 +1,36 @@
|
||||
//
|
||||
// MVMCoreAlertDelegateProtocol.h
|
||||
// mobilefirst
|
||||
//
|
||||
// Created by Pfeil, Scott Robert on 8/8/17.
|
||||
// Copyright © 2017 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
// Called for popup style alerts.
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
@class MVMCoreAlertObject;
|
||||
@class MVMCoreLoadObject;
|
||||
@class MVMCoreErrorObject;
|
||||
|
||||
@protocol MVMCoreAlertDelegateProtocol
|
||||
|
||||
@optional
|
||||
|
||||
// helps tracking alert state
|
||||
- (nullable NSDictionary *)additionalAlertDataToTrackForAlertWithObject:(nullable MVMCoreAlertObject *)alertObject;
|
||||
|
||||
// All are performed on the main thread.
|
||||
- (void)alertShown:(nonnull UIAlertController *)alertController;
|
||||
- (void)alertCancelled:(nonnull UIAlertController *)alertController;
|
||||
- (void)alertDismissed:(nonnull UIAlertController *)alertController;
|
||||
- (void)alertPaused:(nonnull UIAlertController *)alertController;
|
||||
- (void)alertUnpaused:(nonnull UIAlertController *)alertController;
|
||||
|
||||
/** Get the alert object whose data will be presented. Overwrite this to alter how you want the alert to show.
|
||||
* @param loadObject The load object.
|
||||
* @param errorObject An error object if there was an error.
|
||||
* @return Returns the alert object.
|
||||
* Details: Gets the alert that will display to the screen. Easier to subclass here to avoid subclassing the displaying logic. */
|
||||
- (nullable MVMCoreAlertObject *)alertObjectToShow:(nonnull MVMCoreLoadObject *)loadObject error:(nullable MVMCoreErrorObject *)errorObject;
|
||||
|
||||
@end
|
||||
95
MVMCoreUI/Alerts/MVMCoreAlertHandler+Extension.swift
Normal file
95
MVMCoreUI/Alerts/MVMCoreAlertHandler+Extension.swift
Normal file
@ -0,0 +1,95 @@
|
||||
//
|
||||
// MVMCoreAlertHandler+Extension.swift
|
||||
// MVMCore
|
||||
//
|
||||
// Created by Scott Pfeil on 9/15/20.
|
||||
// Copyright © 2020 myverizon. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
// Temporary, until we can move page checking logic into isReady of topAlertOperation.
|
||||
@objcMembers public class NotificationPagesOperation: Operation {
|
||||
public let pages: [String]
|
||||
|
||||
public init(with pages: [String]) {
|
||||
self.pages = pages
|
||||
}
|
||||
|
||||
public override var isReady: Bool {
|
||||
get {
|
||||
return super.isReady && isCancelled
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Move this type of logic into isReady for the top alert operation... then can remove this dependency operation.
|
||||
public extension MVMCoreAlertHandler {
|
||||
|
||||
/// Adds a page type dependency to the operation
|
||||
@objc func addPagesDependency(to operation: MVMCoreTopAlertOperation) {
|
||||
// This notification may only show for certain pages.
|
||||
guard let pages = operation.topAlertObject.json?.optionalArrayForKey("pages") as? [String],
|
||||
pages.count > 0 else { return }
|
||||
let pagesOperation = NotificationPagesOperation(with: pages)
|
||||
pageOperations.addOperation(pagesOperation)
|
||||
operation.addDependency(pagesOperation)
|
||||
}
|
||||
|
||||
/// Updates the pages requirement for the operation
|
||||
@objc func updatePages(for operation: MVMCoreTopAlertOperation, with topAlertObject: MVMCoreTopAlertObject) {
|
||||
// Add new dependencies, remove old.
|
||||
let previousPages = operation.dependencies.filter { $0 as? NotificationPagesOperation != nil }
|
||||
addPagesDependency(to: operation)
|
||||
for pageOperation in previousPages {
|
||||
pageOperation.cancel()
|
||||
operation.removeDependency(pageOperation)
|
||||
}
|
||||
}
|
||||
|
||||
/// Handles page dependencies for all top alerts with the new pageType
|
||||
@objc func handleAllPagesDependency(for pageType: String?) {
|
||||
var currentOperation: MVMCoreTopAlertOperation? = nil
|
||||
for case let operation as MVMCoreTopAlertOperation in topAlertQueue.operations {
|
||||
// Handle the currently executing opration last to avoid race conditions.
|
||||
guard !operation.isExecuting else {
|
||||
currentOperation = operation
|
||||
continue
|
||||
}
|
||||
handlePageDependency(for: operation, with: pageType)
|
||||
}
|
||||
if let operation = currentOperation {
|
||||
handlePageDependency(for: operation, with: pageType)
|
||||
}
|
||||
}
|
||||
|
||||
/// Updates the operation based on the page type and its dependencies.
|
||||
@objc func handlePageDependency(for operation: MVMCoreTopAlertOperation, with pageType: String?) {
|
||||
guard !operation.isCancelled else { return }
|
||||
|
||||
if let pages = operation.topAlertObject.json?.optionalArrayForKey("pages") as? [String],
|
||||
pages.count > 0,
|
||||
(pageType == nil || !pages.contains(pageType!)) {
|
||||
if let dependency = operation.dependencies.first(where: { $0.isFinished && ($0 as? NotificationPagesOperation)?.pages == pages }) {
|
||||
// Re-add the dependency if it was previously cancelled.
|
||||
let pagesOperation = NotificationPagesOperation(with: pages)
|
||||
pageOperations.addOperation(pagesOperation)
|
||||
operation.addDependency(pagesOperation)
|
||||
operation.removeDependency(dependency)
|
||||
}
|
||||
if operation.isExecuting {
|
||||
// If the current running operation should not show on the current page, cancel it. If it's persistent, re-add it
|
||||
operation.reAddAfterCancel = operation.topAlertObject.persistent
|
||||
operation.cancel()
|
||||
}
|
||||
}
|
||||
|
||||
// Cancel any dependency if it contains the current page.
|
||||
guard let pageType = pageType else { return }
|
||||
for case let operation as NotificationPagesOperation in operation.dependencies {
|
||||
if operation.pages.contains(pageType) {
|
||||
operation.cancel()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
119
MVMCoreUI/Alerts/MVMCoreAlertHandler.h
Normal file
119
MVMCoreUI/Alerts/MVMCoreAlertHandler.h
Normal file
@ -0,0 +1,119 @@
|
||||
//
|
||||
// MVMCoreAlertHandler.h
|
||||
// myverizon
|
||||
//
|
||||
// Created by Scott Pfeil on 3/10/14.
|
||||
// Copyright (c) 2014 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
// Keeps track of alerts and handles them. Should always use this to present alerts in mf.
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <MVMCoreUI/MVMCoreTopAlertObject.h>
|
||||
#import <MVMCoreUI/MVMCoreAlertDelegateProtocol.h>
|
||||
|
||||
@class MVMCoreAlertObject;
|
||||
@class MVMCoreTopAlertOperation;
|
||||
|
||||
@interface MVMCoreAlertHandler : NSObject
|
||||
|
||||
// An operation queue for displaying popup alerts.
|
||||
@property (nonnull, strong, nonatomic) NSOperationQueue *popupAlertQueue;
|
||||
|
||||
// An operation queue for top alerts
|
||||
@property (nonnull, strong, nonatomic) NSOperationQueue *topAlertQueue;
|
||||
|
||||
/// Stores any page dependencies for top alerts
|
||||
@property (nonnull, strong, nonatomic) NSOperationQueue *pageOperations;
|
||||
|
||||
/// Returns the shared instance of this singleton
|
||||
+ (nullable instancetype)sharedAlertHandler;
|
||||
|
||||
#pragma mark - Popup Alert Functions
|
||||
|
||||
/// Returns if any alert is currently showing (even if supressed).
|
||||
- (BOOL)alertCurrentlyShowing;
|
||||
|
||||
/// Returns if a greedy alert is currently showing (even if supressed).
|
||||
- (BOOL)greedyAlertShowing;
|
||||
|
||||
/** Shows the popup with the passed in parameter.
|
||||
* @param title The title of the alert.
|
||||
* @param message The message of the alert.
|
||||
* @param actions An array of actions for the alert.
|
||||
* @param isGreedy Sets up a greedy popup. In other words, any popups currently shown or queued are dismissed.
|
||||
* @return Returns the UIAlertController.
|
||||
*/
|
||||
- (nonnull UIAlertController *)showAlertWithTitle:(nullable NSString *)title message:(nullable NSString *)message actions:(nullable NSArray<UIAlertAction *>*)actions isGreedy:(BOOL)isGreedy;
|
||||
|
||||
/** Shows the alert.
|
||||
* @param title The title of the alert.
|
||||
* @param message The message of the alert.
|
||||
* @param actions An array of actions for the alert.
|
||||
* @param alertStyle Popup or action sheet
|
||||
* @param isGreedy Sets up a greedy alert. In other words, any alerts currently shown or queued are dismissed.
|
||||
* @param alertDelegate The delegate to be notified.
|
||||
* @return Returns the UIAlertController.
|
||||
*/
|
||||
- (nonnull UIAlertController *)showAlertWithTitle:(nullable NSString *)title message:(nullable NSString *)message actions:(nullable NSArray<UIAlertAction *>*)actions alertStyle:(UIAlertControllerStyle)alertStyle isGreedy:(BOOL)isGreedy alertDelegate:(nullable NSObject <MVMCoreAlertDelegateProtocol>*)alertDelegate;
|
||||
|
||||
/** Shows the popup with the passed in alert object. This is a convenience method that automatically handles using the proper alert type based on what's available.
|
||||
* @param alertObject The alert object to use for the alert.
|
||||
* @return Returns UIAlertController.
|
||||
*/
|
||||
- (nonnull UIAlertController *)showAlertWithAlertObject:(nonnull MVMCoreAlertObject *)alertObject;
|
||||
|
||||
/** Cancels and removes an alert operation for the given alertObject.
|
||||
* @param alertObject The alertObject scheduled to be shown.
|
||||
*/
|
||||
- (void)removeAlertViewForObject:(nonnull MVMCoreAlertObject *)alertObject;
|
||||
|
||||
/** Iterates through all scheduled alerts and cancels any that match the provided predicate.
|
||||
* @param predicate The predicate block to decide whether to cancel an alert.
|
||||
*/
|
||||
- (void)removeAlertViewUsingPredicate:(BOOL(^_Nonnull)(MVMCoreAlertObject * _Nonnull obj))predicate;
|
||||
|
||||
/// Removes all alerts.
|
||||
- (void)removeAllAlertViews;
|
||||
|
||||
#pragma mark - Supression Functions
|
||||
|
||||
/// Returns true if alerts are supressed.
|
||||
- (BOOL)mfAlertsSupressed;
|
||||
|
||||
/// Supresses the alerts (Used by other "apps" in our app).
|
||||
- (void)supressMFAlerts;
|
||||
|
||||
/// Unsupresses the alerts (Used by other "apps" in our app).
|
||||
- (void)unSupressMFAlerts;
|
||||
|
||||
#pragma mark - Top Alert Functions
|
||||
|
||||
/// Show based on the object. Will be used by the architecture. Creates an operation and calls addTopAlertOperation.
|
||||
- (void)showTopAlertWithObject:(nullable MVMCoreTopAlertObject *)topAlertObject;
|
||||
|
||||
/// Adds the top alert operation to the queue.
|
||||
- (void)addTopAlertOperation:(nonnull MVMCoreTopAlertOperation *)topAlertOperation;
|
||||
|
||||
/// Convenience functions
|
||||
- (void)showTopAlertErrorWithMessage:(nullable NSString *)message;
|
||||
- (void)showTopAlertConfirmationWithMessage:(nullable NSString *)message;
|
||||
- (void)showTopAlertWithType:(nullable NSString *)type message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage persistent:(BOOL)persistent actionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData;
|
||||
- (void)showTopAlertWithType:(nullable NSString *)type message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage persistent:(BOOL)persistent buttonTitle:(nullable NSString *)buttonTitle userActionHandler:(nullable void (^)(id _Nonnull sender))userActionHandler;
|
||||
|
||||
/// Hides the current alert view.
|
||||
- (void)hideTopAlertView;
|
||||
|
||||
/// Hides a persistent alert based on the type string.
|
||||
- (void)hidePersistentTopAlertViewOfType:(nullable NSString *)type;
|
||||
|
||||
/// Removes a scheduled top alert given its top alert object.
|
||||
- (void)removeTopAlertForObject:(nonnull MVMCoreTopAlertObject *)topAlertObject;
|
||||
|
||||
/// Removes all top alerts.
|
||||
- (void)removeAllTopAlerts;
|
||||
|
||||
/// Returns YES if the persistent type is already registered in the alert queue.
|
||||
- (BOOL)hasPersistentTopAlertOfType:(nullable NSString *)type;
|
||||
|
||||
@end
|
||||
262
MVMCoreUI/Alerts/MVMCoreAlertHandler.m
Normal file
262
MVMCoreUI/Alerts/MVMCoreAlertHandler.m
Normal file
@ -0,0 +1,262 @@
|
||||
//
|
||||
// MVMCoreAlertHandler.m
|
||||
// myverizon
|
||||
//
|
||||
// Created by Scott Pfeil on 3/10/14.
|
||||
// Copyright (c) 2014 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
#import "MVMCoreAlertHandler.h"
|
||||
#import "MVMCoreAlertObject.h"
|
||||
#import <MVMCore/MVMCoreAlertController.h>
|
||||
#import "MVMCoreAlertOperation.h"
|
||||
#import "MVMCoreTopAlertOperation.h"
|
||||
#import <MVMCore/MVMCoreJSONConstants.h>
|
||||
#import <MVMCore/NSDictionary+MFConvenience.h>
|
||||
#import <MVMCore/NSArray+MFConvenience.h>
|
||||
#import <MVMCore/MVMCore-Swift.h>
|
||||
|
||||
@interface MVMCoreAlertHandler ()
|
||||
|
||||
// Flag that keeps track of if the alerts are supressed or not.
|
||||
@property (assign, nonatomic) BOOL mfAlertsSupressed;
|
||||
|
||||
@end
|
||||
|
||||
@implementation MVMCoreAlertHandler
|
||||
|
||||
+ (instancetype)sharedAlertHandler {
|
||||
static dispatch_once_t once;
|
||||
static id sharedInstance;
|
||||
|
||||
dispatch_once(&once, ^{
|
||||
sharedInstance = [[self alloc] init];
|
||||
});
|
||||
|
||||
return sharedInstance;
|
||||
}
|
||||
|
||||
- (nullable instancetype)init {
|
||||
if (self = [super init]) {
|
||||
self.popupAlertQueue = [[NSOperationQueue alloc] init];
|
||||
self.popupAlertQueue.maxConcurrentOperationCount = 1;
|
||||
self.topAlertQueue = [[NSOperationQueue alloc] init];
|
||||
self.topAlertQueue.maxConcurrentOperationCount = 1;
|
||||
self.pageOperations = [[NSOperationQueue alloc] init];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
#pragma mark - Popup Alert Functions
|
||||
|
||||
- (BOOL)alertCurrentlyShowing {
|
||||
return (self.popupAlertQueue.operationCount > 0);
|
||||
}
|
||||
|
||||
- (BOOL)greedyAlertShowing {
|
||||
if ([self alertCurrentlyShowing]) {
|
||||
NSInteger index = [self.popupAlertQueue.operations indexOfObjectPassingTest:^BOOL(__kindof MVMCoreAlertOperation * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
|
||||
if (obj.isExecuting && obj.isGreedy && stop) {
|
||||
*stop = YES;
|
||||
return YES;
|
||||
} else {
|
||||
return NO;
|
||||
}
|
||||
}];
|
||||
return (index != NSNotFound);
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (nonnull UIAlertController *)showAlertWithTitle:(nullable NSString *)title message:(nullable NSString *)message actions:(nullable NSArray<UIAlertAction *>*)actions isGreedy:(BOOL)isGreedy {
|
||||
return [self showAlertWithTitle:title message:message actions:actions isGreedy:isGreedy alertDelegate:nil];
|
||||
}
|
||||
|
||||
- (nonnull UIAlertController *)showAlertWithTitle:(nullable NSString *)title message:(nullable NSString *)message actions:(nullable NSArray<UIAlertAction *>*)actions isGreedy:(BOOL)isGreedy alertDelegate:(nullable NSObject <MVMCoreAlertDelegateProtocol>*)alertDelegate {
|
||||
return [self showAlertWithTitle:title message:message actions:actions alertStyle:UIAlertControllerStyleAlert isGreedy:isGreedy alertDelegate:alertDelegate];
|
||||
}
|
||||
|
||||
- (nonnull UIAlertController *)showAlertWithTitle:(nullable NSString *)title message:(nullable NSString *)message actions:(nullable NSArray<UIAlertAction *>*)actions alertStyle:(UIAlertControllerStyle)alertStyle isGreedy:(BOOL)isGreedy alertDelegate:(nullable NSObject <MVMCoreAlertDelegateProtocol>*)alertDelegate {
|
||||
|
||||
// It's a greedy alert! Clear all alerts that are queued up and the one that is showing
|
||||
if (isGreedy) {
|
||||
[self removeAllAlertViews];
|
||||
}
|
||||
|
||||
// Create the alert. Adds the actions one by one.
|
||||
MVMCoreAlertController *alertController = [MVMCoreAlertController alertControllerWithTitle:(title ?: @"") message:message preferredStyle:alertStyle];
|
||||
for (NSUInteger i = 0; i < [actions count]; i++) {
|
||||
UIAlertAction *action = [actions objectAtIndex:i ofType:[UIAlertAction class]];
|
||||
if (action) {
|
||||
[alertController addAction:action];
|
||||
}
|
||||
}
|
||||
|
||||
MVMCoreAlertOperation *alertOperation = [[MVMCoreAlertOperation alloc] initWithAlert:alertController isGreedy:isGreedy alertDelegate:alertDelegate];
|
||||
[self.popupAlertQueue addOperation:alertOperation];
|
||||
return alertController;
|
||||
}
|
||||
|
||||
- (nonnull UIAlertController *)showAlertWithAlertObject:(nonnull MVMCoreAlertObject *)alertObject {
|
||||
MVMCoreAlertController *controller = (MVMCoreAlertController *)[self showAlertWithTitle:alertObject.title message:alertObject.message actions:alertObject.actions alertStyle:alertObject.alertStyle isGreedy:alertObject.isGreedy alertDelegate:alertObject.alertDelegate];
|
||||
controller.alertObject = alertObject;
|
||||
return controller;
|
||||
}
|
||||
|
||||
- (void)removeAlertViewForObject:(MVMCoreAlertObject *)alertObject {
|
||||
for (MVMCoreAlertOperation *operation in self.popupAlertQueue.operations) {
|
||||
if ([operation.currentAlertView isKindOfClass:[MVMCoreAlertController class]] && [(MVMCoreAlertController *)operation.currentAlertView alertObject] == alertObject) {
|
||||
[operation cancel];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)removeAlertViewUsingPredicate:(BOOL(^)(MVMCoreAlertObject *obj))predicate {
|
||||
for (MVMCoreAlertOperation *operation in self.popupAlertQueue.operations) {
|
||||
if ([operation.currentAlertView isKindOfClass:[MVMCoreAlertController class]]) {
|
||||
MVMCoreAlertObject *alertObject = [(MVMCoreAlertController *)operation.currentAlertView alertObject];
|
||||
if (alertObject && predicate(alertObject)) {
|
||||
[operation cancel];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)removeAllAlertViews {
|
||||
[self.popupAlertQueue cancelAllOperations];
|
||||
}
|
||||
|
||||
#pragma mark - Supression Functions
|
||||
|
||||
- (BOOL)mfAlertsSupressed {
|
||||
return _mfAlertsSupressed;
|
||||
}
|
||||
|
||||
- (void)supressMFAlerts {
|
||||
if (!self.mfAlertsSupressed) {
|
||||
self.mfAlertsSupressed = YES;
|
||||
for (MVMCoreAlertOperation *operation in self.popupAlertQueue.operations) {
|
||||
[operation pause];
|
||||
}
|
||||
for (MVMCoreTopAlertOperation *operation in self.topAlertQueue.operations) {
|
||||
[operation pause];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)unSupressMFAlerts {
|
||||
if (self.mfAlertsSupressed) {
|
||||
self.mfAlertsSupressed = NO;
|
||||
for (MVMCoreAlertOperation *operation in self.popupAlertQueue.operations) {
|
||||
[operation unpause];
|
||||
}
|
||||
for (MVMCoreTopAlertOperation *operation in self.topAlertQueue.operations) {
|
||||
[operation unpause];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Top Alert Functions
|
||||
|
||||
- (void)addTopAlertOperation:(nonnull MVMCoreTopAlertOperation *)topAlertOperation {
|
||||
__block MVMCoreTopAlertOperation *alertOperation = topAlertOperation;
|
||||
__weak typeof(self) weakSelf = self;
|
||||
[alertOperation setCompletionBlock:^{
|
||||
|
||||
// If the alert was cancelled to show another with higher priority, re-add to the operation when cancelled to the queue.
|
||||
if (alertOperation.reAddAfterCancel) {
|
||||
MVMCoreTopAlertOperation *newOperation = [alertOperation copy];
|
||||
newOperation.reAddAfterCancel = NO;
|
||||
[weakSelf addTopAlertOperation:newOperation];
|
||||
}
|
||||
alertOperation = nil;
|
||||
}];
|
||||
|
||||
[self.topAlertQueue addOperation:alertOperation];
|
||||
|
||||
// If the current running operation is persistent and has a lower queue priority then the added operation, cancel it and re-add it.
|
||||
for (MVMCoreTopAlertOperation *operation in self.topAlertQueue.operations) {
|
||||
|
||||
if (operation.isExecuting && !operation.isCancelled && operation.topAlertObject.persistent && operation.queuePriority < alertOperation.queuePriority && alertOperation.isReady) {
|
||||
operation.reAddAfterCancel = YES;
|
||||
[operation cancel];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)showTopAlertWithObject:(nullable MVMCoreTopAlertObject *)topAlertObject {
|
||||
MVMCoreTopAlertOperation *alertOperation = [[MVMCoreTopAlertOperation alloc] initWithTopAlertObject:topAlertObject];
|
||||
[self addTopAlertOperation:alertOperation];
|
||||
}
|
||||
|
||||
- (void)showTopAlertErrorWithMessage:(nullable NSString *)message {
|
||||
|
||||
MVMCoreTopAlertObject *topAlertObject = [[MVMCoreTopAlertObject alloc] initWithType:ValueTypeError message:message];
|
||||
[self showTopAlertWithObject:topAlertObject];
|
||||
}
|
||||
|
||||
- (void)showTopAlertConfirmationWithMessage:(nullable NSString *)message {
|
||||
|
||||
MVMCoreTopAlertObject *topAlertObject = [[MVMCoreTopAlertObject alloc] initWithType:ValueTypeSuccess message:message];
|
||||
[self showTopAlertWithObject:topAlertObject];
|
||||
}
|
||||
|
||||
- (void)showTopAlertWithType:(nullable NSString *)type message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage persistent:(BOOL)persistent actionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData {
|
||||
|
||||
MVMCoreTopAlertObject *topAlertObject = [[MVMCoreTopAlertObject alloc] initWithType:type message:message subMessage:subMessage persistent:persistent actionMap:actionMap additionalData:additionalData];
|
||||
[self showTopAlertWithObject:topAlertObject];
|
||||
}
|
||||
|
||||
- (void)showTopAlertWithType:(nullable NSString *)type message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage persistent:(BOOL)persistent buttonTitle:(nullable NSString *)buttonTitle userActionHandler:(nullable void (^)(id _Nonnull sender))userActionHandler {
|
||||
|
||||
MVMCoreTopAlertObject *topAlertObject = [[MVMCoreTopAlertObject alloc] initWithType:type message:message subMessage:subMessage persistent:persistent buttonTitle:buttonTitle userActionHandler:userActionHandler];
|
||||
[self showTopAlertWithObject:topAlertObject];
|
||||
}
|
||||
|
||||
- (void)hideTopAlertView {
|
||||
|
||||
MVMCoreTopAlertOperation *currentOperation = [self.topAlertQueue.operations firstObject];
|
||||
currentOperation.topAlertObject.persistent = NO;
|
||||
currentOperation.reAddAfterCancel = NO;
|
||||
[currentOperation cancel];
|
||||
}
|
||||
|
||||
- (BOOL)hasPersistentTopAlertOfType:(nullable NSString *)type {
|
||||
BOOL hasAlert = NO;
|
||||
for (MVMCoreTopAlertOperation *operation in self.topAlertQueue.operations) {
|
||||
if (operation.topAlertObject.persistent && [operation.topAlertObject.type isEqualToString:type]) {
|
||||
hasAlert = YES;
|
||||
}
|
||||
}
|
||||
return hasAlert;
|
||||
}
|
||||
|
||||
- (void)hidePersistentTopAlertViewOfType:(nullable NSString *)type {
|
||||
if (type) {
|
||||
for (MVMCoreTopAlertOperation *operation in self.topAlertQueue.operations) {
|
||||
|
||||
// Cancel all persistent operations of this type.
|
||||
if (operation.topAlertObject.persistent && [operation.topAlertObject.type isEqualToString:type]) {
|
||||
operation.reAddAfterCancel = NO;
|
||||
[operation cancel];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)removeTopAlertForObject:(MVMCoreTopAlertObject *)topAlertObject {
|
||||
for (MVMCoreTopAlertOperation *operation in self.topAlertQueue.operations) {
|
||||
// Finds an cancels top alerts associated with the object.
|
||||
if (operation.topAlertObject == topAlertObject) {
|
||||
operation.reAddAfterCancel = NO;
|
||||
[operation cancel];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)removeAllTopAlerts {
|
||||
[self.topAlertQueue cancelAllOperations];
|
||||
}
|
||||
|
||||
@end
|
||||
45
MVMCoreUI/Alerts/MVMCoreAlertObject+Swift.swift
Normal file
45
MVMCoreUI/Alerts/MVMCoreAlertObject+Swift.swift
Normal file
@ -0,0 +1,45 @@
|
||||
//
|
||||
// MVMCoreAlertObject+Swift.swift
|
||||
// MVMCore
|
||||
//
|
||||
// Created by Suresh, Kamlesh on 7/10/20.
|
||||
// Copyright © 2020 myverizon. All rights reserved.
|
||||
//
|
||||
|
||||
|
||||
public extension MVMCoreAlertObject {
|
||||
|
||||
@objc static func alertObjectWith(action actionJson: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?, delegateObject: DelegateObject?, error: AutoreleasingUnsafeMutablePointer<MVMCoreErrorObject?>?) -> MVMCoreAlertObject? {
|
||||
|
||||
guard let alertJson = actionJson?.optionalDictionaryForKey("alert"),
|
||||
(alertJson.optionalStringForKey(KeyTitle) != nil || alertJson.optionalStringForKey(KeyMessage) != nil),
|
||||
let actionsList = alertJson.optionalArrayForKey("alertActions") as? [[AnyHashable: Any]]
|
||||
else {
|
||||
error?.pointee = MVMCoreErrorObject(title: nil, message: MVMCoreGetterUtility.hardcodedString(withKey: HardcodedErrorUnableToProcess), code: ErrorCode.popupFailed.rawValue, domain: ErrorDomainNative, location: String(describing: self))
|
||||
return nil
|
||||
}
|
||||
|
||||
var actionsForAlert: [UIAlertAction] = []
|
||||
|
||||
for actionJson in actionsList {
|
||||
let style = UIAlertAction.Style(rawValue: actionJson.stringForkey("style"))
|
||||
let alertAction = UIAlertAction(title: actionJson.optionalStringForKey(KeyTitle), style: style) { action in
|
||||
MVMCoreActionHandler.shared()?.handleAction(with: actionJson.optionalDictionaryForKey("action"),
|
||||
additionalData: additionalData,
|
||||
delegateObject: delegateObject)
|
||||
}
|
||||
actionsForAlert.append(alertAction)
|
||||
}
|
||||
|
||||
let alertObject = MVMCoreAlertObject(popupAlertWithTitle: alertJson.optionalStringForKey(KeyTitle),
|
||||
message: alertJson.optionalStringForKey(KeyMessage),
|
||||
actions: actionsForAlert,
|
||||
isGreedy: false)
|
||||
|
||||
if let alertStyle = alertJson.optionalStringForKey("style") {
|
||||
alertObject?.alertStyle = UIAlertController.Style(rawValue: alertStyle)
|
||||
}
|
||||
|
||||
return alertObject
|
||||
}
|
||||
}
|
||||
72
MVMCoreUI/Alerts/MVMCoreAlertObject.h
Normal file
72
MVMCoreUI/Alerts/MVMCoreAlertObject.h
Normal file
@ -0,0 +1,72 @@
|
||||
//
|
||||
// MVMCoreAlertObject.h
|
||||
// myverizon
|
||||
//
|
||||
// Created by Scott Pfeil on 11/21/14.
|
||||
// Copyright (c) 2014 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
// An object for keeping track of all alert variables. Easier to pass around.
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <MVMCore/MVMCoreActionDelegateProtocol.h>
|
||||
#import <MVMCore/MVMCoreLoadDelegateProtocol.h>
|
||||
#import <MVMCore/MVMCorePresentationDelegateProtocol.h>
|
||||
#import <MVMCoreUI/MVMCoreAlertDelegateProtocol.h>
|
||||
|
||||
@class MVMCoreErrorObject;
|
||||
@class MVMCoreLoadObject;
|
||||
@class DelegateObject;
|
||||
|
||||
typedef NS_ENUM(NSInteger, MFAlertType) {
|
||||
MFAlertTypePopup = 0,
|
||||
MFAlertTypeField,
|
||||
MFAlertTypeTop,
|
||||
MFAlertTypeNone
|
||||
};
|
||||
|
||||
typedef void (^TextFieldErrorHandler)(NSArray * _Nonnull fieldErrors);
|
||||
|
||||
@interface MVMCoreAlertObject : NSObject
|
||||
|
||||
@property (nullable, strong, nonatomic) NSString *title;
|
||||
@property (nullable, copy, nonatomic) NSDictionary *pageJson;
|
||||
@property (nullable, strong, nonatomic) NSString *message;
|
||||
@property (nonnull, strong, nonatomic) NSArray *actions;
|
||||
@property (nonatomic) BOOL isGreedy;
|
||||
@property (nonatomic) UIAlertControllerStyle alertStyle;
|
||||
@property (nonatomic) MFAlertType type;
|
||||
@property (nonatomic) BOOL defaultAction;
|
||||
|
||||
@property (nonnull, strong, nonatomic) NSArray *fieldErrors;
|
||||
@property (nullable, nonatomic, copy) TextFieldErrorHandler textFieldErrorHandler;
|
||||
|
||||
// Set to be notified of popup style alert events.
|
||||
@property (nonatomic, weak, nullable) NSObject <MVMCoreAlertDelegateProtocol> *alertDelegate;
|
||||
|
||||
// Creates an alert object for an error with the passed in load object response info
|
||||
+ (nullable instancetype)alertObjectForLoadObject:(nullable MVMCoreLoadObject *)loadObject error:(nullable MVMCoreErrorObject *)error delegateObject:(nullable DelegateObject *)delegateObject;
|
||||
+ (nullable instancetype)alertObjectForPageType:(nullable NSString *)pageType responseInfo:(nullable NSDictionary *)responseInfo additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject;
|
||||
|
||||
// Initializes a popup style alert object. Look at the alert handler to see what each is used for.
|
||||
- (nullable instancetype)initPopupAlertWithTitle:(nullable NSString *)title message:(nullable NSString *)message actions:(nonnull NSArray *)actions isGreedy:(BOOL)isGreedy;
|
||||
|
||||
// Initializes a popup style alert object using the error passed in. Message is formatted default style. By defualt uses the Okay button to just dismiss the error.
|
||||
- (nullable instancetype)initPopupAlertWithError:(nullable MVMCoreErrorObject *)error isGreedy:(BOOL)isGreedy;
|
||||
|
||||
// Same as above but no default actions. They are passed in.
|
||||
- (nullable instancetype)initPopupAlertWithError:(nullable MVMCoreErrorObject *)error actions:(nonnull NSArray *)actions isGreedy:(BOOL)isGreedy;
|
||||
|
||||
// Returns the alert object made with the page json. If there is not enough data to make, we will set error
|
||||
+ (nullable instancetype)alertObjectWithPage:(nullable NSDictionary *)page isGreedy:(BOOL)isGreedy additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject error:(MVMCoreErrorObject *_Nullable *_Nullable)error;
|
||||
|
||||
// Will show this alert in it's appropriate type style.
|
||||
- (void)showAlert;
|
||||
|
||||
#pragma mark - Deprecated
|
||||
|
||||
// Creates an alert object for an error with the passed in load object response info
|
||||
+ (nullable instancetype)alertObjectForLoadObject:(nullable MVMCoreLoadObject *)loadObject error:(nullable MVMCoreErrorObject *)error actionDelegate:(nullable NSObject <MVMCoreLoadDelegateProtocol,MVMCorePresentationDelegateProtocol,MVMCoreActionDelegateProtocol>*)actionDelegate __deprecated;
|
||||
+ (nullable instancetype)alertObjectForPageType:(nullable NSString *)pageType responseInfo:(nullable NSDictionary *)responseInfo additionalData:(nullable NSDictionary *)additionalData actionDelegate:(nullable NSObject <MVMCoreLoadDelegateProtocol,MVMCorePresentationDelegateProtocol,MVMCoreActionDelegateProtocol>*)actionDelegate __deprecated;
|
||||
+ (nullable instancetype)alertObjectWithPage:(nullable NSDictionary *)page isGreedy:(BOOL)isGreedy additionalData:(nullable NSDictionary *)additionalData delegate:(nullable NSObject <MVMCoreLoadDelegateProtocol,MVMCorePresentationDelegateProtocol,MVMCoreActionDelegateProtocol>*)delegate error:(MVMCoreErrorObject *_Nullable *_Nullable)error __deprecated;
|
||||
|
||||
@end
|
||||
308
MVMCoreUI/Alerts/MVMCoreAlertObject.m
Normal file
308
MVMCoreUI/Alerts/MVMCoreAlertObject.m
Normal file
@ -0,0 +1,308 @@
|
||||
//
|
||||
// MVMCoreAlertObject.m
|
||||
// myverizon
|
||||
//
|
||||
// Created by Scott Pfeil on 11/21/14.
|
||||
// Copyright (c) 2014 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
#import "MVMCoreAlertObject.h"
|
||||
#import "MVMCoreAlertHandler.h"
|
||||
#import "MVMCoreTopAlertObject.h"
|
||||
#import <MVMCore/MVMCoreCache.h>
|
||||
#import <MVMCore/MVMCoreErrorConstants.h>
|
||||
#import <MVMCore/MVMCoreErrorObject.h>
|
||||
#import <MVMCore/MVMCoreLoadObject.h>
|
||||
#import <MVMCore/MVMCoreGetterUtility.h>
|
||||
#import <MVMCore/NSDictionary+MFConvenience.h>
|
||||
#import <MVMCore/MVMCoreHardcodedStringsConstants.h>
|
||||
#import <MVMCore/MVMCoreJSONConstants.h>
|
||||
#import <MVMCore/MVMCoreActionHandler.h>
|
||||
#import <MVMCore/MVMCore-Swift.h>
|
||||
#import <MVMCoreUI/MVMCoreUI-Swift.h>
|
||||
|
||||
@interface MVMCoreAlertObject ()
|
||||
|
||||
@property (strong, nonatomic) MVMCoreLoadObject *loadObject;
|
||||
@property (nullable, strong, nonatomic) NSString *systemDomain;
|
||||
@property (nullable, strong, nonatomic) MVMCoreTopAlertObject *topAlertObject;
|
||||
@end
|
||||
|
||||
@implementation MVMCoreAlertObject
|
||||
|
||||
+ (nullable instancetype)alertObjectForLoadObject:(nullable MVMCoreLoadObject *)loadObject error:(nullable MVMCoreErrorObject *)error delegateObject:(nullable DelegateObject *)delegateObject {
|
||||
|
||||
MVMCoreAlertObject *alert = nil;
|
||||
if (!error || [ErrorDomainServer isEqualToString:error.domain]) {
|
||||
alert = [MVMCoreAlertObject alertObjectForPageType:loadObject.pageType responseInfo:loadObject.responseInfoMap additionalData:loadObject.dataForPage delegateObject:delegateObject];
|
||||
} else {
|
||||
alert = [[MVMCoreAlertObject alloc] initPopupAlertWithError:error isGreedy:NO];
|
||||
}
|
||||
|
||||
// only if actions are empty, then go inside and set OK as default action
|
||||
if (alert.type == MFAlertTypePopup && alert.actions.count == 0) {
|
||||
alert.defaultAction = YES;
|
||||
alert.actions = @[[UIAlertAction actionWithTitle:[MVMCoreGetterUtility hardcodedStringWithKey:HardcodedOK] style:UIAlertActionStyleDefault handler:nil]];
|
||||
}
|
||||
return alert;
|
||||
}
|
||||
|
||||
+ (nullable instancetype)alertObjectForPageType:(nullable NSString *)pageType responseInfo:(nullable NSDictionary *)responseInfo additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject {
|
||||
MVMCoreUIDelegateObject *alertDelegateObject = nil;
|
||||
if ([delegateObject isKindOfClass:[MVMCoreUIDelegateObject class]]) {
|
||||
alertDelegateObject = (MVMCoreUIDelegateObject *)delegateObject;
|
||||
}
|
||||
|
||||
__block MVMCoreAlertObject *alert = [[MVMCoreAlertObject alloc] init];
|
||||
alert.title = [responseInfo stringForKey:KeyErrorHeading];
|
||||
alert.message = [responseInfo stringForKey:KeyUserMessage];
|
||||
|
||||
NSString *messageStyle = [responseInfo stringForKey:KeyMessageStyle];
|
||||
if ([ValueTypeFieldErrors isEqualToString:[responseInfo string:KeyType]]) {
|
||||
|
||||
// field errors.
|
||||
alert.type = MFAlertTypeField;
|
||||
alert.fieldErrors = [responseInfo array:ValueTypeFieldErrors];
|
||||
} else {
|
||||
|
||||
// Check for top alert (persistent or regular).
|
||||
if ([messageStyle isEqualToString:ValueMessageStyleTopPersistent] || [messageStyle isEqualToString:ValueMessageStyleTop]) {
|
||||
|
||||
alert.topAlertObject = [[MVMCoreTopAlertObject alloc] initWithResponseInfo:responseInfo];
|
||||
alert.topAlertObject.delegate = alertDelegateObject.topAlertDelegate;
|
||||
alert.topAlertObject.pageType = pageType;
|
||||
alert.type = MFAlertTypeTop;
|
||||
} else if ([messageStyle isEqualToString:ValueMessageStylePopup]) {
|
||||
|
||||
// Perform a popup.
|
||||
alert.type = MFAlertTypePopup;
|
||||
alert.alertStyle = UIAlertControllerStyleAlert;
|
||||
|
||||
// Check if we have a popup driven by page object (otherwise by default it will just use response info title message with an OK button).
|
||||
NSString *pageTypeForPopup = [responseInfo stringForKey:@"popupPageType"];
|
||||
[[MVMCoreCache sharedCache] fetchJSONForPageType:pageTypeForPopup queue:nil waitUntilFinished:YES completionHandler:^(NSDictionary * _Nullable jsonDictionary) {
|
||||
|
||||
MVMCoreErrorObject *error = nil;
|
||||
MVMCoreAlertObject *popupAlert = [MVMCoreAlertObject alertObjectWithPage:jsonDictionary isGreedy:NO additionalData:additionalData delegateObject:delegateObject error:&error];
|
||||
if (error) {
|
||||
|
||||
// Error, popup page not found for page type.
|
||||
popupAlert = [[MVMCoreAlertObject alloc] initPopupAlertWithError:error isGreedy:NO];
|
||||
}
|
||||
|
||||
if (popupAlert) {
|
||||
alert = popupAlert;
|
||||
}
|
||||
}];
|
||||
} else if (messageStyle.length == 0 && pageType) {
|
||||
|
||||
// No message style!
|
||||
alert.type = MFAlertTypeNone;
|
||||
} else {
|
||||
|
||||
// Default to popup
|
||||
alert.type = MFAlertTypePopup;
|
||||
alert.alertStyle = UIAlertControllerStyleAlert;
|
||||
}
|
||||
}
|
||||
alert.alertDelegate = alertDelegateObject.alertDelegate;
|
||||
return alert;
|
||||
}
|
||||
|
||||
- (nullable instancetype)initPopupAlertWithTitle:(nullable NSString *)title message:(nullable NSString *)message actions:(nonnull NSArray *)actions isGreedy:(BOOL)isGreedy {
|
||||
if (self = [super init]) {
|
||||
self.title = title;
|
||||
self.message = message;
|
||||
self.actions = actions;
|
||||
self.isGreedy = isGreedy;
|
||||
self.type = MFAlertTypePopup;
|
||||
self.alertStyle = UIAlertControllerStyleAlert;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (nullable instancetype)initPopupAlertWithError:(nullable MVMCoreErrorObject *)error isGreedy:(BOOL)isGreedy {
|
||||
|
||||
if (self = [super init]) {
|
||||
self.title = error.title;
|
||||
self.message = [NSString stringWithFormat:@"%@ (%@)",error.messageToDisplay,[error stringErrorCode]];
|
||||
self.actions = @[[UIAlertAction actionWithTitle:[MVMCoreGetterUtility hardcodedStringWithKey:HardcodedOK] style:UIAlertActionStyleDefault handler:nil]];
|
||||
self.defaultAction = YES;
|
||||
self.isGreedy = isGreedy;
|
||||
self.type = MFAlertTypePopup;
|
||||
self.alertStyle = UIAlertControllerStyleAlert;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (nullable instancetype)initPopupAlertWithError:(nullable MVMCoreErrorObject *)error actions:(nonnull NSArray *)actions isGreedy:(BOOL)isGreedy {
|
||||
|
||||
if (self = [super init]) {
|
||||
self.title = error.title;
|
||||
self.message = [NSString stringWithFormat:@"%@ (%@)",error.messageToDisplay,[error stringErrorCode]];
|
||||
self.actions = actions;
|
||||
self.isGreedy = isGreedy;
|
||||
self.type = MFAlertTypePopup;
|
||||
self.alertStyle = UIAlertControllerStyleAlert;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
+ (nullable instancetype)alertObjectWithPage:(nullable NSDictionary *)page isGreedy:(BOOL)isGreedy additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject error:(MVMCoreErrorObject *_Nullable *_Nullable)error {
|
||||
|
||||
MVMCoreAlertObject *alert = [[MVMCoreAlertObject alloc] init];
|
||||
alert.title = [page stringForKey:KeyTitle];
|
||||
alert.pageJson = page;
|
||||
alert.message = [page stringForKey:KeyMessage];
|
||||
alert.isGreedy = isGreedy;
|
||||
alert.type = MFAlertTypePopup;
|
||||
alert.alertStyle = UIAlertControllerStyleAlert;
|
||||
|
||||
NSArray <NSDictionary *> *actions = [page array:KeyLinks];
|
||||
NSMutableArray <UIAlertAction *> *actionsForAlert = [NSMutableArray array];
|
||||
for (NSDictionary *actionMap in actions) {
|
||||
[actionsForAlert addObject:[UIAlertAction actionWithTitle:[actionMap stringForKey:KeyTitle] style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
|
||||
[[MVMCoreActionHandler sharedActionHandler] handleActionWithDictionary:actionMap additionalData:additionalData delegateObject:delegateObject];
|
||||
}]];
|
||||
}
|
||||
alert.actions = actionsForAlert;
|
||||
|
||||
if ((alert.title.length > 0 || alert.message.length > 0) && alert.actions.count > 0) {
|
||||
return alert;
|
||||
} else {
|
||||
if (error) {
|
||||
id delegate = [delegateObject isKindOfClass:[MVMCoreUIDelegateObject class]] ? ((MVMCoreUIDelegateObject *)delegateObject).alertDelegate : nil;
|
||||
*error = [[MVMCoreErrorObject alloc] initWithTitle:nil message:[MVMCoreGetterUtility hardcodedStringWithKey:HardcodedErrorUnableToProcess] code:ErrorCodePopupFailed domain:ErrorDomainNative location:[NSString stringWithFormat:@"%@_Popup_pageType:%@",NSStringFromClass([delegate class]),[page stringForKey:KeyPageType]]];
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)showAlert {
|
||||
|
||||
switch (self.type) {
|
||||
case MFAlertTypeField:
|
||||
self.textFieldErrorHandler(self.fieldErrors);
|
||||
break;
|
||||
case MFAlertTypeTop:
|
||||
[[MVMCoreAlertHandler sharedAlertHandler] showTopAlertWithObject:self.topAlertObject];
|
||||
break;
|
||||
case MFAlertTypePopup:
|
||||
[[MVMCoreAlertHandler sharedAlertHandler] showAlertWithAlertObject:self];
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Deprecated
|
||||
|
||||
+ (nullable instancetype)alertObjectForLoadObject:(nullable MVMCoreLoadObject *)loadObject error:(nullable MVMCoreErrorObject *)error actionDelegate:(nullable NSObject <MVMCoreLoadDelegateProtocol,MVMCorePresentationDelegateProtocol,MVMCoreActionDelegateProtocol>*)actionDelegate {
|
||||
|
||||
MVMCoreAlertObject *alert = nil;
|
||||
if (!error || [ErrorDomainServer isEqualToString:error.domain]) {
|
||||
alert = [MVMCoreAlertObject alertObjectForPageType:loadObject.pageType responseInfo:loadObject.responseInfoMap additionalData:loadObject.dataForPage actionDelegate:actionDelegate];
|
||||
} else {
|
||||
alert = [[MVMCoreAlertObject alloc] initPopupAlertWithError:error isGreedy:NO];
|
||||
}
|
||||
|
||||
// only if actions are empty, then go inside and set OK as default action
|
||||
if (alert.type == MFAlertTypePopup && alert.actions.count == 0) {
|
||||
alert.defaultAction = YES;
|
||||
alert.actions = @[[UIAlertAction actionWithTitle:[MVMCoreGetterUtility hardcodedStringWithKey:HardcodedOK] style:UIAlertActionStyleDefault handler:nil]];
|
||||
}
|
||||
return alert;
|
||||
}
|
||||
|
||||
+ (nullable instancetype)alertObjectForPageType:(nullable NSString *)pageType responseInfo:(nullable NSDictionary *)responseInfo additionalData:(nullable NSDictionary *)additionalData actionDelegate:(nullable NSObject <MVMCoreLoadDelegateProtocol,MVMCorePresentationDelegateProtocol,MVMCoreActionDelegateProtocol>*)actionDelegate {
|
||||
|
||||
__block MVMCoreAlertObject *alert = [[MVMCoreAlertObject alloc] init];
|
||||
alert.title = [responseInfo stringForKey:KeyErrorHeading];
|
||||
alert.message = [responseInfo stringForKey:KeyUserMessage];
|
||||
|
||||
NSString *messageStyle = [responseInfo stringForKey:KeyMessageStyle];
|
||||
if ([ValueTypeFieldErrors isEqualToString:[responseInfo string:KeyType]]) {
|
||||
|
||||
// field errors.
|
||||
alert.type = MFAlertTypeField;
|
||||
alert.fieldErrors = [responseInfo array:ValueTypeFieldErrors];
|
||||
} else {
|
||||
|
||||
// Check for top alert (persistent or regular).
|
||||
if ([messageStyle isEqualToString:ValueMessageStyleTopPersistent] || [messageStyle isEqualToString:ValueMessageStyleTop]) {
|
||||
|
||||
alert.topAlertObject = [[MVMCoreTopAlertObject alloc] initWithResponseInfo:responseInfo];
|
||||
if ([actionDelegate conformsToProtocol:@protocol(MVMCoreTopAlertDelegateProtocol)]) {
|
||||
alert.topAlertObject.delegate = (NSObject <MVMCoreTopAlertDelegateProtocol> *)actionDelegate;
|
||||
}
|
||||
alert.topAlertObject.pageType = pageType;
|
||||
alert.type = MFAlertTypeTop;
|
||||
} else if ([messageStyle isEqualToString:ValueMessageStylePopup]) {
|
||||
|
||||
// Perform a popup.
|
||||
alert.type = MFAlertTypePopup;
|
||||
alert.alertStyle = UIAlertControllerStyleAlert;
|
||||
|
||||
// Check if we have a popup driven by page object (otherwise by default it will just use response info title message with an OK button).
|
||||
NSString *pageTypeForPopup = [responseInfo stringForKey:@"popupPageType"];
|
||||
[[MVMCoreCache sharedCache] fetchJSONForPageType:pageTypeForPopup queue:nil waitUntilFinished:YES completionHandler:^(NSDictionary * _Nullable jsonDictionary) {
|
||||
|
||||
MVMCoreErrorObject *error = nil;
|
||||
MVMCoreAlertObject *popupAlert = [MVMCoreAlertObject alertObjectWithPage:jsonDictionary isGreedy:NO additionalData:additionalData delegate:actionDelegate error:&error];
|
||||
if (error) {
|
||||
|
||||
// Error, popup page not found for page type.
|
||||
popupAlert = [[MVMCoreAlertObject alloc] initPopupAlertWithError:error isGreedy:NO];
|
||||
}
|
||||
|
||||
if (popupAlert) {
|
||||
alert = popupAlert;
|
||||
}
|
||||
}];
|
||||
} else if (messageStyle.length == 0 && pageType) {
|
||||
|
||||
// No message style!
|
||||
alert.type = MFAlertTypeNone;
|
||||
} else {
|
||||
|
||||
// Default to popup
|
||||
alert.type = MFAlertTypePopup;
|
||||
alert.alertStyle = UIAlertControllerStyleAlert;
|
||||
}
|
||||
}
|
||||
if ([actionDelegate conformsToProtocol:@protocol(MVMCoreAlertDelegateProtocol)]) {
|
||||
alert.alertDelegate = (NSObject <MVMCoreAlertDelegateProtocol> *)actionDelegate;
|
||||
}
|
||||
return alert;
|
||||
}
|
||||
|
||||
+ (nullable instancetype)alertObjectWithPage:(nullable NSDictionary *)page isGreedy:(BOOL)isGreedy additionalData:(nullable NSDictionary *)additionalData delegate:(nullable NSObject <MVMCoreLoadDelegateProtocol,MVMCorePresentationDelegateProtocol,MVMCoreActionDelegateProtocol>*)delegate error:(MVMCoreErrorObject *_Nullable *_Nullable)error {
|
||||
|
||||
MVMCoreAlertObject *alert = [[MVMCoreAlertObject alloc] init];
|
||||
alert.title = [page stringForKey:KeyTitle];
|
||||
alert.pageJson = page;
|
||||
alert.message = [page stringForKey:KeyMessage];
|
||||
alert.isGreedy = isGreedy;
|
||||
alert.type = MFAlertTypePopup;
|
||||
alert.alertStyle = UIAlertControllerStyleAlert;
|
||||
|
||||
NSArray <NSDictionary *> *actions = [page array:KeyLinks];
|
||||
NSMutableArray <UIAlertAction *> *actionsForAlert = [NSMutableArray array];
|
||||
for (NSDictionary *actionMap in actions) {
|
||||
[actionsForAlert addObject:[UIAlertAction actionWithTitle:[actionMap stringForKey:KeyTitle] style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
|
||||
[[MVMCoreActionHandler sharedActionHandler] handleActionWithDictionary:actionMap additionalData:additionalData delegate:delegate];
|
||||
}]];
|
||||
}
|
||||
alert.actions = actionsForAlert;
|
||||
|
||||
if ((alert.title.length > 0 || alert.message.length > 0) && alert.actions.count > 0) {
|
||||
return alert;
|
||||
} else {
|
||||
if (error) {
|
||||
*error = [[MVMCoreErrorObject alloc] initWithTitle:nil messageToLog:[MVMCoreGetterUtility hardcodedStringWithKey:HardcodedErrorUnableToProcess] code:ErrorCodePopupFailed domain:ErrorDomainNative location:[NSString stringWithFormat:@"%@_Popup_pageType:%@",NSStringFromClass([delegate class]),[page stringForKey:KeyPageType]]];
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
39
MVMCoreUI/Alerts/MVMCoreAlertOperation.h
Normal file
39
MVMCoreUI/Alerts/MVMCoreAlertOperation.h
Normal file
@ -0,0 +1,39 @@
|
||||
//
|
||||
// MVMCoreAlertOperation.h
|
||||
// myverizon
|
||||
//
|
||||
// Created by Scott Pfeil on 9/28/15.
|
||||
// Copyright © 2015 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
// Operation for handling an alert. Should NOT be on the main queue.
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <MVMCore/MVMCoreOperation.h>
|
||||
#import <MVMCoreUI/MVMCoreAlertDelegateProtocol.h>
|
||||
|
||||
@interface MVMCoreAlertOperation : MVMCoreOperation
|
||||
|
||||
/// Alert controller to be displayed.
|
||||
@property (nonnull, readonly) UIAlertController *currentAlertView;
|
||||
|
||||
/// If this operation is temporarily paused.
|
||||
@property (readonly, getter=isPaused) BOOL paused;
|
||||
|
||||
/// If this alert is a greedy alert (See MVMCoreAlertHandler).
|
||||
@property (readonly, getter=isGreedy) BOOL greedy;
|
||||
|
||||
/// The alert delegate if needed.
|
||||
@property (readonly, nullable, nonatomic, weak) NSObject <MVMCoreAlertDelegateProtocol> *alertDelegate;
|
||||
|
||||
/// Initializes the operation with the alert to display and if it is greedy or not.
|
||||
- (nullable instancetype)initWithAlert:(nonnull UIAlertController *)alert isGreedy:(BOOL)isGreedy;
|
||||
- (nullable instancetype)initWithAlert:(nonnull UIAlertController *)alert isGreedy:(BOOL)isGreedy alertDelegate:(nullable id <MVMCoreAlertDelegateProtocol>)alertDelegate;
|
||||
|
||||
/// Pauses the operation. Temporarily removes any alert.
|
||||
- (void)pause;
|
||||
|
||||
/// Unpauses the operation, resuming any alert.
|
||||
- (void)unpause;
|
||||
|
||||
@end
|
||||
242
MVMCoreUI/Alerts/MVMCoreAlertOperation.m
Normal file
242
MVMCoreUI/Alerts/MVMCoreAlertOperation.m
Normal file
@ -0,0 +1,242 @@
|
||||
//
|
||||
// MVMCoreAlertOperation.m
|
||||
// myverizon
|
||||
//
|
||||
// Created by Scott Pfeil on 9/28/15.
|
||||
// Copyright © 2015 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
#import "MVMCoreAlertOperation.h"
|
||||
#import <MVMCoreUI/MVMCoreAlertHandler.h>
|
||||
#import <MVMCore/MVMCoreAlertController.h>
|
||||
#import <MVMCore/MVMCoreNavigationHandler.h>
|
||||
|
||||
@interface MVMCoreAlertOperation () {
|
||||
__block BOOL _paused;
|
||||
__block BOOL _displayed;
|
||||
}
|
||||
|
||||
@property (readwrite, getter=isPaused) BOOL paused;
|
||||
|
||||
@property (readwrite, getter=isGreedy) BOOL greedy;
|
||||
|
||||
@property (readwrite, getter=isDisplayed) BOOL displayed;
|
||||
|
||||
@property (readwrite, nullable, nonatomic, weak) NSObject <MVMCoreAlertDelegateProtocol> *alertDelegate;
|
||||
|
||||
// The currently displayed alert view.
|
||||
@property (nullable, strong, nonatomic) UIAlertController *currentAlertView;
|
||||
|
||||
// A boolean to keep track of if we alreadys signed up to observe.
|
||||
@property (assign, nonatomic) BOOL alertBeingObserved;
|
||||
|
||||
// For thread safety
|
||||
@property (strong, nonatomic) dispatch_queue_t pausedQueue;
|
||||
@property (strong, nonatomic) dispatch_queue_t displayedQueue;
|
||||
|
||||
// Dismisses the alert.
|
||||
- (void)dismissAlertView;
|
||||
|
||||
// Begins observing for when the alert is dismissed.
|
||||
- (void)observeForCurrentAlertViewDismissal;
|
||||
|
||||
// Stops observing for when the alert is dismissed.
|
||||
- (void)stopObservingAlertView;
|
||||
|
||||
@end
|
||||
|
||||
@implementation MVMCoreAlertOperation
|
||||
|
||||
// The context for kvo
|
||||
static void * XXContext = &XXContext;
|
||||
|
||||
- (instancetype)init {
|
||||
|
||||
self = [super init];
|
||||
if (self) {
|
||||
self.pausedQueue = dispatch_queue_create("paused", DISPATCH_QUEUE_CONCURRENT);
|
||||
self.displayedQueue = dispatch_queue_create("displayed", DISPATCH_QUEUE_CONCURRENT);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (nullable instancetype)initWithAlert:(nonnull UIAlertController *)alert isGreedy:(BOOL)isGreedy {
|
||||
|
||||
if (self = [self init]) {
|
||||
self.currentAlertView = alert;
|
||||
self.greedy = isGreedy;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (nullable instancetype)initWithAlert:(nonnull UIAlertController *)alert isGreedy:(BOOL)isGreedy alertDelegate:(nullable NSObject <MVMCoreAlertDelegateProtocol>*)alertDelegate {
|
||||
if (self = [self initWithAlert:alert isGreedy:isGreedy]) {
|
||||
self.alertDelegate = alertDelegate;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
[self stopObservingAlertView];
|
||||
}
|
||||
|
||||
- (BOOL)isPaused {
|
||||
__block BOOL isPaused;
|
||||
dispatch_sync(self.pausedQueue, ^{
|
||||
isPaused = self->_paused;
|
||||
});
|
||||
return isPaused;
|
||||
}
|
||||
|
||||
- (void)setPaused:(BOOL)paused {
|
||||
dispatch_barrier_async(self.pausedQueue, ^{
|
||||
self->_paused = paused;
|
||||
});
|
||||
}
|
||||
|
||||
- (BOOL)isDisplayed {
|
||||
__block BOOL isDisplayed;
|
||||
dispatch_sync(self.displayedQueue, ^{
|
||||
isDisplayed = self->_displayed;
|
||||
});
|
||||
return isDisplayed;
|
||||
}
|
||||
|
||||
- (void)setDisplayed:(BOOL)displayed {
|
||||
dispatch_barrier_async(self.displayedQueue, ^{
|
||||
self->_displayed = displayed;
|
||||
});
|
||||
}
|
||||
|
||||
- (void)main {
|
||||
|
||||
// Always check for cancellation before launching the task.
|
||||
if ([self checkAndHandleForCancellation]) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Display alert only if alerts aren't supressed.
|
||||
if (![[MVMCoreAlertHandler sharedAlertHandler] mfAlertsSupressed] && self.currentAlertView) {
|
||||
|
||||
// Observe for when it is removed.
|
||||
[self observeForCurrentAlertViewDismissal];
|
||||
|
||||
// Adds the presentation to the animation queue.
|
||||
[[MVMCoreNavigationHandler sharedNavigationHandler] presentViewController:self.currentAlertView animated:YES delegate:nil completionHandler:^{
|
||||
|
||||
// We finished but it was not displayed yet. It's possible that it was cancelled. Finish this task
|
||||
if (!self.isDisplayed) {
|
||||
[self markAsFinished];
|
||||
} else if (self.isCancelled) {
|
||||
[self dismissAlertView];
|
||||
}
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)cancel {
|
||||
[super cancel];
|
||||
|
||||
// Notify delegate that the alert is cancelled.
|
||||
if ([self.alertDelegate respondsToSelector:@selector(alertCancelled:)]) {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[self.alertDelegate alertCancelled:self.currentAlertView];
|
||||
});
|
||||
}
|
||||
|
||||
[self dismissAlertView];
|
||||
}
|
||||
|
||||
- (void)dismissAlertView {
|
||||
|
||||
if (self.isDisplayed) {
|
||||
|
||||
// Dismisses.
|
||||
[[MVMCoreNavigationHandler sharedNavigationHandler] dismissViewController:self.currentAlertView animated:YES];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)pause {
|
||||
[self willChangeValueForKey:@"isPaused"];
|
||||
self.paused = YES;
|
||||
[self didChangeValueForKey:@"isPaused"];
|
||||
|
||||
// Notify delegate of pause.
|
||||
if ([self.alertDelegate respondsToSelector:@selector(alertPaused:)]) {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[self.alertDelegate alertPaused:self.currentAlertView];
|
||||
});
|
||||
}
|
||||
|
||||
// Dismiss until unpaused.
|
||||
[self dismissAlertView];
|
||||
}
|
||||
|
||||
- (void)unpause {
|
||||
[self willChangeValueForKey:@"isPaused"];
|
||||
self.paused = NO;
|
||||
[self didChangeValueForKey:@"isPaused"];
|
||||
|
||||
// Notify delegate of unpause.
|
||||
if ([self.alertDelegate respondsToSelector:@selector(alertUnpaused:)]) {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[self.alertDelegate alertUnpaused:self.currentAlertView];
|
||||
});
|
||||
}
|
||||
|
||||
// Show alert...
|
||||
if (self.currentAlertView) {
|
||||
[self start];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Observer Functions
|
||||
|
||||
- (void)observeForCurrentAlertViewDismissal {
|
||||
if (!self.alertBeingObserved && ![[MVMCoreAlertHandler sharedAlertHandler] mfAlertsSupressed] && self.currentAlertView && [self.currentAlertView isKindOfClass:[UIAlertController class]]) {
|
||||
self.alertBeingObserved = YES;
|
||||
[self.currentAlertView addObserver:self forKeyPath:@"visible" options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:XXContext];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)stopObservingAlertView {
|
||||
if (self.alertBeingObserved) {
|
||||
[self.currentAlertView removeObserver:self forKeyPath:@"visible" context:XXContext];
|
||||
self.alertBeingObserved = NO;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
|
||||
if (context == XXContext && [keyPath isEqualToString:@"visible"]) {
|
||||
if (![object isVisible]) {
|
||||
|
||||
self.displayed = NO;
|
||||
|
||||
// Notify delegate that the alert is dismissed.
|
||||
if ([self.alertDelegate respondsToSelector:@selector(alertDismissed:)]) {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[self.alertDelegate alertDismissed:self.currentAlertView];
|
||||
});
|
||||
}
|
||||
|
||||
// Is visible was set to NO, meaning that the alertview is no longer visible.
|
||||
if (!self.isPaused) {
|
||||
[self stopObservingAlertView];
|
||||
self.currentAlertView = nil;
|
||||
[self markAsFinished];
|
||||
}
|
||||
} else {
|
||||
|
||||
self.displayed = YES;
|
||||
|
||||
// Notify delegate that the alert is shown.
|
||||
if ([self.alertDelegate respondsToSelector:@selector(alertShown:)]) {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[self.alertDelegate alertShown:self.currentAlertView];
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
20
MVMCoreUI/Atomic/Actions/ActionAlertModel.swift
Normal file
20
MVMCoreUI/Atomic/Actions/ActionAlertModel.swift
Normal file
@ -0,0 +1,20 @@
|
||||
//
|
||||
// ActionAlertModel.swift
|
||||
// MVMCoreUI
|
||||
//
|
||||
// Created by Suresh, Kamlesh on 7/9/20.
|
||||
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
|
||||
@objcMembers public class ActionAlertModel: ActionModelProtocol {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
public static var identifier: String = "alert"
|
||||
public var actionType: String = ActionAlertModel.identifier
|
||||
public var alert: AlertModel
|
||||
public var extraParameters: JSONValueDictionary?
|
||||
public var analyticsData: JSONValueDictionary?
|
||||
}
|
||||
30
MVMCoreUI/Atomic/Actions/ActionPopupModel.swift
Normal file
30
MVMCoreUI/Atomic/Actions/ActionPopupModel.swift
Normal file
@ -0,0 +1,30 @@
|
||||
//
|
||||
// ActionPopupModel.swift
|
||||
// MVMCore
|
||||
//
|
||||
// Created by Suresh, Kamlesh on 12/16/19.
|
||||
// Copyright © 2019 myverizon. All rights reserved.
|
||||
//
|
||||
|
||||
|
||||
@objcMembers public class ActionPopupModel: ActionModelProtocol {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
public static var identifier: String = "popup"
|
||||
public var actionType: String = ActionPopupModel.identifier
|
||||
public var pageType: String
|
||||
public var extraParameters: JSONValueDictionary?
|
||||
public var analyticsData: JSONValueDictionary?
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Initializer
|
||||
//--------------------------------------------------
|
||||
|
||||
public init(pageType: String, _ extraParameters: JSONValueDictionary? = nil, _ analyticsData: JSONValueDictionary? = nil) {
|
||||
self.pageType = pageType
|
||||
self.extraParameters = extraParameters
|
||||
self.analyticsData = analyticsData
|
||||
}
|
||||
}
|
||||
116
MVMCoreUI/Atomic/Actions/AlertModel.swift
Normal file
116
MVMCoreUI/Atomic/Actions/AlertModel.swift
Normal file
@ -0,0 +1,116 @@
|
||||
//
|
||||
// AlertModel.swift
|
||||
// MVMCore
|
||||
//
|
||||
// Created by Suresh, Kamlesh on 7/14/20.
|
||||
// Copyright © 2020 myverizon. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
|
||||
public class AlertButtonModel: Codable {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
public var title: String
|
||||
public var action: ActionModelProtocol
|
||||
public var style: UIAlertAction.Style = .default
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Initializer
|
||||
//--------------------------------------------------
|
||||
|
||||
public init(_ title: String,_ action: ActionModelProtocol,_ style: UIAlertAction.Style = .default) {
|
||||
self.title = title
|
||||
self.action = action
|
||||
self.style = style
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Keys
|
||||
//--------------------------------------------------
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case title
|
||||
case action
|
||||
case style
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Codec
|
||||
//--------------------------------------------------
|
||||
|
||||
required public init(from decoder: Decoder) throws {
|
||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||
title = try typeContainer.decode(String.self, forKey: .title)
|
||||
|
||||
if let style = try typeContainer.decodeIfPresent(String.self, forKey: .style) {
|
||||
self.style = UIAlertAction.Style(rawValue: style)
|
||||
}
|
||||
action = try typeContainer.decodeModel(codingKey: .action)
|
||||
}
|
||||
|
||||
open func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
try container.encode(title, forKey: .title)
|
||||
try container.encode(style.rawValueString, forKey: .style)
|
||||
try container.encodeModel(action, forKey: .action)
|
||||
}
|
||||
}
|
||||
|
||||
public class AlertModel: Codable {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
public var title: String
|
||||
public var message: String
|
||||
public var style: UIAlertController.Style = .alert
|
||||
public var alertActions: [AlertButtonModel]
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
public init(_ title: String,_ message: String,_ alertActions: [AlertButtonModel]) {
|
||||
self.title = title
|
||||
self.message = message
|
||||
self.alertActions = alertActions
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Keys
|
||||
//--------------------------------------------------
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case title
|
||||
case message
|
||||
case alertActions
|
||||
case style
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Codec
|
||||
//--------------------------------------------------
|
||||
|
||||
required public init(from decoder: Decoder) throws {
|
||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||
title = try typeContainer.decode(String.self, forKey: .title)
|
||||
message = try typeContainer.decode(String.self, forKey: .message)
|
||||
alertActions = try typeContainer.decode([AlertButtonModel].self, forKey: .alertActions)
|
||||
|
||||
if let style = try typeContainer.decodeIfPresent(String.self, forKey: .style) {
|
||||
self.style = UIAlertController.Style(rawValue: style)
|
||||
}
|
||||
}
|
||||
|
||||
open func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
try container.encode(title, forKey: .title)
|
||||
try container.encode(message, forKey: .message)
|
||||
try container.encode(alertActions, forKey: .alertActions)
|
||||
try container.encode(style.rawValueString, forKey: .style)
|
||||
}
|
||||
}
|
||||
43
MVMCoreUI/Atomic/Extensions/UIAlertActionStyle+Codable.swift
Normal file
43
MVMCoreUI/Atomic/Extensions/UIAlertActionStyle+Codable.swift
Normal file
@ -0,0 +1,43 @@
|
||||
//
|
||||
// UIAlertActionStyle+Codable.swift
|
||||
// MVMCore
|
||||
//
|
||||
// Created by Suresh, Kamlesh on 7/14/20.
|
||||
// Copyright © 2020 myverizon. All rights reserved.
|
||||
//
|
||||
|
||||
|
||||
extension UIAlertAction.Style: Codable {
|
||||
|
||||
init(rawValue: String) {
|
||||
switch rawValue {
|
||||
case "default":
|
||||
self = .default
|
||||
|
||||
case "cancel":
|
||||
self = .cancel
|
||||
|
||||
case "destructive":
|
||||
self = .destructive
|
||||
|
||||
default:
|
||||
self = .default
|
||||
}
|
||||
}
|
||||
|
||||
var rawValueString: String {
|
||||
switch self {
|
||||
case .default:
|
||||
return "default"
|
||||
|
||||
case .cancel:
|
||||
return "cancel"
|
||||
|
||||
case .destructive:
|
||||
return "destructive"
|
||||
|
||||
@unknown default:
|
||||
return "default"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,37 @@
|
||||
//
|
||||
// UIAlertControllerStyle+Extension.swift
|
||||
// MVMCore
|
||||
//
|
||||
// Created by Kevin Christiano on 7/17/20.
|
||||
// Copyright © 2020 myverizon. All rights reserved.
|
||||
//
|
||||
|
||||
|
||||
extension UIAlertController.Style: Codable {
|
||||
|
||||
init(rawValue: String) {
|
||||
switch rawValue {
|
||||
case "alert":
|
||||
self = .alert
|
||||
|
||||
case "actionSheet":
|
||||
self = .actionSheet
|
||||
|
||||
default:
|
||||
self = .alert
|
||||
}
|
||||
}
|
||||
|
||||
var rawValueString: String {
|
||||
switch self {
|
||||
case .alert:
|
||||
return "alert"
|
||||
|
||||
case .actionSheet:
|
||||
return "actionSheet"
|
||||
|
||||
@unknown default:
|
||||
return "alert"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -252,6 +252,8 @@ import Foundation
|
||||
try? ModelRegistry.register(RuleRegexModel.self)
|
||||
|
||||
// MARK:- Actions
|
||||
try? ModelRegistry.register(ActionPopupModel.self)
|
||||
try? ModelRegistry.register(ActionAlertModel.self)
|
||||
try? ModelRegistry.register(ActionTopAlertModel.self)
|
||||
try? ModelRegistry.register(ActionCollapseNotificationModel.self)
|
||||
try? ModelRegistry.register(ActionOpenPanelModel.self)
|
||||
|
||||
@ -10,7 +10,6 @@
|
||||
@import MVMCore.MVMCoreNavigationHandler;
|
||||
@import MVMCore.MVMCoreDispatchUtility;
|
||||
@import MVMCore.MVMCoreViewManagerProtocol;
|
||||
@import MVMCore.MVMCoreObject;
|
||||
@import MVMCore.MVMCoreActionUtility;
|
||||
@import MVMCore.NSDictionary_MFConvenience;
|
||||
#import "MVMCoreUIUtility.h"
|
||||
@ -847,8 +846,8 @@ CGFloat const PanelAnimationDuration = 0.2;
|
||||
|
||||
// Top Alert
|
||||
MVMCoreUITopAlertView *topAlertView = nil;
|
||||
if ([[MVMCoreObject sharedInstance].globalTopAlertDelegate respondsToSelector:@selector(getTopAlertView)]) {
|
||||
topAlertView = (MVMCoreUITopAlertView *)[[MVMCoreObject sharedInstance].globalTopAlertDelegate getTopAlertView];
|
||||
if ([[CoreUIObject sharedInstance].globalTopAlertDelegate respondsToSelector:@selector(getTopAlertView)]) {
|
||||
topAlertView = (MVMCoreUITopAlertView *)[[CoreUIObject sharedInstance].globalTopAlertDelegate getTopAlertView];
|
||||
if (topAlertView) {
|
||||
self.topAlertView = topAlertView;
|
||||
[self.view addSubview:topAlertView];
|
||||
|
||||
@ -20,8 +20,22 @@ FOUNDATION_EXPORT const unsigned char MVMCoreUIVersionString[];
|
||||
#import <MVMCoreUI/MVMCoreUILoggingHandler.h>
|
||||
#import <MVMCoreUI/MVMCoreUIViewControllerMappingObject.h>
|
||||
#import <MVMCoreUI/MVMCoreUIViewConstrainingProtocol.h>
|
||||
#import <MVMCoreUI/MVMCoreUIActionDelegateProtocol.h>
|
||||
#import <MVMCoreUI/MVMCoreUIActionHandler.h>
|
||||
|
||||
// Alert Handling
|
||||
#import <MVMCoreUI/MVMCoreAlertObject.h>
|
||||
#import <MVMCoreUI/MVMCoreAlertOperation.h>
|
||||
#import <MVMCoreUI/MVMCoreAlertHandler.h>
|
||||
#import <MVMCoreUI/MVMCoreAlertDelegateProtocol.h>
|
||||
|
||||
#pragma mark - TopAlert
|
||||
#import <MVMCoreUI/MVMCoreGlobalTopAlertDelegateProtocol.h>
|
||||
#import <MVMCoreUI/MVMCoreTopAlertObject.h>
|
||||
#import <MVMCoreUI/MVMCoreTopAlertAnimationDelegateProtocol.h>
|
||||
#import <MVMCoreUI/MVMCoreTopAlertDelegateProtocol.h>
|
||||
#import <MVMCoreUI/MVMCoreTopAlertViewProtocol.h>
|
||||
#import <MVMCoreUI/MVMCoreTopAlertOperation.h>
|
||||
#import <MVMCoreUI/MVMCoreUITopAlertView.h>
|
||||
#import <MVMCoreUI/MVMCoreUITopAlertBaseView.h>
|
||||
#import <MVMCoreUI/MVMCoreUITopAlertMainView.h>
|
||||
|
||||
@ -10,6 +10,7 @@ import UIKit
|
||||
|
||||
@objcMembers open class CoreUIObject: MVMCoreObject {
|
||||
public var moleculeMap: MoleculeObjectMapping?
|
||||
public var globalTopAlertDelegate: MVMCoreGlobalTopAlertDelegateProtocol?
|
||||
|
||||
open override func defaultInitialSetup() {
|
||||
cache = MVMCoreCache()
|
||||
|
||||
19
MVMCoreUI/OtherHandlers/MVMCoreUIActionDelegateProtocol.h
Normal file
19
MVMCoreUI/OtherHandlers/MVMCoreUIActionDelegateProtocol.h
Normal file
@ -0,0 +1,19 @@
|
||||
//
|
||||
// MVMCoreUIActionDelegateProtocol.h
|
||||
// MVMCoreUI
|
||||
//
|
||||
// Created by Scott Pfeil on 10/28/20.
|
||||
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
#import <MVMCore/MVMCoreActionDelegateProtocol.h>
|
||||
@class MVMCoreAlertObject;
|
||||
|
||||
@protocol MVMCoreUIActionDelegateProtocol <MVMCoreActionDelegateProtocol>
|
||||
|
||||
// Gives the delegate a chance to alter the alert object
|
||||
- (void)willShowPopupWithAlertObject:(nonnull MVMCoreAlertObject *)alertObject alertJson:(nonnull NSDictionary *)alertJson;
|
||||
|
||||
// Gives the delegate a chance to alter the alert object
|
||||
- (nullable MVMCoreAlertObject *)willShowTopAlertWithAlertObject:(nonnull MVMCoreAlertObject *)alertObject alertJson:(nonnull NSDictionary *)alertJson;
|
||||
|
||||
@end
|
||||
40
MVMCoreUI/OtherHandlers/MVMCoreUIActionHandler.h
Normal file
40
MVMCoreUI/OtherHandlers/MVMCoreUIActionHandler.h
Normal file
@ -0,0 +1,40 @@
|
||||
//
|
||||
// MVMCoreUIActionHandler.h
|
||||
// MVMCoreUI
|
||||
//
|
||||
// Created by Scott Pfeil on 10/28/20.
|
||||
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
#import <MVMCore/MVMCoreActionHandler.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface MVMCoreUIActionHandler : MVMCoreActionHandler
|
||||
|
||||
// Shows a popup alert by grabbing the content from the page map.
|
||||
- (void)popupAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject;
|
||||
|
||||
// Shows popup alert from the alert object in the action map. The actionType of the action is 'alert'
|
||||
- (void)showAlert:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject;
|
||||
|
||||
// Shows a top alert
|
||||
- (void)topAlertAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject;
|
||||
|
||||
// Collapses the current top notification
|
||||
- (void)collapseNotificationAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject;
|
||||
|
||||
#pragma mark - Deprecated
|
||||
|
||||
// Shows a popup
|
||||
- (void)popupAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegate:(nullable NSObject <MVMCoreLoadDelegateProtocol, MVMCorePresentationDelegateProtocol,MVMCoreActionDelegateProtocol>*)delegate __deprecated;
|
||||
|
||||
// Shows a top alert
|
||||
- (void)topAlertAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegate:(nullable NSObject <MVMCoreLoadDelegateProtocol, MVMCorePresentationDelegateProtocol,MVMCoreActionDelegateProtocol>*)delegate __deprecated;
|
||||
|
||||
// Collapses the current top notification
|
||||
- (void)collapseNotificationAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegate:(nullable NSObject <MVMCoreLoadDelegateProtocol, MVMCorePresentationDelegateProtocol,MVMCoreActionDelegateProtocol>*)delegate __deprecated;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
164
MVMCoreUI/OtherHandlers/MVMCoreUIActionHandler.m
Normal file
164
MVMCoreUI/OtherHandlers/MVMCoreUIActionHandler.m
Normal file
@ -0,0 +1,164 @@
|
||||
//
|
||||
// MVMCoreUIActionHandler.m
|
||||
// MVMCoreUI
|
||||
//
|
||||
// Created by Scott Pfeil on 10/28/20.
|
||||
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
#import "MVMCoreUIActionHandler.h"
|
||||
#import "MVMCoreUIConstants.h"
|
||||
#import "MVMCoreAlertObject.h"
|
||||
#import <MVMCoreUI/MVMCoreUIActionDelegateProtocol.h>
|
||||
#import <MVMCoreUI/MVMCoreUI-Swift.h>
|
||||
@import MVMCore.MVMCoreActionHandler;
|
||||
@import MVMCore.NSDictionary_MFConvenience;
|
||||
@import MVMCore.MVMCoreJSONConstants;
|
||||
@import MVMCore.MVMCoreCache;
|
||||
|
||||
@implementation MVMCoreUIActionHandler
|
||||
|
||||
- (BOOL)handleOtherActions:(NSString *)actionType actionInformation:(NSDictionary *)actionInformation additionalData:(NSDictionary *)additionalData delegateObject:(DelegateObject *)delegateObject {
|
||||
if ([actionType isEqualToString:KeyActionTypePopup]) {
|
||||
[self popupAction:actionInformation additionalData:additionalData delegateObject:delegateObject];
|
||||
return YES;
|
||||
} else if ([actionType isEqualToString:KeyActionTypeTopAlert]) {
|
||||
[self topAlertAction:actionInformation additionalData:additionalData delegateObject:delegateObject];
|
||||
return YES;
|
||||
} else if ([actionType isEqualToString:KeyActionTypeCollapseNotification]) {
|
||||
[self collapseNotificationAction:actionInformation additionalData:additionalData delegateObject:delegateObject];
|
||||
return YES;
|
||||
} else if ([actionType isEqualToString:KeyActionTypeAlert]) {
|
||||
[self showAlert:actionInformation additionalData:additionalData delegateObject:delegateObject];
|
||||
return YES;
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void)popupAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject {
|
||||
// Perform a popup.
|
||||
NSString *pageTypeForPopup = [actionInformation stringForKey:KeyPageType];
|
||||
[[MVMCoreCache sharedCache] fetchJSONForPageType:pageTypeForPopup queue:nil waitUntilFinished:YES completionHandler:^(NSDictionary * _Nullable jsonDictionary) {
|
||||
|
||||
MVMCoreErrorObject *error = nil;
|
||||
MVMCoreAlertObject *alertObject = [MVMCoreAlertObject alertObjectWithPage:jsonDictionary isGreedy:NO additionalData:additionalData delegateObject:delegateObject error:&error];
|
||||
if ([delegateObject.actionDelegate respondsToSelector:@selector(willShowPopupWithAlertObject:alertJson:)]) {
|
||||
[((id <MVMCoreUIActionDelegateProtocol>)delegateObject.actionDelegate) willShowPopupWithAlertObject:alertObject alertJson:jsonDictionary];
|
||||
}
|
||||
|
||||
if (alertObject) {
|
||||
[[MVMCoreAlertHandler sharedAlertHandler] showAlertWithAlertObject:alertObject];
|
||||
} else {
|
||||
[self handleActionError:error actionInformation:actionInformation additionalData:additionalData delegateObject:delegateObject ];
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)showAlert:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject {
|
||||
|
||||
MVMCoreErrorObject *error = nil;
|
||||
MVMCoreAlertObject *alertObject = [MVMCoreAlertObject alertObjectWithAction:actionInformation additionalData:additionalData delegateObject:delegateObject error:&error];
|
||||
if ([delegateObject.actionDelegate respondsToSelector:@selector(willShowPopupWithAlertObject:alertJson:)]) {
|
||||
[((id <MVMCoreUIActionDelegateProtocol>)delegateObject.actionDelegate) willShowPopupWithAlertObject:alertObject alertJson:actionInformation];
|
||||
}
|
||||
|
||||
if (alertObject) {
|
||||
[[MVMCoreAlertHandler sharedAlertHandler] showAlertWithAlertObject:alertObject];
|
||||
} else {
|
||||
[self handleActionError:error actionInformation:actionInformation additionalData:additionalData delegateObject:delegateObject];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)topAlertAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject {
|
||||
// Perform a top alert.
|
||||
NSString *pageTypeForTopAlert = [actionInformation stringForKey:KeyPageType];
|
||||
[[MVMCoreCache sharedCache] fetchJSONForPageType:pageTypeForTopAlert queue:nil waitUntilFinished:YES completionHandler:^(NSDictionary * _Nullable jsonDictionary) {
|
||||
|
||||
NSDictionary *responseInfo = [jsonDictionary dict:KeyResponseInfo];
|
||||
if (responseInfo) {
|
||||
MVMCoreAlertObject *alertObject = [MVMCoreAlertObject alertObjectForPageType:pageTypeForTopAlert responseInfo:responseInfo additionalData:additionalData delegateObject:delegateObject];
|
||||
if ([delegateObject.actionDelegate respondsToSelector:@selector(willShowTopAlertWithAlertObject:alertJson:)]) {
|
||||
[((id <MVMCoreUIActionDelegateProtocol>)delegateObject.actionDelegate) willShowTopAlertWithAlertObject:alertObject alertJson:actionInformation];
|
||||
}
|
||||
[alertObject showAlert];
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)collapseNotificationAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject {
|
||||
// Collapse the current notification.
|
||||
if ([[CoreUIObject sharedInstance].globalTopAlertDelegate respondsToSelector:@selector(getTopAlertView)]) {
|
||||
[[[CoreUIObject sharedInstance].globalTopAlertDelegate getTopAlertView] collapseNotification];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)defaultHandleActionError:(nonnull MVMCoreErrorObject *)error additionalData:(nullable NSDictionary *)additionalData {
|
||||
[super defaultHandleActionError:error additionalData:additionalData];
|
||||
if (!error.silentError) {
|
||||
|
||||
// Show alert
|
||||
[MVMCoreDispatchUtility performBlockOnMainThread:^{
|
||||
MVMCoreAlertObject *alertObject = [[MVMCoreAlertObject alloc] initPopupAlertWithError:error isGreedy:NO];
|
||||
[[MVMCoreAlertHandler sharedAlertHandler] showAlertWithAlertObject:alertObject];
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Deprecated
|
||||
|
||||
- (BOOL)handleOtherActions:(nullable NSString *)actionType actionInformation:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegate:(nullable NSObject <MVMCoreLoadDelegateProtocol, MVMCorePresentationDelegateProtocol,MVMCoreActionDelegateProtocol>*)delegate {
|
||||
if ([actionType isEqualToString:KeyActionTypePopup]) {
|
||||
[self popupAction:actionInformation additionalData:additionalData delegate:delegate];
|
||||
} else if ([actionType isEqualToString:KeyActionTypeTopAlert]) {
|
||||
[self topAlertAction:actionInformation additionalData:additionalData delegate:delegate];
|
||||
return YES;
|
||||
} else if ([actionType isEqualToString:KeyActionTypeCollapseNotification]) {
|
||||
[self collapseNotificationAction:actionInformation additionalData:additionalData delegate:delegate];
|
||||
return YES;
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void)popupAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegate:(nullable NSObject <MVMCoreLoadDelegateProtocol, MVMCorePresentationDelegateProtocol,MVMCoreActionDelegateProtocol>*)delegate {
|
||||
// Perform a popup.
|
||||
NSString *pageTypeForPopup = [actionInformation stringForKey:KeyPageType];
|
||||
[[MVMCoreCache sharedCache] fetchJSONForPageType:pageTypeForPopup queue:nil waitUntilFinished:YES completionHandler:^(NSDictionary * _Nullable jsonDictionary) {
|
||||
|
||||
MVMCoreErrorObject *error = nil;
|
||||
MVMCoreAlertObject *alertObject = [MVMCoreAlertObject alertObjectWithPage:jsonDictionary isGreedy:NO additionalData:additionalData delegate:delegate error:&error];
|
||||
if ([delegate respondsToSelector:@selector(willShowPopupWithAlertObject:alertJson:)]) {
|
||||
[((id <MVMCoreUIActionDelegateProtocol>)delegate) willShowPopupWithAlertObject:alertObject alertJson:jsonDictionary];
|
||||
}
|
||||
|
||||
if (alertObject) {
|
||||
[[MVMCoreAlertHandler sharedAlertHandler] showAlertWithAlertObject:alertObject];
|
||||
} else {
|
||||
[self handleActionError:error actionInformation:actionInformation additionalData:additionalData delegate:delegate];
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)topAlertAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegate:(nullable NSObject <MVMCoreLoadDelegateProtocol, MVMCorePresentationDelegateProtocol,MVMCoreActionDelegateProtocol>*)delegate {
|
||||
// Perform a top alert.
|
||||
NSString *pageTypeForTopAlert = [actionInformation stringForKey:KeyPageType];
|
||||
[[MVMCoreCache sharedCache] fetchJSONForPageType:pageTypeForTopAlert queue:nil waitUntilFinished:YES completionHandler:^(NSDictionary * _Nullable jsonDictionary) {
|
||||
|
||||
NSDictionary *responseInfo = [jsonDictionary dict:KeyResponseInfo];
|
||||
if (responseInfo) {
|
||||
MVMCoreAlertObject *alertObject = [MVMCoreAlertObject alertObjectForPageType:pageTypeForTopAlert responseInfo:responseInfo additionalData:additionalData actionDelegate:delegate];
|
||||
if ([delegate respondsToSelector:@selector(willShowTopAlertWithAlertObject:alertJson:)]) {
|
||||
alertObject = [((id <MVMCoreUIActionDelegateProtocol>)delegate) willShowTopAlertWithAlertObject:alertObject alertJson:jsonDictionary];
|
||||
}
|
||||
[alertObject showAlert];
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)collapseNotificationAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegate:(nullable NSObject <MVMCoreLoadDelegateProtocol, MVMCorePresentationDelegateProtocol,MVMCoreActionDelegateProtocol>*)delegate {
|
||||
// Collapse the current notification.
|
||||
if ([[CoreUIObject sharedInstance].globalTopAlertDelegate respondsToSelector:@selector(getTopAlertView)]) {
|
||||
[[[CoreUIObject sharedInstance].globalTopAlertDelegate getTopAlertView] collapseNotification];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
@ -17,6 +17,8 @@ open class MVMCoreUIDelegateObject: DelegateObject {
|
||||
public weak var uiTextViewDelegate: UITextViewDelegate?
|
||||
public weak var observingTextFieldDelegate: ObservingTextFieldDelegate?
|
||||
public weak var moleculeDelegate: MoleculeDelegateProtocol?
|
||||
public weak var alertDelegate: (MVMCoreAlertDelegateProtocol & NSObjectProtocol)?
|
||||
public weak var topAlertDelegate: (MVMCoreTopAlertDelegateProtocol & NSObjectProtocol)?
|
||||
|
||||
open override func setAll(withDelegate delegate: Any) {
|
||||
super.setAll(withDelegate: delegate)
|
||||
@ -26,6 +28,8 @@ open class MVMCoreUIDelegateObject: DelegateObject {
|
||||
uiTextViewDelegate = delegate as? UITextViewDelegate
|
||||
observingTextFieldDelegate = delegate as? ObservingTextFieldDelegate
|
||||
moleculeDelegate = delegate as? MoleculeDelegateProtocol
|
||||
alertDelegate = delegate as? (MVMCoreAlertDelegateProtocol & NSObjectProtocol)
|
||||
topAlertDelegate = delegate as? (MVMCoreTopAlertDelegateProtocol & NSObjectProtocol)
|
||||
}
|
||||
|
||||
class func delegateObject(from controller: MVMCoreViewControllerProtocol?) -> MVMCoreUIDelegateObject? {
|
||||
|
||||
21
MVMCoreUI/TopAlert/MVMCoreGlobalTopAlertDelegateProtocol.h
Normal file
21
MVMCoreUI/TopAlert/MVMCoreGlobalTopAlertDelegateProtocol.h
Normal file
@ -0,0 +1,21 @@
|
||||
//
|
||||
// MVMCoreGlobalTopAlertDelegateProtocol.h
|
||||
// MVMCore
|
||||
//
|
||||
// Created by Pfeil, Scott Robert on 1/2/18.
|
||||
// Copyright © 2018 myverizon. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <MVMCoreUI/MVMCoreTopAlertViewProtocol.h>
|
||||
@class MVMCoreTopAlertObject;
|
||||
|
||||
@protocol MVMCoreGlobalTopAlertDelegateProtocol <NSObject>
|
||||
|
||||
- (NSOperationQueuePriority)priorityForTopAlertByObject:(nonnull MVMCoreTopAlertObject *)object;
|
||||
|
||||
@optional
|
||||
|
||||
- (nonnull UIView <MVMCoreTopAlertViewProtocol>*)getTopAlertView;
|
||||
|
||||
@end
|
||||
@ -0,0 +1,22 @@
|
||||
//
|
||||
// MVMCoreTopAlertAnimationDelegateProtocol.h
|
||||
// mobilefirst
|
||||
//
|
||||
// Created by Scott Pfeil on 6/4/16.
|
||||
// Copyright © 2016 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@protocol MVMCoreTopAlertAnimationDelegateProtocol
|
||||
|
||||
// Called when the top alert is starting an animation
|
||||
- (void)topAlertViewBeginAnimation;
|
||||
|
||||
// Called when the top alert is ending an animation
|
||||
- (void)topAlertViewFinishAnimation;
|
||||
|
||||
// Called when the top alert close button was pressed by the user
|
||||
- (void)topAlertCloseButtonPressed;
|
||||
|
||||
@end
|
||||
23
MVMCoreUI/TopAlert/MVMCoreTopAlertDelegateProtocol.h
Normal file
23
MVMCoreUI/TopAlert/MVMCoreTopAlertDelegateProtocol.h
Normal file
@ -0,0 +1,23 @@
|
||||
//
|
||||
// MVMCoreTopAlertDelegateProtocol.h
|
||||
// mobilefirst
|
||||
//
|
||||
// Created by Scott Pfeil on 6/4/16.
|
||||
// Copyright © 2016 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@class MVMCoreTopAlertObject;
|
||||
|
||||
@protocol MVMCoreTopAlertDelegateProtocol
|
||||
|
||||
@optional
|
||||
|
||||
- (void)topAlertViewShown:(nonnull id)topAlert topAlertObject:(nonnull MVMCoreTopAlertObject *)topAlertObject;
|
||||
- (void)topAlertViewDismissed:(nonnull id)topAlert;
|
||||
|
||||
// Called when the top alert is pressed. Determines if we should load the option the default way or not.
|
||||
- (BOOL)shouldLoadTopAlertAction:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData;
|
||||
|
||||
@end
|
||||
64
MVMCoreUI/TopAlert/MVMCoreTopAlertObject.h
Normal file
64
MVMCoreUI/TopAlert/MVMCoreTopAlertObject.h
Normal file
@ -0,0 +1,64 @@
|
||||
//
|
||||
// MVMCoreTopAlertObject.h
|
||||
// mobilefirst
|
||||
//
|
||||
// Created by Scott Pfeil on 5/24/16.
|
||||
// Copyright © 2016 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <MVMCoreUI/MVMCoreTopAlertDelegateProtocol.h>
|
||||
|
||||
extern NSUInteger const TopAlertDismissTime;
|
||||
|
||||
@interface MVMCoreTopAlertObject : NSObject
|
||||
|
||||
@property (nonatomic) BOOL persistent;
|
||||
@property (nullable, nonatomic) NSString *type;
|
||||
@property (nonatomic) NSOperationQueuePriority queuePriority;
|
||||
|
||||
// The text
|
||||
@property (nullable, strong, nonatomic) NSString *title;
|
||||
@property (nullable, strong, nonatomic) NSString *message;
|
||||
@property (nullable, strong, nonatomic) NSString *topMessage;
|
||||
|
||||
// For the button.
|
||||
@property (nullable, strong, nonatomic) NSDictionary *buttonMap;
|
||||
@property (nullable, strong, nonatomic) NSDictionary *additionalData;
|
||||
@property (nonatomic) BOOL useCloseButton;
|
||||
|
||||
// For non action map driven button.
|
||||
@property (nullable, strong, nonatomic) NSString *buttonTitle;
|
||||
@property (nullable, copy, nonatomic) void (^userActionHandler)(id _Nonnull sender);
|
||||
|
||||
@property (nullable, weak, nonatomic) NSObject <MVMCoreTopAlertDelegateProtocol> *delegate;
|
||||
|
||||
// This is used to ensure legacy style stays intact with new changes
|
||||
@property (nonatomic) BOOL useNewStyle;
|
||||
|
||||
// The page type used for the top alert
|
||||
@property (nullable, strong, nonatomic) NSString *pageType;
|
||||
|
||||
// image name or url used imageviews
|
||||
@property (nullable, strong, nonatomic) NSString *imageNameOrURL;
|
||||
@property (nullable, strong, nonatomic) NSString *aboveTextImageString;
|
||||
|
||||
// If 0, uses default 5 seconds.
|
||||
@property (nonatomic) NSInteger topAlertDismissTime;
|
||||
|
||||
// Server can set color.
|
||||
@property (nullable, strong, nonatomic) UIColor *backgroundColor;
|
||||
@property (nullable, strong, nonatomic) UIColor *textColor;
|
||||
|
||||
// The full top alert json. Currently only used for molecular.
|
||||
@property (nullable, strong, nonatomic) NSDictionary *json;
|
||||
|
||||
- (nullable instancetype)initWithResponseInfo:(nullable NSDictionary *)responseInfo;
|
||||
|
||||
- (nullable instancetype)initWithType:(nullable NSString *)type message:(nullable NSString *)message;
|
||||
|
||||
- (nullable instancetype)initWithType:(nullable NSString *)type message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage persistent:(BOOL)persistent actionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData;
|
||||
|
||||
- (nullable instancetype)initWithType:(nullable NSString *)type message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage persistent:(BOOL)persistent buttonTitle:(nullable NSString *)buttonTitle userActionHandler:(nullable void (^)(id _Nonnull sender))userActionHandler;
|
||||
|
||||
@end
|
||||
94
MVMCoreUI/TopAlert/MVMCoreTopAlertObject.m
Normal file
94
MVMCoreUI/TopAlert/MVMCoreTopAlertObject.m
Normal file
@ -0,0 +1,94 @@
|
||||
//
|
||||
// MVMCoreTopAlertObject.m
|
||||
// mobilefirst
|
||||
//
|
||||
// Created by Scott Pfeil on 5/24/16.
|
||||
// Copyright © 2016 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
#import "MVMCoreTopAlertObject.h"
|
||||
#import <MVMCore/NSDictionary+MFConvenience.h>
|
||||
#import <MVMCore/MVMCoreGetterUtility.h>
|
||||
#import <MVMCore/MVMCoreJSONConstants.h>
|
||||
#import "MVMCoreAlertHandler.h"
|
||||
|
||||
NSUInteger const TopAlertDismissTime = 5;
|
||||
|
||||
@implementation MVMCoreTopAlertObject
|
||||
|
||||
- (nullable instancetype)initWithResponseInfo:(nullable NSDictionary *)responseInfo {
|
||||
if (self = [super init]) {
|
||||
|
||||
self.type = [responseInfo string:KeyType];
|
||||
self.persistent = [[responseInfo stringForKey:KeyMessageStyle] isEqualToString:ValueMessageStyleTopPersistent];
|
||||
|
||||
self.title = [responseInfo string:KeyMessage];
|
||||
self.message = [responseInfo string:KeyUserMessage];
|
||||
self.buttonMap = [responseInfo dict:KeyButtonMap];
|
||||
self.topMessage = [responseInfo string:KeyTopMessage];
|
||||
self.imageNameOrURL = [responseInfo string:@"topAlertImageUrl"];
|
||||
self.aboveTextImageString = [responseInfo string:@"topAlertImageURLAboveText"];
|
||||
|
||||
NSString *color = [responseInfo string:@"topAlertColor"];
|
||||
if (color) {
|
||||
self.backgroundColor = [MVMCoreGetterUtility getColorForHexString:color];
|
||||
}
|
||||
color = [responseInfo string:@"messageColor"];
|
||||
if (color) {
|
||||
self.textColor = [MVMCoreGetterUtility getColorForHexString:color];
|
||||
}
|
||||
|
||||
// The default is yes if not sent by server (for legacy to work as is)
|
||||
NSNumber *closeButton = [responseInfo optionalNumberForKey:KeyCloseButton];
|
||||
if (closeButton != nil) {
|
||||
self.useCloseButton = [closeButton boolValue];
|
||||
} else {
|
||||
self.useCloseButton = YES;
|
||||
}
|
||||
|
||||
self.useNewStyle = [responseInfo boolForKey:@"newTopAlertStyle"];
|
||||
|
||||
// Server driven dismiss time.
|
||||
NSNumber *topAlertTime = [responseInfo optionalNumberForKey:@"topAlertTime"];
|
||||
if (topAlertTime != nil) {
|
||||
self.topAlertDismissTime = [topAlertTime integerValue];
|
||||
}
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (nullable instancetype)initWithType:(nullable NSString *)type message:(nullable NSString *)message {
|
||||
return [self initWithType:type message:nil subMessage:message persistent:NO actionMap:nil additionalData:nil];
|
||||
}
|
||||
|
||||
- (nullable instancetype)initWithType:(nullable NSString *)type message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage persistent:(BOOL)persistent actionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData {
|
||||
|
||||
if (self = [super init]) {
|
||||
|
||||
self.type = type;
|
||||
self.persistent = persistent;
|
||||
|
||||
self.title = message;
|
||||
self.message = subMessage;
|
||||
self.buttonMap = actionMap;
|
||||
self.additionalData = additionalData;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (nullable instancetype)initWithType:(nullable NSString *)type message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage persistent:(BOOL)persistent buttonTitle:(nullable NSString *)buttonTitle userActionHandler:(nullable void (^)(id _Nonnull sender))userActionHandler {
|
||||
|
||||
if (self = [super init]) {
|
||||
|
||||
self.type = type;
|
||||
self.persistent = persistent;
|
||||
|
||||
self.title = message;
|
||||
self.message = subMessage;
|
||||
self.buttonTitle = buttonTitle;
|
||||
self.userActionHandler = userActionHandler;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
||||
33
MVMCoreUI/TopAlert/MVMCoreTopAlertOperation.h
Normal file
33
MVMCoreUI/TopAlert/MVMCoreTopAlertOperation.h
Normal file
@ -0,0 +1,33 @@
|
||||
//
|
||||
// MVMCoreTopAlertOperation.h
|
||||
// mobilefirst
|
||||
//
|
||||
// Created by Scott Pfeil on 6/4/16.
|
||||
// Copyright © 2016 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
#import <MVMCore/MVMCoreOperation.h>
|
||||
#import <MVMCoreUI/MVMCoreTopAlertAnimationDelegateProtocol.h>
|
||||
|
||||
@class MVMCoreTopAlertObject;
|
||||
|
||||
@interface MVMCoreTopAlertOperation : MVMCoreOperation <MVMCoreTopAlertAnimationDelegateProtocol>
|
||||
|
||||
@property (readonly, getter=isPaused) BOOL paused;
|
||||
|
||||
@property (nonatomic) BOOL reAddAfterCancel;
|
||||
|
||||
@property (nonnull, nonatomic, strong) MVMCoreTopAlertObject *topAlertObject;
|
||||
|
||||
- (nullable instancetype)initWithTopAlertObject:(nonnull MVMCoreTopAlertObject *)topAlertObject;
|
||||
|
||||
/// Updates the operation with a new object
|
||||
- (void)updateWithTopAlertObject:(nonnull MVMCoreTopAlertObject *)topAlertObject;
|
||||
|
||||
// Pauses the operation. Temporarily removes any alert.
|
||||
- (void)pause;
|
||||
|
||||
// Unpauses the operation, resuming any alert.
|
||||
- (void)unpause;
|
||||
|
||||
@end
|
||||
263
MVMCoreUI/TopAlert/MVMCoreTopAlertOperation.m
Normal file
263
MVMCoreUI/TopAlert/MVMCoreTopAlertOperation.m
Normal file
@ -0,0 +1,263 @@
|
||||
//
|
||||
// MVMCoreTopAlertOperation.m
|
||||
// mobilefirst
|
||||
//
|
||||
// Created by Scott Pfeil on 6/4/16.
|
||||
// Copyright © 2016 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
#import "MVMCoreTopAlertOperation.h"
|
||||
#import "MVMCoreTopAlertObject.h"
|
||||
#import "MVMCoreAlertHandler.h"
|
||||
#import <MVMCoreUI/MVMCoreUI-Swift.h>
|
||||
|
||||
@interface MVMCoreTopAlertOperation () {
|
||||
__block BOOL _paused;
|
||||
__block BOOL _displayed;
|
||||
__block BOOL _animating;
|
||||
}
|
||||
|
||||
@property (readwrite, getter=isPaused) BOOL paused;
|
||||
@property (readwrite, getter=isDisplayed) BOOL displayed;
|
||||
@property (readwrite, getter=isAnimating) BOOL animating;
|
||||
|
||||
// For thread safety
|
||||
@property (strong, nonatomic) dispatch_queue_t pausedQueue;
|
||||
@property (strong, nonatomic) dispatch_queue_t displayedQueue;
|
||||
@property (strong, nonatomic) dispatch_queue_t animatingQueue;
|
||||
|
||||
@property (nonatomic, strong) dispatch_source_t timerSource;
|
||||
|
||||
@end
|
||||
|
||||
@implementation MVMCoreTopAlertOperation
|
||||
|
||||
- (instancetype)init {
|
||||
|
||||
self = [super init];
|
||||
if (self) {
|
||||
self.pausedQueue = dispatch_queue_create("paused", DISPATCH_QUEUE_CONCURRENT);
|
||||
self.displayedQueue = dispatch_queue_create("displayed", DISPATCH_QUEUE_CONCURRENT);
|
||||
self.animatingQueue = dispatch_queue_create("animating", DISPATCH_QUEUE_CONCURRENT);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (nullable instancetype)initWithTopAlertObject:(nonnull MVMCoreTopAlertObject *)topAlertObject {
|
||||
|
||||
if (self = [self init]) {
|
||||
self.topAlertObject = topAlertObject;
|
||||
|
||||
// Sets the queue priority for various types of alerts.
|
||||
self.queuePriority = [[CoreUIObject sharedInstance].globalTopAlertDelegate priorityForTopAlertByObject:topAlertObject];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)updateWithTopAlertObject:(nonnull MVMCoreTopAlertObject *)topAlertObject {
|
||||
self.topAlertObject = topAlertObject;
|
||||
self.queuePriority = [[CoreUIObject sharedInstance].globalTopAlertDelegate priorityForTopAlertByObject:topAlertObject];
|
||||
if (self.isExecuting && !self.isCancelled && !self.isPaused) {
|
||||
[self updateDismissTimer];
|
||||
UIView <MVMCoreTopAlertViewProtocol>*topAlertView = [[CoreUIObject sharedInstance].globalTopAlertDelegate getTopAlertView];
|
||||
if ([topAlertView respondsToSelector:@selector(updateTopAlertWith:)]) {
|
||||
[topAlertView updateTopAlertWith:topAlertObject];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)isPaused {
|
||||
__block BOOL isPaused;
|
||||
dispatch_sync(self.pausedQueue, ^{
|
||||
isPaused = self->_paused;
|
||||
});
|
||||
return isPaused;
|
||||
}
|
||||
|
||||
- (void)setPaused:(BOOL)paused {
|
||||
dispatch_barrier_async(self.pausedQueue, ^{
|
||||
self->_paused = paused;
|
||||
});
|
||||
}
|
||||
|
||||
- (BOOL)isDisplayed {
|
||||
__block BOOL isDisplayed;
|
||||
dispatch_sync(self.displayedQueue, ^{
|
||||
isDisplayed = self->_displayed;
|
||||
});
|
||||
return isDisplayed;
|
||||
}
|
||||
|
||||
- (void)setDisplayed:(BOOL)displayed {
|
||||
dispatch_barrier_async(self.displayedQueue, ^{
|
||||
self->_displayed = displayed;
|
||||
});
|
||||
}
|
||||
|
||||
- (BOOL)isAnimating {
|
||||
__block BOOL isAnimating;
|
||||
dispatch_sync(self.animatingQueue, ^{
|
||||
isAnimating = self->_animating;
|
||||
});
|
||||
return isAnimating;
|
||||
}
|
||||
|
||||
- (void)setAnimating:(BOOL)animating {
|
||||
dispatch_barrier_async(self.animatingQueue, ^{
|
||||
self->_animating = animating;
|
||||
});
|
||||
}
|
||||
|
||||
- (void)main {
|
||||
|
||||
// Always check for cancellation before launching the task.
|
||||
if ([self checkAndHandleForCancellation]) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Do nothing if paused
|
||||
if (!self.isPaused) {
|
||||
|
||||
// Display alert only if alerts aren't supressed.
|
||||
if (![[MVMCoreAlertHandler sharedAlertHandler] mfAlertsSupressed]) {
|
||||
|
||||
// Show
|
||||
if (![[CoreUIObject sharedInstance].globalTopAlertDelegate respondsToSelector:@selector(getTopAlertView)]) {
|
||||
|
||||
// Needs to be a top alert view....
|
||||
[self markAsFinished];
|
||||
} else {
|
||||
UIView <MVMCoreTopAlertViewProtocol>*topAlertView = [[CoreUIObject sharedInstance].globalTopAlertDelegate getTopAlertView];
|
||||
[topAlertView showWithTopAlertObject:self.topAlertObject animationDelegate:self completionHandler:^(BOOL finished) {
|
||||
|
||||
self.displayed = YES;
|
||||
if (self.isCancelled) {
|
||||
|
||||
// Cancelled, dismiss immediately.
|
||||
[self dismissAlertView:YES forceful:YES];
|
||||
} else if (self.isPaused) {
|
||||
|
||||
// Paused, dismiss for the time being if persistent.
|
||||
[self dismissAlertView:!self.topAlertObject.persistent forceful:YES];
|
||||
} else {
|
||||
[self updateDismissTimer];
|
||||
}
|
||||
}];
|
||||
}
|
||||
} else {
|
||||
[self pause];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Updates the timer to dismiss the top alert.
|
||||
- (void)updateDismissTimer {
|
||||
if (self.timerSource) {
|
||||
dispatch_source_cancel(self.timerSource);
|
||||
}
|
||||
if (self.topAlertObject.persistent) {
|
||||
return;
|
||||
}
|
||||
|
||||
NSInteger dismissTime;
|
||||
if (self.topAlertObject.topAlertDismissTime > 0) {
|
||||
dismissTime = self.topAlertObject.topAlertDismissTime;
|
||||
} else {
|
||||
dismissTime = TopAlertDismissTime;
|
||||
}
|
||||
|
||||
self.timerSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue());
|
||||
dispatch_source_set_timer(self.timerSource, dispatch_time(DISPATCH_TIME_NOW, dismissTime * NSEC_PER_SEC), DISPATCH_TIME_FOREVER, (1ull * NSEC_PER_SEC) / 10);
|
||||
|
||||
__weak typeof(self) weakSelf = self;
|
||||
dispatch_source_set_event_handler(self.timerSource, ^{
|
||||
if (weakSelf.isFinished || [weakSelf checkAndHandleForCancellation]) {
|
||||
return;
|
||||
}
|
||||
[weakSelf dismissAlertView:YES forceful:NO];
|
||||
});
|
||||
dispatch_resume(self.timerSource);
|
||||
}
|
||||
|
||||
- (void)cancel {
|
||||
[super cancel];
|
||||
|
||||
// Do nothing if animating.
|
||||
if (!self.isAnimating) {
|
||||
|
||||
if (self.isDisplayed) {
|
||||
[self dismissAlertView:YES forceful:YES];
|
||||
} else if (self.isExecuting) {
|
||||
[self markAsFinished];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)dismissAlertView:(BOOL)andFinish forceful:(BOOL)forceful {
|
||||
if (self.timerSource) {
|
||||
dispatch_source_cancel(self.timerSource);
|
||||
}
|
||||
if (self.isDisplayed && !self.isAnimating) {
|
||||
|
||||
// Dismisses.
|
||||
[[[CoreUIObject sharedInstance].globalTopAlertDelegate getTopAlertView] hideAlertView:forceful completionHandler:^(BOOL finished) {
|
||||
|
||||
self.displayed = NO;
|
||||
if (andFinish) {
|
||||
[self markAsFinished];
|
||||
}
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)pause {
|
||||
|
||||
if (!self.paused) {
|
||||
[self willChangeValueForKey:@"isPaused"];
|
||||
self.paused = YES;
|
||||
[self didChangeValueForKey:@"isPaused"];
|
||||
}
|
||||
[self dismissAlertView:!self.topAlertObject.persistent forceful:YES];
|
||||
}
|
||||
|
||||
- (void)unpause {
|
||||
|
||||
if (self.paused) {
|
||||
[self willChangeValueForKey:@"isPaused"];
|
||||
self.paused = NO;
|
||||
[self didChangeValueForKey:@"isPaused"];
|
||||
}
|
||||
if (self.executing) {
|
||||
[self start];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Delegate functions
|
||||
|
||||
- (void)topAlertViewBeginAnimation {
|
||||
self.animating = YES;
|
||||
}
|
||||
|
||||
- (void)topAlertViewFinishAnimation {
|
||||
self.animating = NO;
|
||||
}
|
||||
|
||||
- (void)topAlertCloseButtonPressed {
|
||||
[self dismissAlertView:YES forceful:YES];
|
||||
}
|
||||
|
||||
- (id)copyWithZone:(nullable NSZone *)zone {
|
||||
MVMCoreTopAlertOperation *copyObject = [[MVMCoreTopAlertOperation alloc] init];
|
||||
copyObject.topAlertObject = self.topAlertObject;
|
||||
copyObject.paused = self.paused;
|
||||
copyObject.reAddAfterCancel = self.reAddAfterCancel;
|
||||
copyObject.queuePriority = self.queuePriority;
|
||||
for (NSOperation *dependency in self.dependencies) {
|
||||
[copyObject addDependency:dependency];
|
||||
}
|
||||
copyObject.name = self.name;
|
||||
copyObject.qualityOfService = self.qualityOfService;
|
||||
return copyObject;
|
||||
}
|
||||
|
||||
@end
|
||||
28
MVMCoreUI/TopAlert/MVMCoreTopAlertViewProtocol.h
Normal file
28
MVMCoreUI/TopAlert/MVMCoreTopAlertViewProtocol.h
Normal file
@ -0,0 +1,28 @@
|
||||
//
|
||||
// MVMCoreTopAlertViewProtocol.h
|
||||
// MVMCore
|
||||
//
|
||||
// Created by Pfeil, Scott Robert on 1/2/18.
|
||||
// Copyright © 2018 myverizon. All rights reserved.
|
||||
//
|
||||
|
||||
#import <MVMCoreUI/MVMCoreTopAlertAnimationDelegateProtocol.h>
|
||||
@class MVMCoreTopAlertObject;
|
||||
|
||||
@protocol MVMCoreTopAlertViewProtocol
|
||||
|
||||
@optional
|
||||
|
||||
// Show based on the object
|
||||
- (void)showWithTopAlertObject:(nullable MVMCoreTopAlertObject *)topAlertObject animationDelegate:(nonnull id <MVMCoreTopAlertAnimationDelegateProtocol>)animationDelegate completionHandler:(void (^ __nullable)(BOOL finished))completionHandler;
|
||||
|
||||
// Hides
|
||||
- (void)hideAlertView:(BOOL)forceful completionHandler:(void (^ __nullable)(BOOL finished))completionHandler;
|
||||
|
||||
// Collapses the notification if it has a short top message. Otherwise removes notification.
|
||||
- (void)collapseNotification;
|
||||
|
||||
/// Updates the existing top alert with the new object
|
||||
- (void)updateTopAlertWith:(nullable MVMCoreTopAlertObject *)topAlertObject;
|
||||
|
||||
@end
|
||||
@ -7,7 +7,7 @@
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <MVMCore/MVMCoreTopAlertAnimationDelegateProtocol.h>
|
||||
#import <MVMCoreUI/MVMCoreTopAlertAnimationDelegateProtocol.h>
|
||||
#import <MVMCore/MVMCoreViewProtocol.h>
|
||||
|
||||
@class Button;
|
||||
|
||||
@ -19,8 +19,7 @@
|
||||
#import "MFStyler.h"
|
||||
#import "MVMCoreUISession.h"
|
||||
#import <MVMCoreUI/MVMCoreUI-Swift.h>
|
||||
|
||||
@import MVMCore.MVMCoreTopAlertDelegateProtocol;
|
||||
#import "MVMCoreTopAlertDelegateProtocol.h"
|
||||
|
||||
@implementation MVMCoreUITopAlertBaseView
|
||||
|
||||
|
||||
@ -8,7 +8,7 @@
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <MVMCoreUI/MVMCoreUITopAlertBaseView.h>
|
||||
#import <MVMCore/MVMCoreTopAlertAnimationDelegateProtocol.h>
|
||||
#import <MVMCoreUI/MVMCoreTopAlertAnimationDelegateProtocol.h>
|
||||
|
||||
@class PrimaryButton;
|
||||
@class MVMCoreUITopAlertShortView;
|
||||
|
||||
@ -10,8 +10,8 @@
|
||||
#import "MVMCoreUITopAlertShortView.h"
|
||||
#import "MVMCoreUITopAlertMainView.h"
|
||||
#import <MVMCore/MVMCoreDispatchUtility.h>
|
||||
#import <MVMCore/MVMCoreTopAlertObject.h>
|
||||
#import <MVMCore/MVMCoreAlertHandler.h>
|
||||
#import <MVMCoreUI/MVMCoreTopAlertObject.h>
|
||||
#import <MVMCoreUI/MVMCoreAlertHandler.h>
|
||||
#import <MVMCore/MVMCoreBlockOperation.h>
|
||||
#import <MVMCore/MVMCoreNavigationHandler.h>
|
||||
#import "MFStyler.h"
|
||||
|
||||
@ -8,7 +8,7 @@
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <MVMCoreUI/MVMCoreUITopAlertBaseView.h>
|
||||
#import <MVMCore/MVMCoreTopAlertAnimationDelegateProtocol.h>
|
||||
#import <MVMCoreUI/MVMCoreTopAlertAnimationDelegateProtocol.h>
|
||||
|
||||
@class PillButton;
|
||||
@class MVMCoreTopAlertObject;
|
||||
|
||||
@ -11,9 +11,9 @@
|
||||
#import "NSLayoutConstraint+MFConvenience.h"
|
||||
#import <MVMCore/NSDictionary+MFConvenience.h>
|
||||
#import <MVMCore/MVMCoreDispatchUtility.h>
|
||||
#import <MVMCore/MVMCoreTopAlertObject.h>
|
||||
#import <MVMCoreUI/MVMCoreTopAlertObject.h>
|
||||
#import "UIColor+MFConvenience.h"
|
||||
#import <MVMCore/MVMCoreAlertHandler.h>
|
||||
#import <MVMCoreUI/MVMCoreAlertHandler.h>
|
||||
#import <MVMCoreUI/MVMCoreUI-Swift.h>
|
||||
#import <MVMCore/MVMCoreJSONConstants.h>
|
||||
#import "MVMCoreUICommonViewsUtility.h"
|
||||
|
||||
@ -28,7 +28,15 @@ public extension MVMCoreUITopAlertView {
|
||||
|
||||
/// Checks for new top alert json
|
||||
@objc private func responseJSONUpdated(notification: Notification) {
|
||||
guard let responseJSON = (notification.userInfo?[String(describing: MVMCoreLoadObject.self)] as? MVMCoreLoadObject)?.responseJSON,
|
||||
guard let loadObject = (notification.userInfo?[String(describing: MVMCoreLoadObject.self)] as? MVMCoreLoadObject) else { return }
|
||||
|
||||
// Dismiss any top alerts that server wants us to dismiss/
|
||||
if let disableType = loadObject.responseInfoMap?.optionalStringForKey("disableType") {
|
||||
MVMCoreAlertHandler.shared()?.hidePersistentTopAlertView(ofType: disableType)
|
||||
}
|
||||
|
||||
// Show any new top alert.
|
||||
guard let responseJSON = loadObject.responseJSON,
|
||||
let json = responseJSON.optionalDictionaryForKey("TopNotification"),
|
||||
let model = decodeTopNotification(with: json, delegateObject: getDelegateObject()) else { return }
|
||||
showTopAlert(with: model)
|
||||
|
||||
@ -7,12 +7,12 @@
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
@import MVMCore.MVMCoreTopAlertAnimationDelegateProtocol;
|
||||
@import MVMCore.MVMCoreLoadDelegateProtocol;
|
||||
@import MVMCore.MVMCoreActionDelegateProtocol;
|
||||
@import MVMCore.MVMCorePresentationDelegateProtocol;
|
||||
@import MVMCore.MVMCoreTopAlertViewProtocol;
|
||||
@import MVMCore.MVMCoreViewProtocol;
|
||||
#import <MVMCoreUI/MVMCoreTopAlertAnimationDelegateProtocol.h>
|
||||
#import <MVMCoreUI/MVMCoreTopAlertViewProtocol.h>
|
||||
#import <MVMCoreUI/ButtonDelegateProtocol.h>
|
||||
|
||||
@class MVMCoreTopAlertObject;
|
||||
|
||||
@ -17,13 +17,13 @@
|
||||
#import "MVMCoreUISession.h"
|
||||
#import "MVMCoreUIUtility.h"
|
||||
#import <MVMCoreUI/MVMCoreUI-Swift.h>
|
||||
@import MVMCore.MVMCoreTopAlertObject;
|
||||
#import <MVMCoreUI/MVMCoreTopAlertObject.h>
|
||||
@import MVMCore.MVMCoreLoadHandler;
|
||||
@import MVMCore.MVMCoreNavigationHandler;
|
||||
@import MVMCore.MVMCoreBlockOperation;
|
||||
@import MVMCore.MVMCoreAlertObject;
|
||||
#import <MVMCoreUI/MVMCoreAlertObject.h>
|
||||
@import MVMCore.MVMCoreActionHandler;
|
||||
@import MVMCore.MVMCoreAlertHandler;
|
||||
#import <MVMCoreUI/MVMCoreAlertHandler.h>
|
||||
@import MVMCore.NSDictionary_MFConvenience;
|
||||
@import MVMCore.MVMCoreRequestParameters;
|
||||
@import MVMCore.MVMCoreJSONConstants;
|
||||
@ -274,7 +274,9 @@ NSString * const MFAccTopAlertClosed = @"Top alert notification is closed.";
|
||||
[weakSelf.topAlertObject.delegate topAlertViewDismissed:view];
|
||||
}
|
||||
[operation markAsFinished];
|
||||
completionHandler(finished);
|
||||
if (completionHandler) {
|
||||
completionHandler(finished);
|
||||
}
|
||||
weakSelf.topAlertObject = nil;
|
||||
[MVMCoreDispatchUtility performBlockOnMainThread:^{
|
||||
[weakSelf setStatusBarColor:[UIColor whiteColor] statusBarStyle:UIStatusBarStyleDefault];
|
||||
|
||||
@ -44,6 +44,11 @@ extern NSString * const KeyFieldKey;
|
||||
extern NSString * const KeyRequired;
|
||||
extern NSString * const KeySourceModel;
|
||||
|
||||
extern NSString * const KeyActionTypePopup;
|
||||
extern NSString * const KeyActionTypeAlert;
|
||||
extern NSString * const KeyActionTypeTopAlert;
|
||||
extern NSString * const KeyActionTypeCollapseNotification;
|
||||
|
||||
#pragma mark - Values
|
||||
|
||||
extern NSString * const StringY;
|
||||
|
||||
@ -42,6 +42,10 @@ NSString * const KeyIsHidden = @"isHidden";
|
||||
NSString * const KeyIsOpaque = @"isOpaque";
|
||||
NSString * const KeySourceModel = @"sourceModel";
|
||||
|
||||
NSString * const KeyActionTypePopup = @"popup";
|
||||
NSString * const KeyActionTypeAlert = @"alert";
|
||||
NSString * const KeyActionTypeTopAlert = @"topAlert";
|
||||
NSString * const KeyActionTypeCollapseNotification = @"collapseNotification";
|
||||
|
||||
#pragma mark - Values
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user