From f5c178bdfd234a58c2733d6391d108b5839309b5 Mon Sep 17 00:00:00 2001 From: zu Date: Tue, 7 Sep 2021 23:05:43 +0800 Subject: [PATCH] =?UTF-8?q?=E7=BD=91=E7=BB=9C=E5=B1=82=E5=AE=8C=E5=96=84?= =?UTF-8?q?=EF=BC=9Btabbar=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Podfile | 1 + Podfile.lock | 6 +- xplan-ios.xcodeproj/project.pbxproj | 58 ++++- xplan-ios/AppDelegate.m | 6 +- .../Assets.xcassets/Tabbar/Contents.json | 6 + .../Contents.json | 22 ++ .../tab_discover_normal@2x.png | Bin 0 -> 1522 bytes .../tab_discover_normal@3x.png | Bin 0 -> 2748 bytes .../Contents.json | 22 ++ .../tab_discover_selected@2x.png | Bin 0 -> 1937 bytes .../tab_discover_selected@3x.png | Bin 0 -> 2609 bytes .../Contents.json | 22 ++ .../tab_gameHome_normal@2x.png | Bin 0 -> 1572 bytes .../tab_gameHome_normal@3x.png | Bin 0 -> 2684 bytes .../Contents.json | 22 ++ .../tab_gameHome_selected@2x.png | Bin 0 -> 1852 bytes .../tab_gameHome_selected@3x.png | Bin 0 -> 2375 bytes .../tab_game_normal.imageset/Contents.json | 22 ++ .../tab_game_normal@2x.png | Bin 0 -> 2804 bytes .../tab_game_normal@3x.png | Bin 0 -> 5513 bytes .../tab_game_selected.imageset/Contents.json | 22 ++ .../tab_game_selected@2x.png | Bin 0 -> 2779 bytes .../tab_game_selected@3x.png | Bin 0 -> 5450 bytes .../tab_message_normal.imageset/Contents.json | 22 ++ .../tab_message_normal@2x.png | Bin 0 -> 1051 bytes .../tab_message_normal@3x.png | Bin 0 -> 2055 bytes .../Contents.json | 22 ++ .../tab_message_selected@2x.png | Bin 0 -> 1231 bytes .../tab_message_selected@3x.png | Bin 0 -> 2421 bytes .../tab_mine_normal.imageset/Contents.json | 22 ++ .../tab_mine_normal@2x.png | Bin 0 -> 1357 bytes .../tab_mine_normal@3x.png | Bin 0 -> 2314 bytes .../tab_mine_selected.imageset/Contents.json | 22 ++ .../tab_mine_selected@2x.png | Bin 0 -> 1686 bytes .../tab_mine_selected@3x.png | Bin 0 -> 2441 bytes .../Tabbar/tabbar_bg.imageset/Contents.json | 22 ++ .../tabbar_bg.imageset/tabbar_bg@2x.png | Bin 0 -> 104 bytes .../tabbar_bg.imageset/tabbar_bg@3x.png | Bin 0 -> 114 bytes xplan-ios/Base/Base.pch | 7 + xplan-ios/{Main => Base}/MVP/Api/Api.h | 0 xplan-ios/{Main => Base}/MVP/Api/Api.m | 0 xplan-ios/Base/MVP/Model/AccountInfoStorage.h | 25 ++ xplan-ios/Base/MVP/Model/AccountInfoStorage.m | 89 +++++++ xplan-ios/Base/MVP/Model/AccountModel.h | 24 ++ xplan-ios/Base/MVP/Model/AccountModel.m | 12 + xplan-ios/Base/MVP/Model/BaseModel.h | 20 ++ xplan-ios/Base/MVP/Model/BaseModel.m | 12 + .../Base/MVP/Model/NSObject+AutoCoding.h | 25 ++ .../Base/MVP/Model/NSObject+AutoCoding.m | 245 ++++++++++++++++++ .../MVP/Presenter/BaseMvpPresenter.h | 2 +- .../MVP/Presenter/BaseMvpPresenter.m | 5 +- .../MVP/Protocol/BaseMvpProtocol.h | 0 .../MVP/View/MvpViewController.h | 2 +- .../MVP/View/MvpViewController.m | 0 xplan-ios/Base/Net/HttpRequestHelper.h | 23 +- xplan-ios/Base/Net/HttpRequestHelper.m | 114 ++++---- xplan-ios/Base/UI/BaseNavigationController.h | 16 ++ xplan-ios/Base/UI/BaseNavigationController.m | 36 +++ xplan-ios/Base/UI/BaseViewController.m | 14 - xplan-ios/Main/Login/Api/Api+Login.m | 4 +- .../Main/Login/Presenter/LoginPresenter.m | 4 +- .../Main/Login/View/LoginViewController.m | 14 +- xplan-ios/Main/Tabbar/Api+Main.h | 18 ++ xplan-ios/Main/Tabbar/Api+Main.m | 16 ++ xplan-ios/Main/Tabbar/MainPresenter.h | 18 ++ xplan-ios/Main/Tabbar/MainPresenter.m | 35 +++ xplan-ios/Main/Tabbar/MainProtocol.h | 18 ++ .../Main/{ => Tabbar}/TabbarViewController.h | 4 +- xplan-ios/Main/Tabbar/TabbarViewController.m | 85 ++++++ xplan-ios/Main/TabbarViewController.m | 22 -- 70 files changed, 1094 insertions(+), 134 deletions(-) create mode 100644 xplan-ios/Assets.xcassets/Tabbar/Contents.json create mode 100644 xplan-ios/Assets.xcassets/Tabbar/tab_discover_normal.imageset/Contents.json create mode 100644 xplan-ios/Assets.xcassets/Tabbar/tab_discover_normal.imageset/tab_discover_normal@2x.png create mode 100644 xplan-ios/Assets.xcassets/Tabbar/tab_discover_normal.imageset/tab_discover_normal@3x.png create mode 100644 xplan-ios/Assets.xcassets/Tabbar/tab_discover_selected.imageset/Contents.json create mode 100644 xplan-ios/Assets.xcassets/Tabbar/tab_discover_selected.imageset/tab_discover_selected@2x.png create mode 100644 xplan-ios/Assets.xcassets/Tabbar/tab_discover_selected.imageset/tab_discover_selected@3x.png create mode 100644 xplan-ios/Assets.xcassets/Tabbar/tab_gameHome_normal.imageset/Contents.json create mode 100644 xplan-ios/Assets.xcassets/Tabbar/tab_gameHome_normal.imageset/tab_gameHome_normal@2x.png create mode 100644 xplan-ios/Assets.xcassets/Tabbar/tab_gameHome_normal.imageset/tab_gameHome_normal@3x.png create mode 100644 xplan-ios/Assets.xcassets/Tabbar/tab_gameHome_selected.imageset/Contents.json create mode 100644 xplan-ios/Assets.xcassets/Tabbar/tab_gameHome_selected.imageset/tab_gameHome_selected@2x.png create mode 100644 xplan-ios/Assets.xcassets/Tabbar/tab_gameHome_selected.imageset/tab_gameHome_selected@3x.png create mode 100644 xplan-ios/Assets.xcassets/Tabbar/tab_game_normal.imageset/Contents.json create mode 100644 xplan-ios/Assets.xcassets/Tabbar/tab_game_normal.imageset/tab_game_normal@2x.png create mode 100644 xplan-ios/Assets.xcassets/Tabbar/tab_game_normal.imageset/tab_game_normal@3x.png create mode 100644 xplan-ios/Assets.xcassets/Tabbar/tab_game_selected.imageset/Contents.json create mode 100644 xplan-ios/Assets.xcassets/Tabbar/tab_game_selected.imageset/tab_game_selected@2x.png create mode 100644 xplan-ios/Assets.xcassets/Tabbar/tab_game_selected.imageset/tab_game_selected@3x.png create mode 100644 xplan-ios/Assets.xcassets/Tabbar/tab_message_normal.imageset/Contents.json create mode 100644 xplan-ios/Assets.xcassets/Tabbar/tab_message_normal.imageset/tab_message_normal@2x.png create mode 100644 xplan-ios/Assets.xcassets/Tabbar/tab_message_normal.imageset/tab_message_normal@3x.png create mode 100644 xplan-ios/Assets.xcassets/Tabbar/tab_message_selected.imageset/Contents.json create mode 100644 xplan-ios/Assets.xcassets/Tabbar/tab_message_selected.imageset/tab_message_selected@2x.png create mode 100644 xplan-ios/Assets.xcassets/Tabbar/tab_message_selected.imageset/tab_message_selected@3x.png create mode 100644 xplan-ios/Assets.xcassets/Tabbar/tab_mine_normal.imageset/Contents.json create mode 100644 xplan-ios/Assets.xcassets/Tabbar/tab_mine_normal.imageset/tab_mine_normal@2x.png create mode 100644 xplan-ios/Assets.xcassets/Tabbar/tab_mine_normal.imageset/tab_mine_normal@3x.png create mode 100644 xplan-ios/Assets.xcassets/Tabbar/tab_mine_selected.imageset/Contents.json create mode 100644 xplan-ios/Assets.xcassets/Tabbar/tab_mine_selected.imageset/tab_mine_selected@2x.png create mode 100644 xplan-ios/Assets.xcassets/Tabbar/tab_mine_selected.imageset/tab_mine_selected@3x.png create mode 100644 xplan-ios/Assets.xcassets/Tabbar/tabbar_bg.imageset/Contents.json create mode 100644 xplan-ios/Assets.xcassets/Tabbar/tabbar_bg.imageset/tabbar_bg@2x.png create mode 100644 xplan-ios/Assets.xcassets/Tabbar/tabbar_bg.imageset/tabbar_bg@3x.png rename xplan-ios/{Main => Base}/MVP/Api/Api.h (100%) rename xplan-ios/{Main => Base}/MVP/Api/Api.m (100%) create mode 100644 xplan-ios/Base/MVP/Model/AccountInfoStorage.h create mode 100644 xplan-ios/Base/MVP/Model/AccountInfoStorage.m create mode 100644 xplan-ios/Base/MVP/Model/AccountModel.h create mode 100644 xplan-ios/Base/MVP/Model/AccountModel.m create mode 100644 xplan-ios/Base/MVP/Model/BaseModel.h create mode 100644 xplan-ios/Base/MVP/Model/BaseModel.m create mode 100644 xplan-ios/Base/MVP/Model/NSObject+AutoCoding.h create mode 100644 xplan-ios/Base/MVP/Model/NSObject+AutoCoding.m rename xplan-ios/{Main => Base}/MVP/Presenter/BaseMvpPresenter.h (92%) rename xplan-ios/{Main => Base}/MVP/Presenter/BaseMvpPresenter.m (89%) rename xplan-ios/{Main => Base}/MVP/Protocol/BaseMvpProtocol.h (100%) rename xplan-ios/{Main => Base}/MVP/View/MvpViewController.h (85%) rename xplan-ios/{Main => Base}/MVP/View/MvpViewController.m (100%) create mode 100644 xplan-ios/Base/UI/BaseNavigationController.h create mode 100644 xplan-ios/Base/UI/BaseNavigationController.m create mode 100644 xplan-ios/Main/Tabbar/Api+Main.h create mode 100644 xplan-ios/Main/Tabbar/Api+Main.m create mode 100644 xplan-ios/Main/Tabbar/MainPresenter.h create mode 100644 xplan-ios/Main/Tabbar/MainPresenter.m create mode 100644 xplan-ios/Main/Tabbar/MainProtocol.h rename xplan-ios/Main/{ => Tabbar}/TabbarViewController.h (50%) create mode 100644 xplan-ios/Main/Tabbar/TabbarViewController.m delete mode 100644 xplan-ios/Main/TabbarViewController.m diff --git a/Podfile b/Podfile index e1334fc8..6f9540bf 100644 --- a/Podfile +++ b/Podfile @@ -8,6 +8,7 @@ target 'xplan-ios' do # Pods for xplan-ios pod 'AFNetworking' pod 'YYText' + pod 'YYModel' pod 'Masonry' pod 'ReactiveObjC' pod 'MBProgressHUD' diff --git a/Podfile.lock b/Podfile.lock index c876a118..4cff4bb8 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -18,6 +18,7 @@ PODS: - MBProgressHUD (1.2.0) - NTESQuickPass (2.1.9) - ReactiveObjC (3.1.1) + - YYModel (1.0.4) - YYText (1.0.7) DEPENDENCIES: @@ -26,6 +27,7 @@ DEPENDENCIES: - MBProgressHUD - NTESQuickPass (~> 2.1.6) - ReactiveObjC + - YYModel - YYText SPEC REPOS: @@ -35,6 +37,7 @@ SPEC REPOS: - MBProgressHUD - NTESQuickPass - ReactiveObjC + - YYModel - YYText SPEC CHECKSUMS: @@ -43,8 +46,9 @@ SPEC CHECKSUMS: MBProgressHUD: 3ee5efcc380f6a79a7cc9b363dd669c5e1ae7406 NTESQuickPass: 8431dc52737c95883cd382c2ee75664d58f39377 ReactiveObjC: 011caa393aa0383245f2dcf9bf02e86b80b36040 + YYModel: 2a7fdd96aaa4b86a824e26d0c517de8928c04b30 YYText: 5c461d709e24d55a182d1441c41dc639a18a4849 -PODFILE CHECKSUM: f8d8c44df1ae85a1571fe37ee767fc992db1ff6b +PODFILE CHECKSUM: 34d6fc0f46b543fbcabfb886e7a531f43d5dd7f5 COCOAPODS: 1.10.1 diff --git a/xplan-ios.xcodeproj/project.pbxproj b/xplan-ios.xcodeproj/project.pbxproj index aec1b597..b323dbd7 100644 --- a/xplan-ios.xcodeproj/project.pbxproj +++ b/xplan-ios.xcodeproj/project.pbxproj @@ -7,6 +7,10 @@ objects = { /* Begin PBXBuildFile section */ + 187EEEDC26E89B32002833B2 /* BaseModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 187EEEDB26E89B32002833B2 /* BaseModel.m */; }; + 187EEEE126E89BFB002833B2 /* AccountModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 187EEEE026E89BFB002833B2 /* AccountModel.m */; }; + 187EEEF026E89FE8002833B2 /* AccountInfoStorage.m in Sources */ = {isa = PBXBuildFile; fileRef = 187EEEEE26E89FE8002833B2 /* AccountInfoStorage.m */; }; + 187EEEFE26E8A82C002833B2 /* NSObject+AutoCoding.m in Sources */ = {isa = PBXBuildFile; fileRef = 187EEEFC26E8A82C002833B2 /* NSObject+AutoCoding.m */; }; 189DD52E26DE255300AB55B1 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 189DD52D26DE255300AB55B1 /* AppDelegate.m */; }; 189DD53426DE255300AB55B1 /* TabbarViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 189DD53326DE255300AB55B1 /* TabbarViewController.m */; }; 189DD53926DE255600AB55B1 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 189DD53826DE255600AB55B1 /* Assets.xcassets */; }; @@ -29,10 +33,21 @@ 189DD75026E21D9000AB55B1 /* GCDHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 189DD74E26E21D9000AB55B1 /* GCDHelper.m */; }; 189DD75926E6003C00AB55B1 /* Api.m in Sources */ = {isa = PBXBuildFile; fileRef = 189DD75826E6003C00AB55B1 /* Api.m */; }; 189DD76226E60DDC00AB55B1 /* Api+Login.m in Sources */ = {isa = PBXBuildFile; fileRef = 189DD76126E60DDC00AB55B1 /* Api+Login.m */; }; + 18E7B1B226E8AF980064BC9B /* MainPresenter.m in Sources */ = {isa = PBXBuildFile; fileRef = 18E7B1B126E8AF980064BC9B /* MainPresenter.m */; }; + 18E7B1B726E8B2D10064BC9B /* Api+Main.m in Sources */ = {isa = PBXBuildFile; fileRef = 18E7B1B626E8B2D10064BC9B /* Api+Main.m */; }; 73FFADDC93E195344047A2EC /* Pods_xplan_ios.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CACF623970097D653132D69A /* Pods_xplan_ios.framework */; }; + 9B0E1C5926E77022005D4442 /* BaseNavigationController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B0E1C5826E77022005D4442 /* BaseNavigationController.m */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + 187EEEDA26E89B32002833B2 /* BaseModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BaseModel.h; sourceTree = ""; }; + 187EEEDB26E89B32002833B2 /* BaseModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BaseModel.m; sourceTree = ""; }; + 187EEEDF26E89BFB002833B2 /* AccountModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AccountModel.h; sourceTree = ""; }; + 187EEEE026E89BFB002833B2 /* AccountModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AccountModel.m; sourceTree = ""; }; + 187EEEEE26E89FE8002833B2 /* AccountInfoStorage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AccountInfoStorage.m; sourceTree = ""; }; + 187EEEEF26E89FE8002833B2 /* AccountInfoStorage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AccountInfoStorage.h; sourceTree = ""; }; + 187EEEFC26E8A82C002833B2 /* NSObject+AutoCoding.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSObject+AutoCoding.m"; sourceTree = ""; }; + 187EEEFD26E8A82C002833B2 /* NSObject+AutoCoding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSObject+AutoCoding.h"; sourceTree = ""; }; 189DD52926DE255300AB55B1 /* xplan-ios.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "xplan-ios.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 189DD52C26DE255300AB55B1 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 189DD52D26DE255300AB55B1 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; @@ -78,7 +93,14 @@ 189DD76026E60DDC00AB55B1 /* Api+Login.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Api+Login.h"; sourceTree = ""; }; 189DD76126E60DDC00AB55B1 /* Api+Login.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "Api+Login.m"; sourceTree = ""; }; 189DD78026E620FE00AB55B1 /* ApiHost.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ApiHost.h; sourceTree = ""; }; + 18E7B1AE26E8AD760064BC9B /* MainProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MainProtocol.h; sourceTree = ""; }; + 18E7B1B026E8AF980064BC9B /* MainPresenter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MainPresenter.h; sourceTree = ""; }; + 18E7B1B126E8AF980064BC9B /* MainPresenter.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MainPresenter.m; sourceTree = ""; }; + 18E7B1B526E8B2D10064BC9B /* Api+Main.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Api+Main.h"; sourceTree = ""; }; + 18E7B1B626E8B2D10064BC9B /* Api+Main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "Api+Main.m"; sourceTree = ""; }; 7DB00EC07F1D0ADFF900B38D /* Pods-xplan-ios.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-xplan-ios.debug.xcconfig"; path = "Target Support Files/Pods-xplan-ios/Pods-xplan-ios.debug.xcconfig"; sourceTree = ""; }; + 9B0E1C5726E77022005D4442 /* BaseNavigationController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BaseNavigationController.h; sourceTree = ""; }; + 9B0E1C5826E77022005D4442 /* BaseNavigationController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BaseNavigationController.m; sourceTree = ""; }; B66633E061B1B34177CD011C /* Pods-xplan-ios.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-xplan-ios.release.xcconfig"; path = "Target Support Files/Pods-xplan-ios/Pods-xplan-ios.release.xcconfig"; sourceTree = ""; }; CACF623970097D653132D69A /* Pods_xplan_ios.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_xplan_ios.framework; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ @@ -178,6 +200,14 @@ 189DD56026DE456100AB55B1 /* Model */ = { isa = PBXGroup; children = ( + 187EEEDA26E89B32002833B2 /* BaseModel.h */, + 187EEEDB26E89B32002833B2 /* BaseModel.m */, + 187EEEDF26E89BFB002833B2 /* AccountModel.h */, + 187EEEE026E89BFB002833B2 /* AccountModel.m */, + 187EEEEF26E89FE8002833B2 /* AccountInfoStorage.h */, + 187EEEEE26E89FE8002833B2 /* AccountInfoStorage.m */, + 187EEEFD26E8A82C002833B2 /* NSObject+AutoCoding.h */, + 187EEEFC26E8A82C002833B2 /* NSObject+AutoCoding.m */, ); path = Model; sourceTree = ""; @@ -185,10 +215,8 @@ 189DD56126DE45F800AB55B1 /* Main */ = { isa = PBXGroup; children = ( - 189DD54826DE327B00AB55B1 /* MVP */, + 18E7B1B426E8B2960064BC9B /* Tabbar */, 189DD56226DE460400AB55B1 /* Login */, - 189DD53226DE255300AB55B1 /* TabbarViewController.h */, - 189DD53326DE255300AB55B1 /* TabbarViewController.m */, ); path = Main; sourceTree = ""; @@ -208,6 +236,7 @@ 189DD56B26DF5B0900AB55B1 /* Base */ = { isa = PBXGroup; children = ( + 189DD54826DE327B00AB55B1 /* MVP */, 189DD61E26E0ED0100AB55B1 /* Net */, 189DD5A726DFA09700AB55B1 /* Tool */, 189DD56C26DF5B5400AB55B1 /* UI */, @@ -221,6 +250,8 @@ children = ( 189DD54926DE338800AB55B1 /* BaseViewController.h */, 189DD54A26DE338800AB55B1 /* BaseViewController.m */, + 9B0E1C5726E77022005D4442 /* BaseNavigationController.h */, + 9B0E1C5826E77022005D4442 /* BaseNavigationController.m */, 189DD67C26E1FD8900AB55B1 /* UIImage+Utils.h */, 189DD67D26E1FD8900AB55B1 /* UIImage+Utils.m */, 189DD68326E1FDBB00AB55B1 /* XCHUDTool.h */, @@ -332,6 +363,20 @@ path = Api; sourceTree = ""; }; + 18E7B1B426E8B2960064BC9B /* Tabbar */ = { + isa = PBXGroup; + children = ( + 18E7B1B526E8B2D10064BC9B /* Api+Main.h */, + 18E7B1B626E8B2D10064BC9B /* Api+Main.m */, + 18E7B1B026E8AF980064BC9B /* MainPresenter.h */, + 18E7B1B126E8AF980064BC9B /* MainPresenter.m */, + 18E7B1AE26E8AD760064BC9B /* MainProtocol.h */, + 189DD53226DE255300AB55B1 /* TabbarViewController.h */, + 189DD53326DE255300AB55B1 /* TabbarViewController.m */, + ); + path = Tabbar; + sourceTree = ""; + }; BFB922F5D81845AC32D1E1ED /* Frameworks */ = { isa = PBXGroup; children = ( @@ -482,18 +527,25 @@ 189DD76226E60DDC00AB55B1 /* Api+Login.m in Sources */, 189DD73E26E21C3F00AB55B1 /* YYUtility.m in Sources */, 189DD53426DE255300AB55B1 /* TabbarViewController.m in Sources */, + 187EEEFE26E8A82C002833B2 /* NSObject+AutoCoding.m in Sources */, 189DD55A26DE39D200AB55B1 /* BaseMvpPresenter.m in Sources */, 189DD6FF26E20E5900AB55B1 /* HttpRequestHelper.m in Sources */, 189DD74A26E21D8400AB55B1 /* SSKeychain.m in Sources */, 189DD68426E1FDBB00AB55B1 /* XCHUDTool.m in Sources */, 189DD73F26E21C3F00AB55B1 /* YYUtility+Carrier.m in Sources */, + 9B0E1C5926E77022005D4442 /* BaseNavigationController.m in Sources */, 189DD54B26DE338800AB55B1 /* BaseViewController.m in Sources */, + 18E7B1B726E8B2D10064BC9B /* Api+Main.m in Sources */, + 18E7B1B226E8AF980064BC9B /* MainPresenter.m in Sources */, 189DD67E26E1FD8900AB55B1 /* UIImage+Utils.m in Sources */, 189DD52E26DE255300AB55B1 /* AppDelegate.m in Sources */, 189DD56526DE465A00AB55B1 /* LoginViewController.m in Sources */, + 187EEEF026E89FE8002833B2 /* AccountInfoStorage.m in Sources */, 189DD73D26E21C3F00AB55B1 /* YYUtility+Device.m in Sources */, + 187EEEDC26E89B32002833B2 /* BaseModel.m in Sources */, 189DD74026E21C3F00AB55B1 /* YYUtility+App.m in Sources */, 189DD74526E21CCC00AB55B1 /* YYReachability.m in Sources */, + 187EEEE126E89BFB002833B2 /* AccountModel.m in Sources */, 189DD75026E21D9000AB55B1 /* GCDHelper.m in Sources */, 189DD75926E6003C00AB55B1 /* Api.m in Sources */, 189DD53F26DE255600AB55B1 /* main.m in Sources */, diff --git a/xplan-ios/AppDelegate.m b/xplan-ios/AppDelegate.m index 59247fa1..63b186ab 100644 --- a/xplan-ios/AppDelegate.m +++ b/xplan-ios/AppDelegate.m @@ -7,6 +7,7 @@ #import "AppDelegate.h" #import "TabbarViewController.h" +#import "BaseNavigationController.h" @interface AppDelegate () @@ -16,9 +17,10 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { TabbarViewController *vc = [[TabbarViewController alloc] init]; - UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc]; + BaseNavigationController *bnc = [[BaseNavigationController alloc] initWithRootViewController:vc]; + [bnc setNavigationBarHidden:YES]; self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; - self.window.rootViewController = nav; + self.window.rootViewController = bnc; [self.window makeKeyAndVisible]; return YES; } diff --git a/xplan-ios/Assets.xcassets/Tabbar/Contents.json b/xplan-ios/Assets.xcassets/Tabbar/Contents.json new file mode 100644 index 00000000..73c00596 --- /dev/null +++ b/xplan-ios/Assets.xcassets/Tabbar/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/xplan-ios/Assets.xcassets/Tabbar/tab_discover_normal.imageset/Contents.json b/xplan-ios/Assets.xcassets/Tabbar/tab_discover_normal.imageset/Contents.json new file mode 100644 index 00000000..e9625098 --- /dev/null +++ b/xplan-ios/Assets.xcassets/Tabbar/tab_discover_normal.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "tab_discover_normal@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "tab_discover_normal@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/xplan-ios/Assets.xcassets/Tabbar/tab_discover_normal.imageset/tab_discover_normal@2x.png b/xplan-ios/Assets.xcassets/Tabbar/tab_discover_normal.imageset/tab_discover_normal@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..05dbdbad4cc708614c3c753a3604fa925ddbf78b GIT binary patch literal 1522 zcmVJiLqlauOlLzwWjQ%j zJUm%BI8;MIVr*-fL_}pvO=)gxn@vt?NJnN-QE+T*mu+j9QBiD9Pi#5Pf%`LT!TDzrLqTFpOle_ZiaR@3YigHMQ*KL3 zX>M$sYiX2GQENXxUPD4;Jw01FIaNPCT|z-(K0RDOKwvvMS3y8vLqlXdJX%3OVL3Tg zJUm!IL198cV>&ukP*HJCPHb&#nN3bbXOUP~d{9wtXJ(I6RCP&5 zX+1nxad3}rZH;kmkxou4t?;6Z-l0_xAPi?(Nvo(Yms+t*NGyf=)O%FdYZ-@a*K_+}zO4 z%fr98vYC^Sdv|tqMML9>v;Y7D$Vo&&R7l6|l?hwgKoEu#K(w}6wfBAB_kG_ti6jIF ziJ*mGfuyCh2x39S>xcK7-6-}+LVrN}?(WR&IB(z)9~A!cPa}pWE=EotIdVF3aUv}8 z-t7-B_T9gH=x=Ix@OVl}Nm7b)d@w8sH!jRDF85b=M3^G+2#_ML;horru&#gK zct&9Lqi5Iei1dVhFME;;Yy);2D(?J zE$qhJ^77)6J+-Y>1~-D-{g}Wo!qk-Yb8cm2adFLU0Lf}J$`69vAUIu(f z3NWz{v2A+kxg}dsbd!4a!a}q8Bc<%{l_NBTL+HAxw5{@7rHz)U<5`lm0CKt#@pHpw zQinqx%SlsrYnJDKfJzc|*hd~r0v#JEfkaDB=!hmxm)!4;j{Bh36_1hzFM*7J2Ov-) zobSXsyB!t1?>dHQ97?pQMnVb9BDqD>MA-Ysg>gWUZ=L}jQ@1SZyH%qSt^FQ(H&E4PRJvR18G9$3%lo1U8`1Wq+((~6g-TjI~``H4VL1$I+2qNG-}hJ zmL@u5f|pRIV;DxdgM(!xztn%#>%U5P7;aUPt9WX@V}t}B&KjDLH}ZMIz)pSnMNG@o z$ZyKTS^sZsO(RpwYntJFVc2POa5ebb)@b6OuY4_HXaGU3a(5M1JPR+b(JxFRMt$8w z_Z~+zkkyi<9HWMslg*-JIXdhsziV9^%4D^S=5V!@L`_mA1Ci=XHlqy*zC3K*6vnfe zSfSM_wOXyJoPmV}5V0tX`@5e?d+y--ceTV>H6~qk5-tuE**8J|nG1V`n^*Rfrl(7# zLczo=XM1r#2;gakDiGhJ{&zWIvx^*|NP7R Y2ApLSUwHjvumAu607*qoM6N<$f?0&8RR910 literal 0 HcmV?d00001 diff --git a/xplan-ios/Assets.xcassets/Tabbar/tab_discover_normal.imageset/tab_discover_normal@3x.png b/xplan-ios/Assets.xcassets/Tabbar/tab_discover_normal.imageset/tab_discover_normal@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..09a4e8b5e365b8b49066031aa597ffdf398a04b1 GIT binary patch literal 2748 zcmWkw2|UyNA74{OC4>$_DI~{3DmG?pb1ZB#V}>!aVV60Q@Hk42j5XKXBt(u1De(w7 z;wfi&-27EiRB}C(;{SVIuiy3kd_Uj!_5HnGzuzr9)>>-6;(ibaB!#g-6M(zxf2V{P zaFxDVs}BN!Rq=L2OJHbgGULE2!#@XioHGC)YKI?P$(}fjtwkFp%@4=PdMBS=<(;|*x57LED_Rz1^@z3C=}fu z%i?l!fmxuR%gHe{A=_h_{@ffB6Bl!HDu4-tk?a8|Gf&_dpazO~hX8;Y0D;0t9CkJi z$3`OQKpOyVZRN{lXT#y{Y*rSRor}lw08%bDo5K=eYmv*d z5Dj7$>WOL+@gWpDDKx? z$PxbB?7#q_EBQ|>mgmDrv9e?U`{nEu?tl*plq&?RBS->#^la|W8JnNqQ;jtgWG2%hSgvPOch*)G=Vqs; z-n>Xow$|F&`LVga{N>YZPiq$S_pg6fmKG-3TAwsLxF-^Z__&@^`n~dQdZ@Rzs{CH! z&9Gn>64w0t*ME`|<{9b6AP{63gSH^LbbJ+Ux}`bDzdW9#&0TKUoQYU&DL)vSRSXut zbq9>8py!;ykVSD7%;uf8=L<7RgKO*H--EoU<*)(x=2S3Z)71RmbKMv28Kith*peNd zUmJe@CfKL@;-p6Yj1e<1Ebe@Z$xcskeK2WYIvTw(K;0Or+czm9>x44RkG!hm9{Bq~ z<&SSeC|?pnO}8NW!)#;aYMrFv`#Hv18>(@?VIo|qp!x)`TuAxEq|S)IuIN2hZ$EUq~8BSz(^TdeP#^xXdI+KmE~*OAqBoT@4!>eq^+(6e)R>`{ltl!yHX@6olT zFhK!Uc1$XGGFD7l<LSIRn;HxZFdo;kPyIYrQ!a4{MAlr7JeYwhEzOJBZ;8x@Lk2xEhvG^ZQWAmo-w zdtzFzpu>;%X{74tTcbh5#C?jK!B;7b^!sypMa-S8DZ116c@yP!vRpyg78~K~IN2wq z@l?sLR)Mo;^T*l(MB!P3L&pF$M!JJm(W+V`!E07l(t4(gYD4O#uWgOOU!EB}uDG)H zqKfG;X8QLm_QQ(0R>xZ7fq(xUx_5S;0qEx*;&K zTd$!Y#gwaCZl14!JSDsIY*bTXySnCUO5AcyfoLC`5q~M#QnAROAvv)#S!fKO<21b{3dWBZ{nTNSIL#_L6HjbM#R zs~Lv|b6tKRtm^MM^II~sV|_F&l_xgq5-bU^mNZz!XukIWo6}% zOVxc9S|Ur_3ue3Q9*vSzU8v~1&9M^Ch{lGYw6WTd$yRO@j08zwjO^yt#r zS(zWfb)Q1O347kxzUg&5aq6D%WUJ)xG)*aUi9S?cD}}Ktzu6?8FSwjGboSKUq{>u~ zCgiZw7uHpAjXsg(fbb@ZUGO0gY+4~o>sirXg|%&<`A+fqhV-F4i8z)i_J!l8YV|*Y zK9qe}YE!aO8Kz0cZqPcP1gGnS^9AR6$M#UTx^}c!lO~Oc?f9jdTcZ1{$}H;vwPWA2 z^+#E{4lQ!m1$r^wm&SglRT(8JNJbEG+CQY}HF}Oxsbg6-gu~kHf%>a#7xZDW)jVlH zw7bGct5Qp~(K%AfFFP3>)i<(jxp}mAcWZx$cx>LTV`!w1PfL9()tV6Q)p1xfl`Yq#!`Hidd^qULacFM;v4q*y$n7273w9TZ zlLwvh=Wm~T7*MM%{(j}!dDi3c&NxBmqz^SOFK_#Vcvgj+-P@Cy^S4=D;Thxj&U~zr z{UI3lQmQaMFAjMqw$D<_c=aGRw&tPGQd@cqoqAwITs*|fLW_IW@{-!^WIe^I+m<2K zf}$7E)VkcdVbLk+;13j)-vLkYMX|n8B_X8_%2h$d;qw`sKMvGO`d#XHoo&%&XQs&F zEr0V*fGIcjd@-238{+PeQGdE{{7v2ScQNRN?1Xl&Aa#UXW~#bqb^Nu#bwP1r&O`le z{`lqkfnRQBcg-IR4aybo?LmgLc3lo+F)Re5n4*g*AFWGaLew#|Rs4L*bK+>lIsxjT zS^u=9o3(L6(4n7}ArU8W(9?Gt=sBy{|`Bl#d%u9RCO&7u!1rkTxb(6cFgtn_v=^xaqB|R_o?6a(^8U7aBV}sHE#VanU zG^j0TPB&E{4g4Yf*^p*e$E2_r5JZ5uu($AkCf)OD+D4DBa@&ql+=;p=H>SGYPOMLh z9VSY;GwjvYf`J!QmIN_H4ufrUdSv8_7u=i7 zTG&76U0do$Nf*l$3_+m1@F`Rx;l6TL<}l%i3-ApGN;Y+7b8h?im>Qivl9oX zF2aRZ7y0|;!&n{~VKa048SR|}nmMSw^B}6}3hg=}_2H$`##alJ>O0AmRGI^`k}M$z z=4%|OkpIE%)jH(S5W4!9NPsim{T$xTsnnq$0+U=T)UOdPVF`p#LO>{Aj2DppE~fi~nJ(|7)iI zWT*diC+2CR|74~AL5TW0Z1ziA@-ub#P*m_zQSd%#^+0CzGI;qzWAtA_?P@gYA&LH1 zOYdkl>LQ2zCWHJaf&40e`z(C>Y%=L`E9W?H_eNp!Z7}F>E$DM8=T%PdVL$9-J?wQS z=bVlIpo{-bSMi^W|1Ns@Hgfn!UGrTIBxe_N$zDi>vkpPqKp3@i~eRh>v^94hnWA6lmC;E|6N4xe4YP) zoBvf#?~0cHKxg$rWAs=|?`Wt0jg~f<2E{pwyf%|uV`Zja;Z(Q|bW%OH3@Ird}Gt{FWc$)r=iv5*{{aum#K8*Ziiu`7U`!js` zg>?9AcK1he_hN4LhimqKVe?{5?`lKs1F0vu00018bW%=J00Ij6@9eIvR#r$yud9oO zg@9E^HWB;!`S#Y&MvkQM?ZK!Fe-g%+nSxVyXS7tWn7>GJF(`~Y}o?(E#V zIZxUM|NYaHK2^Pnd*sREQQWJlk5XXj^(xmoZN{8`i~4xwUnr5^%SRCUXUw&XWON@* zSIT5sXrh8O3sELhsjkT7N{b_{yJ($`Mx$}f8Y31vjdVb}GJTXeEz2zK!s$Flr81(N zJkkj@Efz}|*V!y%ootscT)1o-E0LvKaImGj%WStrdlq41?Xg`7hD)|ZA`ET8J9qBv z=kj~Ur8>8mIVT+<+eYE){~a%JYAtgrb@J}wu3fu&yZW6QPmnmhfH|EyIf?AW0Rmt7 ziBi`?tkw`~$aUx7>SDNBo}aBThiu<2K4Q-J!k6`P(c#0l4yOWo(iZF9Ch`F{EGQ}q7n(|z zuv&r#ohYo>)0Dj?zQCi9ESzQ@`1$#rpawab*EqiNF}>Z5nxa5MRW#1tdW- zl7|cHc7%oP(CKzOjgOCi8m7aQCc3C~9PH z6^DwBlHZMeGqK|)QBfAIu1+?q&1SRuQDkJ~BQ=w3-)zOQC#%iqsMPeC>awu+XxN5w zJc)ebpxZXbO=}3;+=hm*2O4i#SlMvp(xppRuB45H({X4$Ipn~L(Y`8`?`X{NnFdNh zrczMQ{P{sxIBEY7v(yJg+`V(>?unFll>|BO5r0T}y@4D`>0*yVY|7o66IPU%xql|? zr`mty49ng|NA@wSDWMQJ(jPc5E5(6X5B!-=tiw(^0!eh8m0sY<+97ZityQaj-ZuCf z3$Upm=aV^_WfNQ}sC9Zgc?L)4x`LZ zW)s|~62N50fx9BRXTH@E`8@k71b6CZXwkB4&-#K$nLV>-kpj7M7bxPHIlEH$?_c%{ XHSsB3)(!=;00000NkvXXu0mjfPofN> literal 0 HcmV?d00001 diff --git a/xplan-ios/Assets.xcassets/Tabbar/tab_discover_selected.imageset/tab_discover_selected@3x.png b/xplan-ios/Assets.xcassets/Tabbar/tab_discover_selected.imageset/tab_discover_selected@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..d7d7820ecfde5f730a1c65b734853d5149edd849 GIT binary patch literal 2609 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 LNkvXXu0mjf^xmXm literal 0 HcmV?d00001 diff --git a/xplan-ios/Assets.xcassets/Tabbar/tab_game_selected.imageset/Contents.json b/xplan-ios/Assets.xcassets/Tabbar/tab_game_selected.imageset/Contents.json new file mode 100644 index 00000000..a69f428f --- /dev/null +++ b/xplan-ios/Assets.xcassets/Tabbar/tab_game_selected.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "tab_game_selected@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "tab_game_selected@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/xplan-ios/Assets.xcassets/Tabbar/tab_game_selected.imageset/tab_game_selected@2x.png b/xplan-ios/Assets.xcassets/Tabbar/tab_game_selected.imageset/tab_game_selected@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..f8f40788ccbaeaa125ae1d8342b41b04e139ca5b GIT binary patch literal 2779 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 literal 0 HcmV?d00001 diff --git a/xplan-ios/Assets.xcassets/Tabbar/tab_game_selected.imageset/tab_game_selected@3x.png b/xplan-ios/Assets.xcassets/Tabbar/tab_game_selected.imageset/tab_game_selected@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..8f6b5580e64571cd5c34497f380e3e6769ddcaac GIT binary patch literal 5450 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 AY5)KL literal 0 HcmV?d00001 diff --git a/xplan-ios/Assets.xcassets/Tabbar/tab_message_normal.imageset/Contents.json b/xplan-ios/Assets.xcassets/Tabbar/tab_message_normal.imageset/Contents.json new file mode 100644 index 00000000..931b135f --- /dev/null +++ b/xplan-ios/Assets.xcassets/Tabbar/tab_message_normal.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "tab_message_normal@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "tab_message_normal@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/xplan-ios/Assets.xcassets/Tabbar/tab_message_normal.imageset/tab_message_normal@2x.png b/xplan-ios/Assets.xcassets/Tabbar/tab_message_normal.imageset/tab_message_normal@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..5fa6729d951ff12f5a19b67e281d5d27ecb6b6f1 GIT binary patch literal 1051 zcmV+$1mydPP)ZS6PESJX=gl zb5BosPfvJ3L19BfWK2tQLP26gL}x)kU^+ThOiXt@JX=LYVns!1O-*-CPJBs6Z8}yO-yt{LuGDlnmIXEMMY>j zI#+INnm;~XOGFcQ2>9K%ud9zpIxeh~ZvX%S zp-DtRR7l6|mDxg@Ko~}mtS+(cYqfg`7RiE;2uK=HF-D`Y@%>+=-#<)1XvTzG^}@q2 zT%9umB9Y!nQp&I9OLMx125~r-E3ew7ZJVp|Jo17PvM`t23YkZikG6GPRdxMaNzS@# z*%)|LLKzGO(HHydj}{7Q;Gmsu8t>@@WX%Q=W)22%&@_luy8E0%YP2{IiQUuG7VSgmN4B zIGn!4BEH&7lXF#U`GtG?7Et(jcJE7U=!b#P_6^lt=Bad7gXX5 zI~YQFw;lr0RH# z6|cn0`~?0D002ovPDHLkV1hz+%V_`r literal 0 HcmV?d00001 diff --git a/xplan-ios/Assets.xcassets/Tabbar/tab_message_normal.imageset/tab_message_normal@3x.png b/xplan-ios/Assets.xcassets/Tabbar/tab_message_normal.imageset/tab_message_normal@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..eb614b614bbc0814197c54087a7fe7046e65dc5d GIT binary patch literal 2055 zcmV+i2>ADjP)IaE+jd{|h8Z)}=4I8{PIWKvXoK|y0{Ynewz zYeGR{Zf%-jV2VmfZ%IdOZfu!HM{8GEgI8FCSXzWxS%hzGn>aXBKtEq@Y??+zYFAi; zJw01NKw(Wxb4*KeLP29gLuEfdUOGBgL_=moL}x)kVnRY>K0jSPK3qjbXgoYxIXP8K zOLIp?Ye+|IIXPBGMruk)Zc9pWJ3LrBI#_IKn?*!uZEKoMOm$FCc1ucdJUm%RNNq|< zaBFIpYG{>cXOu}vZBI^hZETreUWsOAl2}@VNJnc@QF>}=mT6~}Wn_?GV2oW|h+0~O zPEK}WVvSZ-fKgC*V`Gn8T!&j*hE7d*XJ(U6PI^g5Ze3i4W@VIFSb6o(oB#j- zRCH2KQve6JxCDTJfFBL`bu1ti@#Wsy&08`0`sd-`&%1_$dun1uIX5Q!`}FSQ%)q{) znT(5xdvk0_LHq0H-PY5%x2=tMXJ3+nB*cCGkBAqzwenzV*DtK zn#(@t%+ag&F>#Xl@y$1RQ7FBR8k7D_{>lA^fT+CXo_$-hiO?=~a!%HsBE}ixobh5I z-{@bzXM_);QqKQj)pge~lboZQx@B1|Eq9Xl4bf9NT8_b2gSWBc7}SQLHy);gt9&*` zp^GhT>n7otjvs*6e+BLG4Lz*|1UJkTaAtv|Hod(p_@><$1z{M3_}#wl7%mSIMveB( z1^2kz!V?%EJ0%GgUs~mJ@442i*@7^G9V@7UT2DJKxm4jcRYGW|gt4zu(#}dQa>f{E zoZF1aM0oZno{_C}iY$sak2n(r0kw!{+3eGwpkBq7M1B zm*py6bD}}wm_-bqj8q&28+}&Gr|sv~YzJQqFiS6mU~omOb<+NBXxVHy}t{Vo%S6IT8^$iDV(T@h9Q)3CwaRVypN45P? z7l+_+U^+@&X^-4B9Y>skKu!ZiE-ac`4@5N4%{!Io{)@RXk)1SfvXJHAx?cJ!(I59K zfr;LOTr_q)#Qld#^q=Q>%4&s$DVB+%-ct$FU!|S>{ybkS=5urw>5vA33>nGlT_yT@ zv0O+Q+O%{?}D@AXXghxYImNaOkM)-C-SZdLpxAB%6neCBBN@RnKWFEUzqd$R{ zLg8pwq)dj#vJ|!GpPxH;)QQF0$oAmzpxj=QV)XxZ%&jMJAPmFqZrv*}To4H%+_}km zVcf)1qDD=On?0WrBx(HvrD2+^LSvOyzyl)giU-);U%T%&15N2tcMQGc={KLoi|3sg z8k{y?*eRg+7096=v~G^*v~7~=d_G@5!Bha~qG1F>cD$fHIkjP&82J+#2th-^j<_8f zC@%$hJ>=AmV+c+}M+yoFxCF@IX*@z~+jB|v!2wEOFt_BoZmCpix_;CHEDR|WK}||M z&K!p^hkDy#R^{mIh}YTKxsP&%8Js-UgQZET{dBTj_66TPZfH#giX*4CfK7v0%s$M9 zxzDj{v~?IjPOX`QWm<$!o%NfcW=w1xl_RT$oEoq?$9}b6-m#g@n2kY<%c*-nueq&i zS#VdrHuBi9cX=+ zDAV^VZJ(q%0QoiODMHmkkW$a9MHMv=S`5E*3WE`Yny${vsJD_u4)o{)1N>3q56Q*< zSe5NqES8u#?c=AP?nl|92wWF!CJ~E0^hh&3`yrJ|t>D`NUmAjQ+;r7ywSIkleRXwl zQK?iKjaKXCvR13*a=9NKxp+MODWim%Q`rE=;P4PJ8(*g%`|^+_ literal 0 HcmV?d00001 diff --git a/xplan-ios/Assets.xcassets/Tabbar/tab_message_selected.imageset/Contents.json b/xplan-ios/Assets.xcassets/Tabbar/tab_message_selected.imageset/Contents.json new file mode 100644 index 00000000..57e79920 --- /dev/null +++ b/xplan-ios/Assets.xcassets/Tabbar/tab_message_selected.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "tab_message_selected@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "tab_message_selected@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/xplan-ios/Assets.xcassets/Tabbar/tab_message_selected.imageset/tab_message_selected@2x.png b/xplan-ios/Assets.xcassets/Tabbar/tab_message_selected.imageset/tab_message_selected@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..6971a60036551c4a1ad3fa219e86e85892456a19 GIT binary patch literal 1231 zcmV;=1Tg!FP)?OsCcXgBF_PwQq;>SROdTt)0*KM&VDnT> z??+zofm-!ZQ}1D_|DuckU_tAFTJ}s?@>5anOjqz@rT?Lb|At!jkXrX{Tk>FB@Loji zQe5zlTK6M}{2_?^WT^k7i~nJ%|Duflky-a*TJU8$>Tg@~Q(f;TgZwvf_alb=LSytu zUGhp>@>WdmUPJ99h5a;i_(oszTSo3bXZ1j3^-xprO;+((O737m>_lPoQc&{!~x!EqnSfdHQXm|0{m`QBv@YmH#S#`%hKzWvKsWr~h)I|B09X zkdyy4bND!J_fcH%cA)=YT=8n9|ACtSJZttmYV~=Z|D2Bhpp5@}TlG~=@LEakT}AF_ zHtK$y|CEvcn2-OWi~oF`|CW&dVm|C~E9Zw=_HJA9L|yKLng52E|21;>LtXA)LhWHd z?PNUco{j%)G3jEf)BoTk-1aIsD7$8R@in}tyYffsHoNd;pr=htKz(>isD1~cX(Jy ztT*oPJ{a{%uhp<@{D_FNEUQs+d!3r)teiEzbF>p@IhN%(bzPaM&TwEQuuB+p<+NJO zP_Y9-qb;LVkNqTu$dEN8Qr}qXG-Fhno4(vICGi7;g^gz@-PR8lm=a!7WW!!xGH$l# z#bWjt*<*ub4U*Mds_j~a>E&q|yM5YD_AZ95ZKB9B9ZHas{loxS9ONg&^g1qr7ydK5|)Yv2wzyvTktdO0Ja#tR~} zu8_mCf!LQwo~Kf$iy~^gBqA4wJi)ECJ*RK`B#U@KM2%NO7soEQgT!9Mk!b4la%pLW zKbIQ!iav|3ey!vN=ThTgL2oY>V3VQ7jeSzXSU9NGLHL+sTtiBpZ!ZzwIfG@1aHPmc(0pjF!aP zh)+nIO0^fqD#VnV(eiOJ5;>2eu9n|S`RqO6=0q;eW^wat+5h}Xh(of^_DbUOY_z() zhbgH(oyla<>2yYTY8VA{&%PG;#3=Fpo75A%qPXGlZ#d)U>?5Ph{qK3LI!0;z@Ry)f t%P7|H?$KX(UdvQOTUT4#z}&eV{sWq>kMWU64I2Oe002ovPDHLkV1fi4f^h%< literal 0 HcmV?d00001 diff --git a/xplan-ios/Assets.xcassets/Tabbar/tab_message_selected.imageset/tab_message_selected@3x.png b/xplan-ios/Assets.xcassets/Tabbar/tab_message_selected.imageset/tab_message_selected@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..1df1719894e82afeb3ec2207e91464cc91640177 GIT binary patch literal 2421 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 literal 0 HcmV?d00001 diff --git a/xplan-ios/Assets.xcassets/Tabbar/tab_mine_normal.imageset/Contents.json b/xplan-ios/Assets.xcassets/Tabbar/tab_mine_normal.imageset/Contents.json new file mode 100644 index 00000000..892f413e --- /dev/null +++ b/xplan-ios/Assets.xcassets/Tabbar/tab_mine_normal.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "tab_mine_normal@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "tab_mine_normal@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/xplan-ios/Assets.xcassets/Tabbar/tab_mine_normal.imageset/tab_mine_normal@2x.png b/xplan-ios/Assets.xcassets/Tabbar/tab_mine_normal.imageset/tab_mine_normal@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..6411eb10d31876c901550a41df23270a7591b63b GIT binary patch literal 1357 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 b{Q0S7vDCHxxs|*d_@$I^XcFowf|KzNuQ4MX literal 0 HcmV?d00001 diff --git a/xplan-ios/Assets.xcassets/Tabbar/tab_mine_selected.imageset/Contents.json b/xplan-ios/Assets.xcassets/Tabbar/tab_mine_selected.imageset/Contents.json new file mode 100644 index 00000000..1c1a6f8a --- /dev/null +++ b/xplan-ios/Assets.xcassets/Tabbar/tab_mine_selected.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "tab_mine_selected@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "tab_mine_selected@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/xplan-ios/Assets.xcassets/Tabbar/tab_mine_selected.imageset/tab_mine_selected@2x.png b/xplan-ios/Assets.xcassets/Tabbar/tab_mine_selected.imageset/tab_mine_selected@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..908f3a1a5d666fcf30ffc42fa2fdb90607572b48 GIT binary patch literal 1686 zcmV;H25I?;P)yBFZOpN}^}}dbIyxLhFrM z_H0`6ppXBISofWg|5&B}c(ngwmj9Mn_n2Avn3n%wLF;$7|1Nv^F?ji!kpFkI|BPAp zd9nXoN9$v%|9Q0kU_tCCf&5NY@KR9lIB@q?Oz%Eu^+aLwP*m_Od-^bW`9Wm#TSo3A zh5buf@ga%+HFNkwWAsW}@=aIqT|@0(LhL$h_B?C$Ttw|7hy5mm{40L@KWFt(Qt(ty z@KjFlS4;0$O7CGm?4gYRHgWhxVDm;_^GRLuMP2SEgZwgf_%w9*M_%)6Tk~36@FIx) zOj+?-N$x6u{5Wp+KxXw~KI|-g`!aX=JZkoMv;Tau|9`Llj9T}4v;T~t|B#*kl$!sX zk^i5M{~(M0Tt@C+LhX02|AealiKPE{p#PVa|2b{yP z^H^N)GhXaIY4$;7^?qCQQd01FrT;d5`Zjp^S%&p~TlHR)C{#c&2Fm_jGdge_Ql^ zTJ%YE@ltZ}U1#w#UF%2Lya)gQ09$lYPE!B_3274&Y9RUTX=qtlMMOg?6%F?D@a^pE>gveIxVN;irJ?v?(XhF3MFZq zwgd?f+$k=_DJ}(qrD$=70(JjCeP=gXy1V(xIXw5icOd6HGn+XZYKlpZ#a6qemNqt) zOYOE=Pz)RAp5AMMDcHU;JuF?v%IyMtc3mtMZ{&Ap%nt)%lop#4_H)I+o=+9pD-;Sb zngo-ESuHJi+l1Z+@->7^(uQy^%#Gx*&3zB;_nB$&Y0?mpi$+on7-qO=r^plpRa z^7@caJt^pvP!z+n^*s0NYCuQ`f`QV&`JDv|gMxyBgAuagk6>3!;EKX_3k4kVw$?xw zmsXdF1d#&UIOG+Nbp!^|lL2ch+9hxW$NTK;?Cj}@pvW}jF$%k}za?8<&?F}(GYjza zBm-a&wy?@;q6r=(9%uuw7XsF>%8R2SBcpW0$CJb((O580(TiE-!%}ytRQjHdhDbCi zEeBcU>CG~k4AJ5)b9YCyNRjF6vLrwfU_e@00E!?(H_H%qdA5&F7HA?ZX_90~$TVg) ztGvitrBZnt;p6RNNY)}&dG(`-yaE_Nr9xJ-%A4hKd0d=aPegWVH1_}m*fmXUKm4|jBQ zjC}ngRJ@AEHit<66o-F~jsIx`Q-8&k0Wb~yGqeDav4>#kw zD=XUF_q!o6v4M$}Z$-tB_lx)*dadYe!rKJE3{3P%Gq^aKM?QsX*|nsz^LtCn54Bp| z*`jVyFL9u#bF|F;*jCdh!rk*nUu!sUW*50;(Y)~Rc_NC#HaCZ>VYkDkD_1u;?1l+o go0*BIDJCa>0b`JAPQB07TmS$707*qoM6N<$g1y&nYXATM literal 0 HcmV?d00001 diff --git a/xplan-ios/Assets.xcassets/Tabbar/tab_mine_selected.imageset/tab_mine_selected@3x.png b/xplan-ios/Assets.xcassets/Tabbar/tab_mine_selected.imageset/tab_mine_selected@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..012439bee65d89a544254a1d95ada3ec3aaed5ed GIT binary patch literal 2441 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 literal 0 HcmV?d00001 diff --git a/xplan-ios/Assets.xcassets/Tabbar/tabbar_bg.imageset/tabbar_bg@3x.png b/xplan-ios/Assets.xcassets/Tabbar/tabbar_bg.imageset/tabbar_bg@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..02bcff0426f70a6d1f10bd92afbcbe9ad4fdd56a GIT binary patch literal 114 zcmeAS@N?(olHy`uVBq!ia0y~yU`YkCCo?hwN!bNvAPMFGpAc6qEz3pccAWuowLD!M sLn>~)J;=xizopr04oC*hX4Qo literal 0 HcmV?d00001 diff --git a/xplan-ios/Base/Base.pch b/xplan-ios/Base/Base.pch index 68008557..c2eef4fd 100644 --- a/xplan-ios/Base/Base.pch +++ b/xplan-ios/Base/Base.pch @@ -11,6 +11,7 @@ // Include any system framework and library headers here that should be included in all compilation units. // You will also need to set the Prefix Header build setting of one or more of your targets to reference this file. #import +#import #define AppName ([[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleDisplayName"]) @@ -36,6 +37,12 @@ isPhoneXSeries = [[UIApplication sharedApplication] delegate].window.safeAreaIns #define ThemeButtonGradientStartColor UIColorFromRGB(0x218EFF) /// 按钮渐变色 end #define ThemeButtonGradientEndColor UIColorFromRGB(0x7727E4) +/// Tabbar 未选中 +#define ThemeTabbarNormalColor UIColorFromRGB(0x555574) +/// Tabbar 选中 +#define ThemeTabbarSelectedColor UIColorFromRGB(0x248CFE) +/// Tabbar 背景色 +#define ThemeTabbarBackgroundColor UIColorFromRGB(0x2A2A39) #define KScreenWidth [[UIScreen mainScreen] bounds].size.width #define KScreenHeight [[UIScreen mainScreen] bounds].size.height diff --git a/xplan-ios/Main/MVP/Api/Api.h b/xplan-ios/Base/MVP/Api/Api.h similarity index 100% rename from xplan-ios/Main/MVP/Api/Api.h rename to xplan-ios/Base/MVP/Api/Api.h diff --git a/xplan-ios/Main/MVP/Api/Api.m b/xplan-ios/Base/MVP/Api/Api.m similarity index 100% rename from xplan-ios/Main/MVP/Api/Api.m rename to xplan-ios/Base/MVP/Api/Api.m diff --git a/xplan-ios/Base/MVP/Model/AccountInfoStorage.h b/xplan-ios/Base/MVP/Model/AccountInfoStorage.h new file mode 100644 index 00000000..8c60a8d7 --- /dev/null +++ b/xplan-ios/Base/MVP/Model/AccountInfoStorage.h @@ -0,0 +1,25 @@ +// +// DataUtils.h +// YYFaceAuth +// +// Created by chenran on 16/10/18. +// Copyright © 2016年 zhangji. All rights reserved. +// + +#import +#import "AccountModel.h" +@interface AccountInfoStorage : NSObject + ++ (instancetype)instance; + +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype)new NS_UNAVAILABLE; +- (id)copy NS_UNAVAILABLE; +- (id)mutableCopy NS_UNAVAILABLE; + +- (AccountModel *)getCurrentAccountInfo; +- (void)saveAccountInfo:(AccountModel *)accountInfo; +- (void)saveTicket:(NSString *)ticket; +- (NSString *)getTicket; +- (NSString *)getUid; +@end diff --git a/xplan-ios/Base/MVP/Model/AccountInfoStorage.m b/xplan-ios/Base/MVP/Model/AccountInfoStorage.m new file mode 100644 index 00000000..32382bd2 --- /dev/null +++ b/xplan-ios/Base/MVP/Model/AccountInfoStorage.m @@ -0,0 +1,89 @@ +// +// DataUtils.m +// YYFaceAuth +// +// Created by chenran on 16/10/18. +// Copyright © 2016年 zhangji. All rights reserved. +// +#define kFileName @"AccountInfo.data" +#define kDataKey @"accountInfo" + +#import "AccountInfoStorage.h" + +@interface AccountInfoStorage() + +@property (nonatomic, copy) NSString *ticket; +@property (nonatomic, strong) AccountModel *accountModel; + +@end + +@implementation AccountInfoStorage + +static AccountInfoStorage *_instance = nil; + ++ (AccountInfoStorage *)instance { + + static dispatch_once_t onceToken; + + dispatch_once(&onceToken, ^{ + _instance = [[self alloc] init]; + }) ; + + return _instance; +} + +-(NSString *) getFilePath{ + NSArray *array = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); + NSString *path = [[array objectAtIndex:0] stringByAppendingPathComponent:kFileName]; + if (![[NSFileManager defaultManager] fileExistsAtPath:path]) { + [[NSFileManager defaultManager] createFileAtPath:path contents:nil attributes:nil]; + } + return path; +} + +- (AccountModel *)getCurrentAccountInfo +{ + if (self.accountModel != nil) { + return self.accountModel; + } + NSData *data = [[NSData alloc] initWithContentsOfFile:[self getFilePath]]; + + NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data]; + //解档出数据模型 + self.accountModel = [unarchiver decodeObjectForKey:kDataKey]; + [unarchiver finishDecoding];//一定不要忘记finishDecoding,否则会报错 + return self.accountModel; +} + +- (void)saveAccountInfo:(AccountModel *)accountInfo +{ + if (accountInfo == nil) { + accountInfo = [[AccountModel alloc] init]; + } + self.accountModel = accountInfo; + NSMutableData *data = [[NSMutableData alloc] init]; + NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data]; + [archiver encodeObject:accountInfo forKey:kDataKey]; + [archiver finishEncoding]; + [data writeToFile:[self getFilePath] atomically:YES]; +} + +- (void)saveTicket:(NSString *)t +{ + self.ticket = t; +} + +- (NSString *)getTicket +{ + return self.ticket; +} + +- (NSString *)getUid +{ + AccountModel *am = [self getCurrentAccountInfo]; + if (am == nil) { + return @""; + } + return am.uid; +} +@end diff --git a/xplan-ios/Base/MVP/Model/AccountModel.h b/xplan-ios/Base/MVP/Model/AccountModel.h new file mode 100644 index 00000000..ce532cd7 --- /dev/null +++ b/xplan-ios/Base/MVP/Model/AccountModel.h @@ -0,0 +1,24 @@ +// +// TokenModel.h +// xplan-ios +// +// Created by zu on 2021/9/8. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface AccountModel : NSObject + +@property (nonatomic , assign) NSString *uid; +@property (nonatomic , copy) NSString *jti; +@property (nonatomic , copy) NSString *token_type; +@property (nonatomic , copy) NSString *refresh_token; +@property (nonatomic , copy) NSString *netEaseToken; +@property (nonatomic , copy) NSString *access_token; +@property (nonatomic , assign) NSNumber *expires_in; + +@end + +NS_ASSUME_NONNULL_END diff --git a/xplan-ios/Base/MVP/Model/AccountModel.m b/xplan-ios/Base/MVP/Model/AccountModel.m new file mode 100644 index 00000000..de7f90e4 --- /dev/null +++ b/xplan-ios/Base/MVP/Model/AccountModel.m @@ -0,0 +1,12 @@ +// +// TokenModel.m +// xplan-ios +// +// Created by zu on 2021/9/8. +// + +#import "AccountModel.h" + +@implementation AccountModel + +@end diff --git a/xplan-ios/Base/MVP/Model/BaseModel.h b/xplan-ios/Base/MVP/Model/BaseModel.h new file mode 100644 index 00000000..48f1e813 --- /dev/null +++ b/xplan-ios/Base/MVP/Model/BaseModel.h @@ -0,0 +1,20 @@ +// +// BaseModel.h +// xplan-ios +// +// Created by zu on 2021/9/8. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface BaseModel : NSObject + +@property (nonatomic , strong) id data; +@property (nonatomic , assign) NSInteger code; +@property (nonatomic , copy) NSString *message; + +@end + +NS_ASSUME_NONNULL_END diff --git a/xplan-ios/Base/MVP/Model/BaseModel.m b/xplan-ios/Base/MVP/Model/BaseModel.m new file mode 100644 index 00000000..d158734d --- /dev/null +++ b/xplan-ios/Base/MVP/Model/BaseModel.m @@ -0,0 +1,12 @@ +// +// BaseModel.m +// xplan-ios +// +// Created by zu on 2021/9/8. +// + +#import "BaseModel.h" + +@implementation BaseModel + +@end diff --git a/xplan-ios/Base/MVP/Model/NSObject+AutoCoding.h b/xplan-ios/Base/MVP/Model/NSObject+AutoCoding.h new file mode 100644 index 00000000..76b615f7 --- /dev/null +++ b/xplan-ios/Base/MVP/Model/NSObject+AutoCoding.h @@ -0,0 +1,25 @@ +// +// NSObject+AutoCoding.h +// YYMobileFramework +// +// Created by wuwei on 14/6/13. +// Copyright (c) 2014年 YY Inc. All rights reserved. +// + +#import + +@interface NSObject (AutoCoding) + +// Coding ++ (NSDictionary *)codableProperties; +- (void)setWithCoder:(NSCoder *)aDecoder; + +// Properties access +- (NSDictionary *)codableProperties; +- (NSDictionary *)dictionaryRepresentation; + +// Loading / Saving ++ (instancetype)objectWithContentsOfFile:(NSString *)path; +- (BOOL)writeToFile:(NSString *)filePath atomically:(BOOL)useAuxiliaryFile; + +@end \ No newline at end of file diff --git a/xplan-ios/Base/MVP/Model/NSObject+AutoCoding.m b/xplan-ios/Base/MVP/Model/NSObject+AutoCoding.m new file mode 100644 index 00000000..b66e955e --- /dev/null +++ b/xplan-ios/Base/MVP/Model/NSObject+AutoCoding.m @@ -0,0 +1,245 @@ +// +// NSObject+AutoCoding.m +// YYMobileFramework +// +// Created by wuwei on 14/6/13. +// Copyright (c) 2014年 YY Inc. All rights reserved. +// + +#import "NSObject+AutoCoding.h" +#import + +#pragma GCC diagnostic ignored "-Wgnu" + +static NSString *const AutocodingException = @"AutocodingException"; + +@implementation NSObject (AutoCoding) + ++ (BOOL)supportsSecureCoding +{ + return YES; +} + ++ (instancetype)objectWithContentsOfFile:(NSString *)filePath +{ + //load the file + NSData *data = [NSData dataWithContentsOfFile:filePath]; + + //attempt to deserialise data as a plist + id object = nil; + if (data) + { + NSPropertyListFormat format; + object = [NSPropertyListSerialization propertyListWithData:data options:NSPropertyListImmutable format:&format error:NULL]; + + //success? + if (object) + { + //check if object is an NSCoded unarchive + if ([object respondsToSelector:@selector(objectForKey:)] && [(NSDictionary *)object objectForKey:@"$archiver"]) + { + object = [NSKeyedUnarchiver unarchiveObjectWithData:data]; + } + } + else + { + //return raw data + object = data; + } + } + + //return object + return object; +} + +- (BOOL)writeToFile:(NSString *)filePath atomically:(BOOL)useAuxiliaryFile +{ + //note: NSData, NSDictionary and NSArray already implement this method + //and do not save using NSCoding, however the objectWithContentsOfFile + //method will correctly recover these objects anyway + + //archive object + NSData *data = [NSKeyedArchiver archivedDataWithRootObject:self]; + return [data writeToFile:filePath atomically:useAuxiliaryFile]; +} + ++ (NSDictionary *)codableProperties +{ + unsigned int propertyCount; + __autoreleasing NSMutableDictionary *codableProperties = [NSMutableDictionary dictionary]; + objc_property_t *properties = class_copyPropertyList(self, &propertyCount); + for (unsigned int i = 0; i < propertyCount; i++) + { + //get property name + objc_property_t property = properties[i]; + const char *propertyName = property_getName(property); + __autoreleasing NSString *key = @(propertyName); + + //check if codable + //get property type + Class propertyClass = nil; + char *typeEncoding = property_copyAttributeValue(property, "T"); + switch (typeEncoding[0]) + { + case '@': + { + if (strlen(typeEncoding) >= 3) + { + char *className = strndup(typeEncoding + 2, strlen(typeEncoding) - 3); + __autoreleasing NSString *name = @(className); + NSRange range = [name rangeOfString:@"<"]; + if (range.location != NSNotFound) + { + name = [name substringToIndex:range.location]; + } + propertyClass = NSClassFromString(name) ?: [NSObject class]; + free(className); + } + break; + } + case 'c': + case 'i': + case 's': + case 'l': + case 'q': + case 'C': + case 'I': + case 'S': + case 'L': + case 'Q': + case 'f': + case 'd': + case 'B': + { + propertyClass = [NSNumber class]; + break; + } + case '{': + { + propertyClass = [NSValue class]; + break; + } + default: + break; + } + free(typeEncoding); + + if (propertyClass && [propertyClass conformsToProtocol:@protocol(NSSecureCoding)]) + { + //check if there is a backing ivar + char *ivar = property_copyAttributeValue(property, "V"); + if (ivar) + { + //check if ivar has KVC-compliant name + __autoreleasing NSString *ivarName = @(ivar); + if ([ivarName isEqualToString:key] || [ivarName isEqualToString:[@"_" stringByAppendingString:key]]) + { + //no setter, but setValue:forKey: will still work + codableProperties[key] = propertyClass; + } + free(ivar); + } + else + { + //check if property is dynamic and readwrite + char *dynamic = property_copyAttributeValue(property, "D"); + char *readonly = property_copyAttributeValue(property, "R"); + if (dynamic && !readonly) + { + //no ivar, but setValue:forKey: will still work + codableProperties[key] = propertyClass; + } + free(dynamic); + free(readonly); + } + } + } + + free(properties); + return codableProperties; +} + +- (NSDictionary *)codableProperties +{ + __autoreleasing NSDictionary *codableProperties = objc_getAssociatedObject([self class], _cmd); + if (!codableProperties) + { + codableProperties = [NSMutableDictionary dictionary]; + Class subclass = [self class]; + while (subclass != [NSObject class]) + { + [(NSMutableDictionary *)codableProperties addEntriesFromDictionary:[subclass codableProperties]]; + subclass = [subclass superclass]; + } + codableProperties = [NSDictionary dictionaryWithDictionary:codableProperties]; + + //make the association atomically so that we don't need to bother with an @synchronize + objc_setAssociatedObject([self class], _cmd, codableProperties, OBJC_ASSOCIATION_RETAIN); + } + return codableProperties; +} + +- (NSDictionary *)dictionaryRepresentation +{ + NSMutableDictionary *dict = [NSMutableDictionary dictionary]; + for (__unsafe_unretained NSString *key in [self codableProperties]) + { + id value = [self valueForKey:key]; + if (value) + dict[key] = value; + else + dict[key] = @"nil"; + } + return dict; +} + +- (void)setWithCoder:(NSCoder *)aDecoder +{ + BOOL secureAvailable = [aDecoder respondsToSelector:@selector(decodeObjectOfClass:forKey:)]; + BOOL secureSupported = [[self class] supportsSecureCoding]; + NSDictionary *properties = [self codableProperties]; + for (NSString *key in properties) + { + id object = nil; + Class propertyClass = properties[key]; + if (secureAvailable) + { + if ([propertyClass isEqual:[NSMutableAttributedString class]]) { + continue; + } + object = [aDecoder decodeObjectOfClass:propertyClass forKey:key]; + } + else + { + if ([propertyClass isEqual:[NSMutableAttributedString class]]) { + continue; + } + object = [aDecoder decodeObjectForKey:key]; + } + if (object) + { + if (secureSupported && ![object isKindOfClass:propertyClass]) + { + [NSException raise:AutocodingException format:@"Expected '%@' to be a %@, but was actually a %@", key, propertyClass, [object class]]; + } + [self setValue:object forKey:key]; + } + } +} + +- (instancetype)initWithCoder:(NSCoder *)aDecoder +{ + [self setWithCoder:aDecoder]; + return self; +} + +- (void)encodeWithCoder:(NSCoder *)aCoder +{ + for (NSString *key in [self codableProperties]) + { + id object = [self valueForKey:key]; + if (object) [aCoder encodeObject:object forKey:key]; + } +} + +@end diff --git a/xplan-ios/Main/MVP/Presenter/BaseMvpPresenter.h b/xplan-ios/Base/MVP/Presenter/BaseMvpPresenter.h similarity index 92% rename from xplan-ios/Main/MVP/Presenter/BaseMvpPresenter.h rename to xplan-ios/Base/MVP/Presenter/BaseMvpPresenter.h index 69307d88..7fe8a91b 100644 --- a/xplan-ios/Main/MVP/Presenter/BaseMvpPresenter.h +++ b/xplan-ios/Base/MVP/Presenter/BaseMvpPresenter.h @@ -11,7 +11,7 @@ NS_ASSUME_NONNULL_BEGIN -typedef void(^HttpSuccess)(id _Nonnull data); +typedef void(^HttpSuccess)(BaseModel *data); typedef void(^HttpFail)(NSNumber * _Nonnull code, NSString * _Nullable msg); @interface BaseMvpPresenter : NSObject diff --git a/xplan-ios/Main/MVP/Presenter/BaseMvpPresenter.m b/xplan-ios/Base/MVP/Presenter/BaseMvpPresenter.m similarity index 89% rename from xplan-ios/Main/MVP/Presenter/BaseMvpPresenter.m rename to xplan-ios/Base/MVP/Presenter/BaseMvpPresenter.m index 974593e3..b6dd58a5 100644 --- a/xplan-ios/Main/MVP/Presenter/BaseMvpPresenter.m +++ b/xplan-ios/Base/MVP/Presenter/BaseMvpPresenter.m @@ -28,7 +28,10 @@ if (loading) { [XCHUDTool showLoading]; } - return ^(id _Nullable data, NSNumber * _Nonnull code, NSString * _Nullable msg) { + return ^(BaseModel *data, NSNumber * _Nonnull code, NSString * _Nullable msg) { + if (loading) { + [XCHUDTool hideHUD]; + } if (data != nil) { NSString *message = [data valueForKey:@"message"]; NSNumber *resCode = [data valueForKey:@"code"]; diff --git a/xplan-ios/Main/MVP/Protocol/BaseMvpProtocol.h b/xplan-ios/Base/MVP/Protocol/BaseMvpProtocol.h similarity index 100% rename from xplan-ios/Main/MVP/Protocol/BaseMvpProtocol.h rename to xplan-ios/Base/MVP/Protocol/BaseMvpProtocol.h diff --git a/xplan-ios/Main/MVP/View/MvpViewController.h b/xplan-ios/Base/MVP/View/MvpViewController.h similarity index 85% rename from xplan-ios/Main/MVP/View/MvpViewController.h rename to xplan-ios/Base/MVP/View/MvpViewController.h index 27a404cc..b86f249b 100644 --- a/xplan-ios/Main/MVP/View/MvpViewController.h +++ b/xplan-ios/Base/MVP/View/MvpViewController.h @@ -12,7 +12,7 @@ NS_ASSUME_NONNULL_BEGIN @interface MvpViewController : BaseViewController -@property (nonatomic,strong) __kindof T presenter; +@property (nonatomic, strong) __kindof T presenter; - (__kindof T)createPresenter; diff --git a/xplan-ios/Main/MVP/View/MvpViewController.m b/xplan-ios/Base/MVP/View/MvpViewController.m similarity index 100% rename from xplan-ios/Main/MVP/View/MvpViewController.m rename to xplan-ios/Base/MVP/View/MvpViewController.m diff --git a/xplan-ios/Base/Net/HttpRequestHelper.h b/xplan-ios/Base/Net/HttpRequestHelper.h index 6fcfd512..f3e85f45 100644 --- a/xplan-ios/Base/Net/HttpRequestHelper.h +++ b/xplan-ios/Base/Net/HttpRequestHelper.h @@ -6,6 +6,7 @@ // #import +#import "BaseModel.h" typedef NS_ENUM(NSUInteger, HttpRequestHelperMethod) { HttpRequestHelperMethodPOST, @@ -14,39 +15,27 @@ typedef NS_ENUM(NSUInteger, HttpRequestHelperMethod) { static dispatch_once_t onceToken; -typedef void(^HttpRequestHelperCompletion)(id _Nullable data, NSNumber * _Nullable code, NSString * _Nullable msg); +typedef void(^HttpRequestHelperCompletion)(BaseModel* _Nullable data, NSNumber * _Nullable code, NSString * _Nullable msg); NS_ASSUME_NONNULL_BEGIN @interface HttpRequestHelper : NSObject + (void)GET:(NSString *)method - params:(NSDictionary *)params - success:(void (^)(id data))success - failure:(void (^)(NSNumber *resCode, NSString *message))failure; - -+ (void)GET:(NSString *)interfaceUrl - method:(NSString *)method - params:(NSDictionary *)params - success:(void (^)(id data))success +params:(NSDictionary *)params +success:(void (^)(BaseModel *data))success failure:(void (^)(NSNumber *resCode, NSString *message))failure; + (void)POST:(NSString *)method params:(NSDictionary *)params - success:(void (^)(id data))success - failure:(void (^)(NSNumber *resCode, NSString *message))failure; - -+ (void)POST:(NSString *)interfaceUrl - method:(NSString *)method - params:(NSDictionary *)params - success:(void (^)(id data))success + success:(void (^)(BaseModel *data))success failure:(void (^)(NSNumber *resCode, NSString *message))failure; + (void)request:(NSString *)url method:(HttpRequestHelperMethod)method params:(NSDictionary *)params - success:(void (^)(id data))success + success:(void (^)(BaseModel *data))success failure:(void (^)(NSNumber *resCode, NSString *message))failure; + (void)request:(NSString *)path diff --git a/xplan-ios/Base/Net/HttpRequestHelper.m b/xplan-ios/Base/Net/HttpRequestHelper.m index 03e50974..8d1b10e7 100644 --- a/xplan-ios/Base/Net/HttpRequestHelper.m +++ b/xplan-ios/Base/Net/HttpRequestHelper.m @@ -8,6 +8,7 @@ #import "HttpRequestHelper.h" #import "ApiHost.h" #import "YYUtility.h" +#import "AccountInfoStorage.h" #import "YYReachability.h" #import @@ -18,8 +19,7 @@ static AFHTTPSessionManager *manager = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ - NSURLSessionConfiguration * config = [NSURLSessionConfiguration defaultSessionConfiguration]; - manager = [[AFHTTPSessionManager alloc]initWithSessionConfiguration:config]; + manager = [[AFHTTPSessionManager manager]initWithBaseURL:[NSURL URLWithString:API_HOST_URL]]; manager.requestSerializer.timeoutInterval = 15; manager.responseSerializer = [AFJSONResponseSerializer serializer]; manager.requestSerializer.HTTPShouldHandleCookies = YES; @@ -36,83 +36,72 @@ + (void)GET:(NSString *)method params:(NSDictionary *)params - success:(void (^)(id data))success + success:(void (^)(BaseModel *data))success failure:(void (^)(NSNumber *resCode, NSString *message))failure -{ - [self GET:API_HOST_URL method:method params:params success:success failure:failure]; - -} - -+ (void)GET:(NSString *)interfaceUrl method:(NSString *)method params:(NSDictionary *)params success:(void (^)(id))success failure:(void (^)(NSNumber *, NSString *))failure { if ([AFNetworkReachabilityManager sharedManager].networkReachabilityStatus == 0) { dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.01 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ - + failure([NSNumber numberWithInt:-1], @"请检查网络连接。"); }); + return; } - AFHTTPSessionManager *manager = [HttpRequestHelper requestManager]; - - NSString *url = [NSString stringWithFormat:@"%@/%@", interfaceUrl, method]; - -#ifdef DEBUG - NSLog(@"url:%@, parameter:%@", url, params); -#endif - - [manager GET:url parameters:params headers:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { - - } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { - - }]; -} - -+ (void)POST:(NSString *)method - params:(NSDictionary *)params - success:(void (^)(id data))success - failure:(void (^)(NSNumber *resCode, NSString *message))failure -{ - [self POST:API_HOST_URL method:method params:params success:success failure:failure]; -} - -+ (void)POST:(NSString *)interfaceUrl - method:(NSString *)method - params:(NSDictionary *)params - success:(void (^)(id data))success - failure:(void (^)(NSNumber *resCode, NSString *message))failure -{ - if ([AFNetworkReachabilityManager sharedManager].networkReachabilityStatus == 0) { - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.01 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ - - }); - } - - AFHTTPSessionManager *manager = [HttpRequestHelper requestManager]; - - NSString *url = [NSString stringWithFormat:@"%@/%@", interfaceUrl, method]; params = [self configBaseParmars:params]; #ifdef DEBUG - NSLog(@"\nurl:\n%@\nparameter:\n%@", url, params); + NSLog(@"\nmethod:\n%@\nparameter:\n%@", method, params); #endif - [manager POST:url parameters:params headers:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { + AFHTTPSessionManager *manager = [HttpRequestHelper requestManager]; + [manager GET:method parameters:params headers:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { #ifdef DEBUG - NSLog(@"\n%@", responseObject); + NSLog(@"\n%@", [responseObject yy_modelToJSONString]); #endif success(responseObject); } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { #ifdef DEBUG NSLog(@"\n%@", error); #endif + failure([NSNumber numberWithLong:error.code], error.domain); + }]; +} + ++ (void)POST:(NSString *)method + params:(NSDictionary *)params + success:(void (^)(BaseModel *data))success + failure:(void (^)(NSNumber *resCode, NSString *message))failure +{ + if ([AFNetworkReachabilityManager sharedManager].networkReachabilityStatus == 0) { + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.01 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + failure([NSNumber numberWithInt:-1], @"请检查网络连接。"); + }); + return; + } + + params = [self configBaseParmars:params]; +#ifdef DEBUG + NSLog(@"\nmethod:\n%@\nparameter:\n%@", method, params); +#endif + + AFHTTPSessionManager *manager = [HttpRequestHelper requestManager]; + [manager POST:method parameters:params headers:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { +#ifdef DEBUG + NSLog(@"\n%@", [responseObject yy_modelToJSONString]); +#endif + success([BaseModel yy_modelWithDictionary:responseObject]); + } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { +#ifdef DEBUG + NSLog(@"\n%@", error); +#endif + failure([NSNumber numberWithLong:error.code], error.domain); }]; } + (void)request:(NSString *)url method:(HttpRequestHelperMethod)method params:(NSDictionary *)params - success:(void (^)(id data))success + success:(void (^)(BaseModel *data))success failure:(void (^)(NSNumber *resCode, NSString *message))failure { - switch (method) { case HttpRequestHelperMethodGET: { [self GET:url params:params success:success failure:failure]; @@ -130,10 +119,7 @@ params:(NSDictionary *)params completion:(HttpRequestHelperCompletion)completion { - if ([path hasPrefix:@"/"]) { - path = [path substringFromIndex:1]; - } - [self request:path method:method params:params success:^(id data) { + [self request:path method:method params:params success:^(BaseModel *data) { if (completion) { completion(data, nil, nil); } @@ -144,7 +130,19 @@ }]; } -+ (NSDictionary*)configBaseParmars:(NSDictionary *)parmars { ++ (NSDictionary*)configBaseParmars:(NSDictionary *)parmars +{ + AFHTTPSessionManager *client = [HttpRequestHelper requestManager]; + if ([[AccountInfoStorage instance] getUid].length > 0) { + [client.requestSerializer setValue:[[AccountInfoStorage instance] getUid] forHTTPHeaderField:@"pub_uid"]; + } else { + [client.requestSerializer setValue:nil forHTTPHeaderField:@"pub_uid"]; + } + if ([[AccountInfoStorage instance] getTicket].length > 0) { + [client.requestSerializer setValue:[[AccountInfoStorage instance] getTicket] forHTTPHeaderField:@"pub_ticket"]; + }else { + [client.requestSerializer setValue:nil forHTTPHeaderField:@"pub_ticket"]; + } NSDictionary *defaultBasciParame = @{ @"os" : @"iOS", @"osVersion" : [YYUtility systemVersion], diff --git a/xplan-ios/Base/UI/BaseNavigationController.h b/xplan-ios/Base/UI/BaseNavigationController.h new file mode 100644 index 00000000..f6a9f12e --- /dev/null +++ b/xplan-ios/Base/UI/BaseNavigationController.h @@ -0,0 +1,16 @@ +// +// BaseNavigationController.h +// xplan-ios +// +// Created by zu on 2021/9/7. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface BaseNavigationController : UINavigationController + +@end + +NS_ASSUME_NONNULL_END diff --git a/xplan-ios/Base/UI/BaseNavigationController.m b/xplan-ios/Base/UI/BaseNavigationController.m new file mode 100644 index 00000000..2f8766c5 --- /dev/null +++ b/xplan-ios/Base/UI/BaseNavigationController.m @@ -0,0 +1,36 @@ +// +// BaseNavigationController.m +// xplan-ios +// +// Created by zu on 2021/9/7. +// + +#import "BaseNavigationController.h" + +@interface BaseNavigationController () + +@end + +@implementation BaseNavigationController + +- (void)viewDidLoad { + [super viewDidLoad]; + [self themeConfig]; +} + +- (void)themeConfig { + self.navigationBar.shadowImage = [[UIImage alloc] init]; + self.navigationBar.barTintColor = ThemeBackgroundColor; + self.navigationBar.tintColor = [UIColor whiteColor]; + self.navigationBar.translucent = NO; + + UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:nil]; + self.navigationItem.backBarButtonItem = item; + + [self.navigationBar setTitleTextAttributes:@{ + NSFontAttributeName:[UIFont systemFontOfSize:18], + NSForegroundColorAttributeName:UIColor.whiteColor + }]; +} + +@end diff --git a/xplan-ios/Base/UI/BaseViewController.m b/xplan-ios/Base/UI/BaseViewController.m index 646da5b7..05681c89 100644 --- a/xplan-ios/Base/UI/BaseViewController.m +++ b/xplan-ios/Base/UI/BaseViewController.m @@ -20,21 +20,7 @@ - (void)themeConfig { self.view.backgroundColor = ThemeBackgroundColor; - [UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleLightContent; - self.navigationController.navigationBar.shadowImage = [[UIImage alloc] init]; - self.navigationController.navigationBar.barTintColor = ThemeBackgroundColor; - self.navigationController.navigationBar.tintColor = [UIColor whiteColor]; - self.navigationController.navigationBar.translucent = NO; - - UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:nil]; - self.navigationItem.backBarButtonItem = item; - - [self.navigationController.navigationBar setTitleTextAttributes:@{ - NSFontAttributeName:[UIFont systemFontOfSize:18], - NSForegroundColorAttributeName:UIColor.whiteColor - }]; - self.navigationItem.title = @"音游"; } /** diff --git a/xplan-ios/Main/Login/Api/Api+Login.m b/xplan-ios/Main/Login/Api/Api+Login.m index 0abc8258..4a82e84b 100644 --- a/xplan-ios/Main/Login/Api/Api+Login.m +++ b/xplan-ios/Main/Login/Api/Api+Login.m @@ -10,9 +10,7 @@ @implementation Api (Login) + (void)phoneQuickLogin:(HttpRequestHelperCompletion)completion accessToken:(NSString *)accessToken token:(NSString *)token { - [self makeRequest:@"acc/oneclick/login" method:HttpRequestHelperMethodPOST completion:^(id _Nullable data, NSNumber * _Nonnull code, NSString * _Nullable msg) { - completion(data, code, msg); - }, __FUNCTION__, accessToken, token, nil]; + [self makeRequest:@"acc/oneclick/login" method:HttpRequestHelperMethodPOST completion:completion, __FUNCTION__, accessToken, token, nil]; } @end diff --git a/xplan-ios/Main/Login/Presenter/LoginPresenter.m b/xplan-ios/Main/Login/Presenter/LoginPresenter.m index 34bba0a7..f9b970ad 100644 --- a/xplan-ios/Main/Login/Presenter/LoginPresenter.m +++ b/xplan-ios/Main/Login/Presenter/LoginPresenter.m @@ -8,6 +8,7 @@ #import "LoginPresenter.h" #import "LoginProtocol.h" #import "Api+Login.h" +#import "AccountInfoStorage.h" @implementation LoginPresenter @@ -16,7 +17,8 @@ } - (void)phoneQuickLogin:(NSString *)accessToken token:(NSString *)token { - [Api phoneQuickLogin:[self createHttpCompletion:^(id _Nonnull data) { + [Api phoneQuickLogin:[self createHttpCompletion:^(BaseModel *data) { + [[AccountInfoStorage instance] saveAccountInfo:[AccountModel yy_modelWithDictionary:data.data]]; [[self getView] phoneQuickLoginSuccess]; } fail:^(NSNumber * _Nonnull code, NSString * _Nullable msg) { // todo fail diff --git a/xplan-ios/Main/Login/View/LoginViewController.m b/xplan-ios/Main/Login/View/LoginViewController.m index e107cf3a..e4e95738 100644 --- a/xplan-ios/Main/Login/View/LoginViewController.m +++ b/xplan-ios/Main/Login/View/LoginViewController.m @@ -41,9 +41,9 @@ typedef NS_ENUM(NSInteger,XYThirdLoginType) { @interface LLButtonView : UIView //icon -@property (nonatomic,strong) UIImageView *logoImageView; +@property (nonatomic, strong) UIImageView *logoImageView; //title -@property (nonatomic,strong) UILabel *titleLabel; +@property (nonatomic, strong) UILabel *titleLabel; @end @implementation LLButtonView @@ -106,13 +106,13 @@ typedef NS_ENUM(NSInteger,XYThirdLoginType) { /** 登录按钮*/ @property (nonatomic, strong) UIButton *loginButton; -@property (nonatomic,strong) UIStackView *stackView; +@property (nonatomic, strong) UIStackView *stackView; ///手机 -@property (nonatomic,strong) LLButtonView *qqButtonView; +@property (nonatomic, strong) LLButtonView *qqButtonView; ///wx -@property (nonatomic,strong) LLButtonView *wxButtonView; +@property (nonatomic, strong) LLButtonView *wxButtonView; ///qq -@property (nonatomic,strong) LLButtonView *phoneButtonView; +@property (nonatomic, strong) LLButtonView *phoneButtonView; /** 同意勾选按钮*/ @property (nonatomic, strong) UIButton *agreeButton; @@ -132,7 +132,7 @@ typedef NS_ENUM(NSInteger,XYThirdLoginType) { } - (void)phoneQuickLoginSuccess { - [XCHUDTool showSuccessWithMessage:@"一键登录成功。"]; + [self.navigationController popToRootViewControllerAnimated:YES]; } - (void)viewDidLoad { diff --git a/xplan-ios/Main/Tabbar/Api+Main.h b/xplan-ios/Main/Tabbar/Api+Main.h new file mode 100644 index 00000000..8a329a3a --- /dev/null +++ b/xplan-ios/Main/Tabbar/Api+Main.h @@ -0,0 +1,18 @@ +// +// Api+Main.h +// xplan-ios +// +// Created by apple on 2021/9/8. +// + +#import "Api.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface Api (Main) + ++ (void)requestTicket:(HttpRequestHelperCompletion)completion access_token:(NSString *)accessToken issue_type:(NSString *)issueType; + +@end + +NS_ASSUME_NONNULL_END diff --git a/xplan-ios/Main/Tabbar/Api+Main.m b/xplan-ios/Main/Tabbar/Api+Main.m new file mode 100644 index 00000000..45daa353 --- /dev/null +++ b/xplan-ios/Main/Tabbar/Api+Main.m @@ -0,0 +1,16 @@ +// +// Api+Main.m +// xplan-ios +// +// Created by apple on 2021/9/8. +// + +#import "Api+Main.h" + +@implementation Api (Main) + ++ (void)requestTicket:(HttpRequestHelperCompletion)completion access_token:(NSString *)accessToken issue_type:(NSString *)issueType { + [self makeRequest:@"oauth/ticket" method:HttpRequestHelperMethodPOST completion:completion, __FUNCTION__, accessToken, issueType, nil]; +} + +@end diff --git a/xplan-ios/Main/Tabbar/MainPresenter.h b/xplan-ios/Main/Tabbar/MainPresenter.h new file mode 100644 index 00000000..d40329d7 --- /dev/null +++ b/xplan-ios/Main/Tabbar/MainPresenter.h @@ -0,0 +1,18 @@ +// +// MainPresenter.h +// xplan-ios +// +// Created by apple on 2021/9/8. +// + +#import "BaseMvpPresenter.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface MainPresenter : BaseMvpPresenter + +- (void)autoLogin; + +@end + +NS_ASSUME_NONNULL_END diff --git a/xplan-ios/Main/Tabbar/MainPresenter.m b/xplan-ios/Main/Tabbar/MainPresenter.m new file mode 100644 index 00000000..c72647b8 --- /dev/null +++ b/xplan-ios/Main/Tabbar/MainPresenter.m @@ -0,0 +1,35 @@ +// +// MainPresenter.m +// xplan-ios +// +// Created by apple on 2021/9/8. +// + +#import "MainPresenter.h" +#import "AccountInfoStorage.h" +#import "AccountModel.h" +#import "Api+Main.h" +#import "MainProtocol.h" + +@implementation MainPresenter + +- (void)autoLogin { + AccountModel *accountModel = [[AccountInfoStorage instance] getCurrentAccountInfo]; + if (accountModel == nil) { + [[self getView] tokenInvalid]; + return; + } + if ([[AccountInfoStorage instance] getTicket] != nil) { + return; + } + [Api requestTicket:[self createHttpCompletion:^(BaseModel * _Nonnull data) { + NSArray *tickets = [data.data valueForKey:@"tickets"]; + NSString *ticket = [tickets[0] valueForKey:@"ticket"]; + [[AccountInfoStorage instance] saveTicket:ticket]; + [[self getView] autoLoginSuccess]; + } fail:^(NSNumber * _Nonnull code, NSString * _Nullable msg) { + + } showLoading:NO errorToast:YES] access_token:accountModel.access_token issue_type:@"multi"]; +} + +@end diff --git a/xplan-ios/Main/Tabbar/MainProtocol.h b/xplan-ios/Main/Tabbar/MainProtocol.h new file mode 100644 index 00000000..e51db52d --- /dev/null +++ b/xplan-ios/Main/Tabbar/MainProtocol.h @@ -0,0 +1,18 @@ +// +// MainProtocol.h +// xplan-ios +// +// Created by apple on 2021/9/8. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@protocol MainProtocol + +- (void)autoLoginSuccess; + +@end + +NS_ASSUME_NONNULL_END diff --git a/xplan-ios/Main/TabbarViewController.h b/xplan-ios/Main/Tabbar/TabbarViewController.h similarity index 50% rename from xplan-ios/Main/TabbarViewController.h rename to xplan-ios/Main/Tabbar/TabbarViewController.h index e9c9b71a..c4ef3f33 100644 --- a/xplan-ios/Main/TabbarViewController.h +++ b/xplan-ios/Main/Tabbar/TabbarViewController.h @@ -5,9 +5,7 @@ // Created by zu on 2021/8/31. // -#import "MvpViewController.h" - -@interface TabbarViewController : MvpViewController +@interface TabbarViewController : UITabBarController @end diff --git a/xplan-ios/Main/Tabbar/TabbarViewController.m b/xplan-ios/Main/Tabbar/TabbarViewController.m new file mode 100644 index 00000000..6aa84045 --- /dev/null +++ b/xplan-ios/Main/Tabbar/TabbarViewController.m @@ -0,0 +1,85 @@ +// +// ViewController.m +// xplan-ios +// +// Created by zu on 2021/8/31. +// +#import +#import "TabbarViewController.h" +#import "BaseViewController.h" +#import "UIImage+Utils.h" +#import "LoginViewController.h" +#import "MainPresenter.h" +#import "MainProtocol.h" + +@interface TabbarViewController () + +@property (nonatomic, strong) MainPresenter *presenter; + +@end + +@implementation TabbarViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + [self configTheme]; + [self initTabs]; +} + +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + [self.presenter autoLogin]; +} + +- (MainPresenter *)presenter { + if (_presenter == nil) { + _presenter = [[MainPresenter alloc] init]; + [_presenter attatchView:self]; + } + return _presenter; +} + +- (void)tokenInvalid { + LoginViewController *lvc = [[LoginViewController alloc] init]; + [self.navigationController pushViewController:lvc animated:YES]; +} + +- (void)completeUserInfo { + +} + +- (void)autoLoginSuccess { + +} + +- (void)configTheme { + [[UITabBar appearance] setBackgroundImage:[UIImage imageWithColor:ThemeTabbarBackgroundColor size:CGSizeMake(KScreenWidth, kTabBarHeight)]]; + [[UITabBar appearance] setShadowImage:[[UIImage alloc]init]]; + if (@available(iOS 10.0, *)) { + [[UITabBar appearance] setUnselectedItemTintColor:ThemeTabbarNormalColor]; + } +} + +- (void)initTabs { + NSArray *normalImageNames = @[@"tab_game_normal", @"tab_mine_normal"]; + NSArray *selectImageNames = @[@"tab_game_selected", @"tab_mine_selected"]; + NSArray *tabLabel = @[@"赛事", @"我的"]; + + BaseViewController *bvcGame = [[BaseViewController alloc] init]; + [self createTabBarItem:bvcGame title:tabLabel[0] image:normalImageNames[0] selectedImage:selectImageNames[0]]; + [self addChildViewController:bvcGame]; + + BaseViewController *bvcMe = [[BaseViewController alloc] init]; + [self createTabBarItem:bvcMe title:tabLabel[1] image:normalImageNames[1] selectedImage:selectImageNames[1]]; + [self addChildViewController:bvcMe]; +} + +- (void)createTabBarItem:(UIViewController *)itemVc title:(NSString *)title image:(NSString *)image selectedImage:(NSString *)selectedImage{ + itemVc.title = title; + itemVc.tabBarItem.image = [[UIImage imageNamed:image] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]; + itemVc.tabBarItem.selectedImage = [[UIImage imageNamed:selectedImage] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]; + [itemVc.tabBarItem setTitleTextAttributes:@{NSForegroundColorAttributeName:ThemeTabbarSelectedColor} forState:UIControlStateSelected]; + [itemVc.tabBarItem setTitleTextAttributes:@{NSForegroundColorAttributeName:ThemeTabbarNormalColor} forState:UIControlStateNormal]; +} + +@end diff --git a/xplan-ios/Main/TabbarViewController.m b/xplan-ios/Main/TabbarViewController.m deleted file mode 100644 index 0824294e..00000000 --- a/xplan-ios/Main/TabbarViewController.m +++ /dev/null @@ -1,22 +0,0 @@ -// -// ViewController.m -// xplan-ios -// -// Created by zu on 2021/8/31. -// - -#import "TabbarViewController.h" -#import "LoginViewController.h" - -@interface TabbarViewController () - -@end - -@implementation TabbarViewController - -- (void)viewDidLoad { - [super viewDidLoad]; - [self tokenInvalid]; -} - -@end